diff --git a/resources/xml/fragment/inbox_chat.xml b/resources/xml/fragment/inbox_chat.xml
index bb312f986..7796a7f98 100644
--- a/resources/xml/fragment/inbox_chat.xml
+++ b/resources/xml/fragment/inbox_chat.xml
@@ -4,16 +4,19 @@
height="auto"
width="auto">
-
-
-
+
+
+
@@ -16,15 +17,15 @@
textColor="@theme/font/grey" />
+ width="auto"
+ height="auto"
+ grow="1"
+ wireframe="false" />
-
-
-
-
+
+
diff --git a/wiliwili/include/api/bilibili.h b/wiliwili/include/api/bilibili.h
index 160284bd0..def48c95d 100644
--- a/wiliwili/include/api/bilibili.h
+++ b/wiliwili/include/api/bilibili.h
@@ -134,7 +134,7 @@ class BilibiliClient {
const ErrorCallback& error = nullptr);
/// 批量获取用户昵称头像
- static void get_user_cards(const std::vector uids,
+ static void get_user_cards(const std::vector& uids,
const std::function& callback = nullptr,
const ErrorCallback& error = nullptr);
diff --git a/wiliwili/include/api/bilibili/api.h b/wiliwili/include/api/bilibili/api.h
index 7d3b24b34..4db803789 100644
--- a/wiliwili/include/api/bilibili/api.h
+++ b/wiliwili/include/api/bilibili/api.h
@@ -175,6 +175,7 @@ const std::string MsgFeedReply = _apiBase + "/x/msgfeed/reply";
const std::string UserCards = _vcBase + "/account/v1/user/cards";
const std::string UserDynamicStat = _vcBase + "/dynamic_svr/v1/dynamic_svr/space_num_ex";
const std::string ChatSessions = _vcBase + "/session_svr/v1/session_svr/new_sessions";
+const std::string ChatUpdateAct = _vcBase + "/session_svr/v1/session_svr/update_ack";
const std::string ChatFetchMsgs = _vcBase + "/svr_sync/v1/svr_sync/fetch_session_msgs";
const std::string ChatSendMsg = _vcBase + "/web_im/v1/web_im/send_msg";
/// 用户追番/追剧
diff --git a/wiliwili/include/api/bilibili/result/inbox_result.h b/wiliwili/include/api/bilibili/result/inbox_result.h
index 1d1286c05..081130150 100644
--- a/wiliwili/include/api/bilibili/result/inbox_result.h
+++ b/wiliwili/include/api/bilibili/result/inbox_result.h
@@ -30,8 +30,9 @@ class MsgFeedItem {
std::string title;
std::string image;
std::string source_content;
+ std::string uri;
};
-NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(MsgFeedItem, subject_id, source_id, type, title, image, source_content);
+NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MsgFeedItem, subject_id, source_id, type, title, image, source_content, uri);
class FeedReplyResult {
public:
@@ -116,12 +117,17 @@ class InboxMessageResult {
uint64_t sender_uid, receiver_id;
uint64_t msg_seqno;
std::vector at_uids;
- int receiver_type, msg_type;
- std::string content;
+ int msg_type, msg_source;
+ nlohmann::json content;
time_t timestamp;
};
-NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(InboxMessageResult, sender_uid, receiver_id, receiver_type, msg_seqno, at_uids,
- msg_type, content, timestamp);
+inline void from_json(const nlohmann::json& nlohmann_json_j, InboxMessageResult& nlohmann_json_t) {
+ if (nlohmann_json_j.contains("content") && nlohmann_json_j.at("content").is_string()) {
+ nlohmann::json::parse(nlohmann_json_j.at("content").get()).get_to(nlohmann_json_t.content);
+ }
+ NLOHMANN_JSON_EXPAND(
+ NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, sender_uid, receiver_id, msg_seqno, msg_type, msg_source, timestamp));
+}
typedef std::vector InboxMessageListResult;
@@ -162,11 +168,18 @@ class InboxChatResult {
uint64_t talker_id;
int session_type;
time_t session_ts;
+ uint64_t max_seqno;
+ int unread_count;
InboxAccountInfo account_info;
InboxMessageResult last_msg;
};
-NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(InboxChatResult, talker_id, session_type, session_ts, account_info,
- last_msg);
+inline void from_json(const nlohmann::json& nlohmann_json_j, InboxChatResult& nlohmann_json_t) {
+ if (nlohmann_json_j.contains("last_msg") && nlohmann_json_j.at("last_msg").is_object()) {
+ nlohmann_json_j.at("last_msg").get_to(nlohmann_json_t.last_msg);
+ }
+ NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, talker_id, session_type, session_ts, max_seqno,
+ unread_count, account_info));
+}
typedef std::vector InboxChatListResult;
diff --git a/wiliwili/include/fragment/inbox_chat.hpp b/wiliwili/include/fragment/inbox_chat.hpp
index 61089f139..5b5832b23 100644
--- a/wiliwili/include/fragment/inbox_chat.hpp
+++ b/wiliwili/include/fragment/inbox_chat.hpp
@@ -5,11 +5,14 @@
#include "presenter/inbox_msg.hpp"
+namespace brls {
+class Label;
+};
class RecyclingGrid;
class InboxChat : public brls::Box, public InboxMsgRequest {
public:
- InboxChat(uint64_t talker_id, int session_type);
+ InboxChat(const bilibili::InboxChatResult& r);
~InboxChat() override;
@@ -19,4 +22,5 @@ class InboxChat : public brls::Box, public InboxMsgRequest {
private:
BRLS_BIND(RecyclingGrid, recyclingGrid, "inbox/msgList");
+ BRLS_BIND(brls::Label, labelTalker, "inbox/talker");
};
\ No newline at end of file
diff --git a/wiliwili/include/fragment/inbox_view.hpp b/wiliwili/include/fragment/inbox_view.hpp
index e6d614d18..5c83c803d 100644
--- a/wiliwili/include/fragment/inbox_view.hpp
+++ b/wiliwili/include/fragment/inbox_view.hpp
@@ -23,8 +23,8 @@ class InboxView : public brls::Box, public InboxChatRequest {
void onError(const std::string& error) override;
private:
- BRLS_BIND(ButtonClose, closebtn, "button/close");
+ BRLS_BIND(ButtonClose, closebtn, "inbox/close");
BRLS_BIND(brls::Box, cancel, "player/cancel");
- BRLS_BIND(AutoTabFrame, inboxFrame, "inbox/tab/frame");
+ BRLS_BIND(AutoTabFrame, tabFrame, "inbox/tab/frame");
BRLS_BIND(RecyclingGrid, recyclingGrid, "inbox/chatList");
};
\ No newline at end of file
diff --git a/wiliwili/include/presenter/inbox_chat.hpp b/wiliwili/include/presenter/inbox_chat.hpp
index d74446319..e1493be66 100644
--- a/wiliwili/include/presenter/inbox_chat.hpp
+++ b/wiliwili/include/presenter/inbox_chat.hpp
@@ -7,6 +7,8 @@
#include "bilibili/result/inbox_result.h"
#include "presenter.h"
+typedef std::unordered_map InboxUserMap;
+
class InboxChatRequest : public Presenter {
public:
virtual void onChatList(const bilibili::InboxChatListResult& result, bool refresh);
@@ -17,6 +19,4 @@ class InboxChatRequest : public Presenter {
protected:
time_t last_time = 0;
-
- std::unordered_map user_map;
};
\ No newline at end of file
diff --git a/wiliwili/include/view/inbox_msg_card.hpp b/wiliwili/include/view/inbox_msg_card.hpp
new file mode 100644
index 000000000..a0018a433
--- /dev/null
+++ b/wiliwili/include/view/inbox_msg_card.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "view/recycling_grid.hpp"
+#include "bilibili/result/inbox_result.h"
+
+class TextBox;
+
+typedef std::shared_ptr InboxEmotePtr;
+typedef std::unordered_map IEMap;
+
+class InboxMsgCard : public RecyclingGridItem {
+public:
+ InboxMsgCard();
+
+ void setCard(const bilibili::InboxMessageResult& r, const IEMap& m, uint64_t talker);
+
+ void setTime(const std::string& time_str);
+
+ void setAvatar(const std::string& face);
+
+private:
+ BRLS_BIND(TextBox, textBox, "msg/content");
+ BRLS_BIND(brls::Box, msgBox, "msg/content_box");
+ BRLS_BIND(brls::Image, talker, "avatar/talker");
+ BRLS_BIND(brls::Image, mine, "avatar/mine");
+ BRLS_BIND(brls::Label, msgTime, "msg/time");
+};
diff --git a/wiliwili/source/activity/main_activity.cpp b/wiliwili/source/activity/main_activity.cpp
index 2d16dd26e..a2336991f 100644
--- a/wiliwili/source/activity/main_activity.cpp
+++ b/wiliwili/source/activity/main_activity.cpp
@@ -18,6 +18,7 @@
#include "activity/main_activity.hpp"
#include "utils/activity_helper.hpp"
+#include "utils/config_helper.hpp"
#include "view/custom_button.hpp"
#include "view/auto_tab_frame.hpp"
#include "view/svg_image.hpp"
@@ -74,8 +75,10 @@ void MainActivity::onContentAvailable() {
});
this->settingBtn->addGestureRecognizer(new brls::TapGestureRecognizer(this->settingBtn));
- this->inboxBtn->registerClickAction([](brls::View* view) -> bool {
- Intent::openInbox();
+ this->inboxBtn->registerClickAction([this](brls::View* view) -> bool {
+ if (ProgramConfig::instance().hasLoginInfo()) {
+ Intent::openInbox();
+ }
return true;
});
diff --git a/wiliwili/source/api/mine_api.cpp b/wiliwili/source/api/mine_api.cpp
index a370c58cf..c0470e672 100644
--- a/wiliwili/source/api/mine_api.cpp
+++ b/wiliwili/source/api/mine_api.cpp
@@ -126,7 +126,7 @@ void BilibiliClient::get_user_dynamic_count(const std::string& mid,
HTTP::getResultAsync(Api::UserDynamicStat, {{"uids", mid}}, callback, error);
}
-void BilibiliClient::get_user_cards(const std::vector uids,
+void BilibiliClient::get_user_cards(const std::vector& uids,
const std::function& callback,
const ErrorCallback& error) {
std::string mid = fmt::format("{}", fmt::join(uids, ","));
@@ -136,7 +136,10 @@ void BilibiliClient::get_user_cards(const std::vector uids,
void BilibiliClient::new_inbox_sessions(time_t begin_ts,
const std::function& callback,
const ErrorCallback& error) {
- HTTP::getResultAsync(Api::ChatSessions, {{"begin_ts", std::to_string(begin_ts)}}, callback, error);
+ HTTP::getResultAsync(Api::ChatSessions, {
+ {"begin_ts", std::to_string(begin_ts)},
+ {"mobi_app", "web"},
+ }, callback, error);
}
void BilibiliClient::fetch_inbox_msgs(const std::string& talker_id, size_t size,
@@ -145,10 +148,12 @@ void BilibiliClient::fetch_inbox_msgs(const std::string& talker_id, size_t size,
const std::function& callback,
const ErrorCallback& error) {
HTTP::getResultAsync(Api::ChatFetchMsgs, {
+ {"sender_device_id", "1"},
{"talker_id", talker_id},
{"session_type", std::to_string(session_type)},
{"begin_seqno", begin_seqno},
{"size", std::to_string(size)},
+ {"mobi_app", "web"},
}, callback, error);
}
diff --git a/wiliwili/source/fragment/inbox_chat.cpp b/wiliwili/source/fragment/inbox_chat.cpp
index a661caaec..6a2794d8b 100644
--- a/wiliwili/source/fragment/inbox_chat.cpp
+++ b/wiliwili/source/fragment/inbox_chat.cpp
@@ -2,94 +2,31 @@
#include
#include "fragment/inbox_chat.hpp"
-#include "view/recycling_grid.hpp"
-
-#include "view/text_box.hpp"
+#include "view/inbox_msg_card.hpp"
+#include "utils/number_helper.hpp"
using namespace brls::literals;
-class ChatMsgCard : public RecyclingGridItem {
-public:
- ChatMsgCard() { this->inflateFromXMLRes("xml/views/inbox_msg.xml"); }
-
- void setCard(const bilibili::InboxMessageResult& r) {
- try {
- auto j = nlohmann::json::parse(r.content);
- switch (r.msg_type) {
- case 1:
- this->textBox->setText(j.at("content").get());
- this->msgBox->setVisibility(brls::Visibility::VISIBLE);
- this->picBox->setVisibility(brls::Visibility::GONE);
- break;
- case 2: {
- std::string pic = j.at("url").get();
- float width = j.at("width").get();
- float height = j.at("height").get();
-
- if (width > 400.f) {
- height = height * 400.f / width;
- width = 400.f;
- }
- this->picBox->setWidth(width);
- this->picBox->setHeight(height);
- ImageHelper::with(this->msgPic)->load(pic);
-
- this->picBox->setVisibility(brls::Visibility::VISIBLE);
- this->msgBox->setVisibility(brls::Visibility::GONE);
- break;
- }
- }
-
- } catch (const std::exception& ex) {
- }
- }
-
- void setTime(const std::string& time_str) {
- if (time_str.empty()) {
- this->labelTime->setVisibility(brls::Visibility::GONE);
- } else {
- this->labelTime->setText(time_str);
- this->labelTime->setVisibility(brls::Visibility::VISIBLE);
- }
- }
-
- void setTalker(bool talker) {
- auto theme = brls::Application::getTheme();
- if (talker) {
- this->talker->setVisibility(brls::Visibility::VISIBLE);
- this->mine->setVisibility(brls::Visibility::INVISIBLE);
- this->msgBox->setBackgroundColor(theme.getColor("color/grey_2"));
- } else {
- this->talker->setVisibility(brls::Visibility::INVISIBLE);
- this->mine->setVisibility(brls::Visibility::VISIBLE);
- this->msgBox->setBackgroundColor(theme.getColor("color/bilibili"));
- }
- }
-
-private:
- BRLS_BIND(TextBox, textBox, "msg/content");
- BRLS_BIND(brls::Box, msgBox, "msg/content_box");
- BRLS_BIND(brls::Box, picBox, "msg/picture_box");
- BRLS_BIND(brls::Image, msgPic, "msg/picture");
- BRLS_BIND(brls::Image, talker, "avatar/talker");
- BRLS_BIND(brls::Image, mine, "avatar/mine");
- BRLS_BIND(brls::Label, labelTime, "msg/time");
-};
-
class DataSourceMsgList : public RecyclingGridDataSource {
public:
- explicit DataSourceMsgList(const bilibili::InboxMessageListResult& result, uint64_t mid)
- : list(std::move(result)), talkerId(mid) {
- std::reverse(this->list.begin(), this->list.end());
+ explicit DataSourceMsgList(const bilibili::InboxMessageResultWrapper& result, uint64_t mid)
+ : list(std::move(result.messages)), talkerId(mid) {
+ std::sort(this->list.begin(), this->list.end(),
+ [](const bilibili::InboxMessageResult& x, const bilibili::InboxMessageResult& y) {
+ return x.msg_seqno < y.msg_seqno;
+ });
+
+ for (auto& e : result.e_infos) {
+ this->emotes.insert({e.text, std::make_shared(e)});
+ }
}
RecyclingGridItem* cellForRow(RecyclingGrid* recycler, size_t index) override {
//从缓存列表中取出 或者 新生成一个表单项
- auto* item = (ChatMsgCard*)recycler->dequeueReusableCell("Cell");
+ auto* item = (InboxMsgCard*)recycler->dequeueReusableCell("Cell");
auto& r = this->list[index];
std::string t = wiliwili::sec2date(r.timestamp);
- item->setTalker(r.sender_uid == this->talkerId);
- item->setCard(r);
+ item->setCard(r, this->emotes, this->talkerId);
if (this->lastTime == t) {
item->setTime("");
} else {
@@ -123,11 +60,12 @@ class DataSourceMsgList : public RecyclingGridDataSource {
private:
bilibili::InboxMessageListResult list;
+ IEMap emotes;
uint64_t talkerId;
std::string lastTime;
};
-InboxChat::InboxChat(uint64_t talker_id, int session_type) {
+InboxChat::InboxChat(const bilibili::InboxChatResult& r) {
this->inflateFromXMLRes("xml/fragment/inbox_chat.xml");
brls::Logger::debug("Fragment InboxChat: create");
@@ -136,12 +74,18 @@ InboxChat::InboxChat(uint64_t talker_id, int session_type) {
return true;
});
- this->setTalkerId(talker_id);
+ this->setTalkerId(r.talker_id);
+
+ recyclingGrid->registerCell("Cell", [r]() {
+ auto* card = new InboxMsgCard();
+ card->setAvatar(r.account_info.pic_url);
+ return card;
+ });
+ recyclingGrid->onNextPage([this, r]() { this->requestData(false, r.session_type); });
- recyclingGrid->registerCell("Cell", []() { return new ChatMsgCard(); });
- recyclingGrid->onNextPage([this, session_type]() { this->requestData(false, session_type); });
+ labelTalker->setText(r.account_info.name);
- this->requestData(true, session_type);
+ this->requestData(true, r.session_type);
}
InboxChat::~InboxChat() { brls::Logger::debug("Fragment InboxChat: delete"); }
@@ -159,7 +103,7 @@ void InboxChat::onMsgList(const bilibili::InboxMessageResultWrapper& result, boo
recyclingGrid->notifyDataChanged();
}
} else {
- auto dataSource = new DataSourceMsgList(result.messages, this->talkerId);
+ auto dataSource = new DataSourceMsgList(result, this->talkerId);
recyclingGrid->setDataSource(dataSource);
}
});
diff --git a/wiliwili/source/fragment/inbox_feed.cpp b/wiliwili/source/fragment/inbox_feed.cpp
index 1c38be7ea..3491a7301 100644
--- a/wiliwili/source/fragment/inbox_feed.cpp
+++ b/wiliwili/source/fragment/inbox_feed.cpp
@@ -5,6 +5,7 @@
#include "view/recycling_grid.hpp"
#include "view/text_box.hpp"
#include "utils/image_helper.hpp"
+#include "utils/activity_helper.hpp"
using namespace brls::literals;
@@ -40,6 +41,16 @@ class FeedCard : public RecyclingGridItem {
this->labelMisc->setText(brls::getStr("wiliwili/inbox/reply/" + r.item.type));
}
+ void prepareForReuse() override {
+ this->avatar->setImageFromRes("pictures/default_avatar.png");
+ this->picture->setImageFromRes("pictures/video-card-bg.png");
+ }
+
+ void cacheForReuse() override {
+ ImageHelper::clear(this->avatar);
+ ImageHelper::clear(this->picture);
+ }
+
private:
BRLS_BIND(brls::Image, avatar, "feed/avatar");
BRLS_BIND(brls::Label, labelAuthor, "feed/label/author");
@@ -63,9 +74,16 @@ class DataSourceFeedList : public RecyclingGridDataSource {
size_t getItemCount() override { return list.size(); }
- void onItemSelected(RecyclingGrid* recycler, size_t index) override {}
-
- void appendData(const std::vector& data) {}
+ void onItemSelected(RecyclingGrid* recycler, size_t index) override {
+ auto& r = this->list[index];
+ if (r.item.type == "video" || r.item.type == "reply") {
+ // 解析BV号
+ size_t pos = r.item.uri.find_last_of('/');
+ if (pos > 0) {
+ Intent::openBV(r.item.uri.substr(pos + 1, r.item.source_id));
+ }
+ }
+ }
void clearData() override { this->list.clear(); }
diff --git a/wiliwili/source/fragment/inbox_view.cpp b/wiliwili/source/fragment/inbox_view.cpp
index 61f9d282d..951dc2af4 100644
--- a/wiliwili/source/fragment/inbox_view.cpp
+++ b/wiliwili/source/fragment/inbox_view.cpp
@@ -19,20 +19,31 @@ class ChatUserCard : public RecyclingGridItem {
void setCard(const bilibili::InboxChatResult& r) {
std::string misc;
if (r.last_msg.msg_type == 1) {
- auto j = nlohmann::json::parse(r.last_msg.content);
- misc = j.at("content").get();
+ misc = r.last_msg.content.at("content");
} else if (r.last_msg.msg_type == 2) {
- misc = "Image";
+ misc = "[图片]";
+ } else if (r.last_msg.msg_type == 10) {
+ misc = r.last_msg.content.at("title");
}
this->talker->setUserInfo(r.account_info.pic_url + ImageHelper::face_ext, r.account_info.name, misc);
if (r.last_msg.timestamp > 0) {
this->time->setText(wiliwili::sec2date(r.last_msg.timestamp));
}
+ if (r.unread_count > 0) {
+ this->badge->setVisibility(brls::Visibility::VISIBLE);
+ } else {
+ this->badge->setVisibility(brls::Visibility::INVISIBLE);
+ }
}
+ void prepareForReuse() override { this->talker->getAvatar()->setImageFromRes("pictures/default_avatar.png"); }
+
+ void cacheForReuse() override { ImageHelper::clear(this->talker->getAvatar()); }
+
private:
BRLS_BIND(UserInfoView, talker, "chat/talker");
BRLS_BIND(brls::Label, time, "inbox/lastTime");
+ BRLS_BIND(brls::Rectangle, badge, "badge");
};
class DataSourceChatList : public RecyclingGridDataSource {
@@ -50,7 +61,7 @@ class DataSourceChatList : public RecyclingGridDataSource {
void onItemSelected(RecyclingGrid* recycler, size_t index) override {
auto& r = this->list[index];
- auto* view = new InboxChat(r.talker_id, r.session_type);
+ auto* view = new InboxChat(r);
recycler->present(view);
brls::sync([view]() { brls::Application::giveFocus(view); });
}
@@ -83,6 +94,36 @@ InboxView::InboxView() {
return true;
});
+ this->registerAction(
+ "上一项", brls::ControllerButton::BUTTON_LT,
+ [this](brls::View* view) -> bool {
+ tabFrame->focus2LastTab();
+ return true;
+ },
+ true);
+ this->registerAction(
+ "上一项", brls::ControllerButton::BUTTON_LB,
+ [this](brls::View* view) -> bool {
+ tabFrame->focus2LastTab();
+ return true;
+ },
+ true);
+
+ this->registerAction(
+ "下一项", brls::ControllerButton::BUTTON_RT,
+ [this](brls::View* view) -> bool {
+ tabFrame->focus2NextTab();
+ return true;
+ },
+ true);
+ this->registerAction(
+ "下一项", brls::ControllerButton::BUTTON_RB,
+ [this](brls::View* view) -> bool {
+ tabFrame->focus2NextTab();
+ return true;
+ },
+ true);
+
recyclingGrid->registerCell("Cell", []() { return new ChatUserCard(); });
recyclingGrid->onNextPage([this]() { this->requestData(false); });
@@ -93,7 +134,7 @@ InboxView::~InboxView() { brls::Logger::debug("Fragment InboxView: delete"); }
bool InboxView::isTranslucent() { return true; }
-brls::View* InboxView::getDefaultFocus() { return this->inboxFrame->getDefaultFocus(); }
+brls::View* InboxView::getDefaultFocus() { return this->tabFrame->getDefaultFocus(); }
void InboxView::onChatList(const bilibili::InboxChatListResult& result, bool refresh) {
brls::Threading::sync([this, result, refresh]() {
diff --git a/wiliwili/source/presenter/inbox_chat.cpp b/wiliwili/source/presenter/inbox_chat.cpp
index 80f5177ef..467a354d9 100644
--- a/wiliwili/source/presenter/inbox_chat.cpp
+++ b/wiliwili/source/presenter/inbox_chat.cpp
@@ -8,12 +8,12 @@ void InboxChatRequest::onError(const std::string& error) {}
void InboxChatRequest::requestData(bool refresh) {
BILI::new_inbox_sessions(
- this->last_time,
+ refresh ? 0 : this->last_time,
[this, refresh](const bilibili::InboxChatResultWrapper& result) {
- std::vector uids;
+ std::vector uids;
for (auto& s : result.session_list) {
if (s.account_info.name.empty()) {
- uids.push_back(s.talker_id);
+ uids.push_back(std::to_string(s.talker_id));
}
}
this->last_time = wiliwili::unix_time() * 1000000;
@@ -21,21 +21,21 @@ void InboxChatRequest::requestData(bool refresh) {
BILI::get_user_cards(
uids,
[this, result, refresh](const bilibili::UserCardListResult& users) {
- for (auto& u : users) {
- user_map[u.mid] = u;
- }
+ InboxUserMap user_map;
+ for (auto& u : users) user_map[u.mid] = u;
+
auto list = result.session_list;
for (auto& s : list) {
auto it = user_map.find(s.talker_id);
if (it != user_map.end()) {
- s.account_info.name = it->second.name;
+ s.account_info.name = it->second.name;
s.account_info.pic_url = it->second.face;
}
}
this->onChatList(list, refresh);
},
[this](BILI_ERR) { this->onError(error); });
- }
+ }
},
[this](BILI_ERR) { this->onError(error); });
}
\ No newline at end of file
diff --git a/wiliwili/source/presenter/inbox_msg.cpp b/wiliwili/source/presenter/inbox_msg.cpp
index 56e58f763..7ff10550d 100644
--- a/wiliwili/source/presenter/inbox_msg.cpp
+++ b/wiliwili/source/presenter/inbox_msg.cpp
@@ -7,7 +7,7 @@ void InboxMsgRequest::onError(const std::string& error) {}
void InboxMsgRequest::requestData(bool refresh, int session_type) {
BILI::fetch_inbox_msgs(
- std::to_string(this->talkerId), 10, session_type, std::to_string(this->msgSeq),
+ std::to_string(this->talkerId), 20, session_type, std::to_string(this->msgSeq),
[this, refresh](const bilibili::InboxMessageResultWrapper& result) {
this->onMsgList(result, refresh);
this->msgSeq = result.max_seqno;
diff --git a/wiliwili/source/view/inbox_msg_card.cpp b/wiliwili/source/view/inbox_msg_card.cpp
new file mode 100644
index 000000000..eeac7ec23
--- /dev/null
+++ b/wiliwili/source/view/inbox_msg_card.cpp
@@ -0,0 +1,120 @@
+#include "view/inbox_msg_card.hpp"
+#include "view/text_box.hpp"
+
+InboxMsgCard::InboxMsgCard() { this->inflateFromXMLRes("xml/views/inbox_msg.xml"); }
+
+void InboxMsgCard::setCard(const bilibili::InboxMessageResult& r, const IEMap& m, uint64_t talker) {
+ RichTextData d;
+ auto theme = brls::Application::getTheme();
+ auto textColor = theme.getColor("brls/text");
+
+ this->textBox->setFontSize(20);
+ this->msgBox->setBackgroundColor(theme.getColor("color/grey_1"));
+
+ // 设置用户头像
+ if (r.msg_type >= 10) {
+ this->talker->setVisibility(brls::Visibility::GONE);
+ this->mine->setVisibility(brls::Visibility::GONE);
+ } else if (talker == r.sender_uid) {
+ this->talker->setVisibility(brls::Visibility::VISIBLE);
+ this->mine->setVisibility(brls::Visibility::INVISIBLE);
+ } else {
+ this->talker->setVisibility(brls::Visibility::INVISIBLE);
+ this->mine->setVisibility(brls::Visibility::VISIBLE);
+ }
+
+ switch (r.msg_type) {
+ case 1: { // 文本消息
+ std::string msg = r.content.at("content");
+ size_t start = 0;
+ for (size_t i = 0; i < msg.length(); i++) {
+ InboxEmotePtr matched = nullptr;
+ size_t nextMatch = -1;
+ for (auto& key : m) {
+ size_t position = msg.find(key.first, i);
+ if (position < nextMatch) {
+ nextMatch = position;
+ matched = key.second;
+ break;
+ }
+ }
+ if (matched == nullptr) nextMatch = msg.length();
+ if (start < nextMatch) {
+ // 纯文本
+ std::string text = msg.substr(start, nextMatch - start);
+ d.push_back(std::make_shared(text, textColor));
+ }
+ if (matched == nullptr) break;
+
+ // 处理表情
+ std::shared_ptr item;
+ if (matched->size == 2) {
+ item = std::make_shared(matched->url, 50, 50);
+ item->t_margin = 4;
+ } else {
+ item = std::make_shared(matched->url, 30, 30);
+ }
+ item->v_align = 4;
+ item->l_margin = 2;
+ item->r_margin = 2;
+ d.push_back(item);
+
+ i = nextMatch + matched->text.length() - 1;
+ start = i + 1;
+ }
+ break;
+ }
+ case 2: { // 图片消息
+ std::string pic = r.content.at("url");
+ float width = r.content.at("width");
+ float height = r.content.at("height");
+
+ if (width > 400.f) {
+ height = height * 400.f / width;
+ width = 400.f;
+ }
+ d.push_back(std::make_shared(pic, width, height));
+ this->msgBox->setBackgroundColor(theme.getColor("brls/background"));
+ break;
+ }
+ case 7: { // 分享消息
+ std::string title = r.content.at("title");
+ std::string thumb = r.content.at("thumb");
+ d.push_back(std::make_shared(title, textColor));
+ d.push_back(std::make_shared(thumb, 400.f, 100.f));
+ break;
+ }
+ case 10: { // 系统消息
+ std::string title = r.content.at("title");
+ std::string text = r.content.at("text");
+ d.push_back(std::make_shared(title, theme.getColor("color/bilibili")));
+ d.push_back(std::make_shared());
+ d.push_back(std::make_shared(text, textColor));
+ break;
+ }
+ case 18: { // 通知消息
+ auto result = nlohmann::json::parse(r.content.at("content").get());
+ d.push_back(std::make_shared(result[0]["text"], theme.getColor("font/grey")));
+ this->textBox->setHorizontalAlign(brls::HorizontalAlign::CENTER);
+ this->textBox->setFontSize(16);
+ this->msgBox->setBackgroundColor(theme.getColor("brls/background"));
+ break;
+ }
+ default:;
+ }
+
+ this->textBox->setRichText(d);
+}
+
+void InboxMsgCard::setTime(const std::string& time_str) {
+ if (time_str.empty()) {
+ this->msgTime->setVisibility(brls::Visibility::GONE);
+ } else {
+ this->msgTime->setText(time_str);
+ this->msgTime->setVisibility(brls::Visibility::VISIBLE);
+ }
+}
+
+void InboxMsgCard::setAvatar(const std::string& face) {
+ ImageHelper::with(this->talker)->load(face + ImageHelper::face_ext);
+}