Skip to content

Commit

Permalink
Support send chat msg
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonflylee committed May 7, 2024
1 parent 0e71646 commit c38a175
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 36 deletions.
3 changes: 2 additions & 1 deletion resources/i18n/zh-Hans/wiliwili.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@
},
"inbox": {
"chat": {
"tab": "聊天列表"
"tab": "聊天列表",
"hint": "发个消息聊聊呗"
},
"feed": {
"like": "收到的赞",
Expand Down
16 changes: 16 additions & 0 deletions resources/xml/fragment/inbox_chat.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,20 @@
paddingRight="20"
wireframe="false"
id="inbox/msgList" />

<brls:Box
focusable="true"
marginLeft="20"
marginRight="20"
marginTop="15"
marginBottom="15"
height="40"
id="inbox/reply/hint"
backgroundColor="@theme/color/grey_2">
<brls:Label
marginLeft="20"
text="@i18n/wiliwili/inbox/chat/hint"
textColor="@theme/font/grey"
fontSize="18" />
</brls:Box>
</brls:Box>
8 changes: 8 additions & 0 deletions wiliwili/include/api/bilibili.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class UserCardResult;
typedef std::vector<UserCardResult> UserCardListResult;
class InboxChatResultWrapper;
class InboxMessageResultWrapper;
class InboxSendResult;
class DynamicVideoResult;
class PGCIndexResultWrapper;
class PGCIndexFilterWrapper;
Expand Down Expand Up @@ -149,6 +150,13 @@ class BilibiliClient {
const std::function<void(InboxMessageResultWrapper)>& callback = nullptr,
const ErrorCallback& error = nullptr);

static void send_inbox_msg(const std::string& sender_id,
const std::string& receiver_id,
const std::string& message,
const std::string& csrf = "",
const std::function<void(InboxSendResult)>& callback = nullptr,
const ErrorCallback& error = nullptr);

/// 消息页 回复列表
static void msg_feed_reply(const MsgFeedCursor& cursor,
const std::function<void(FeedReplyResultWrapper)>& callback = nullptr,
Expand Down
1 change: 1 addition & 0 deletions wiliwili/include/api/bilibili/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ const std::string QrLoginInfoV2 = _passBase + "/x/passport-login/web/q
const std::string CheckRefreshToken = _passBase + "/x/passport-login/web/cookie/info";
const std::string MyInfo = _apiBase + "/x/space/myinfo";
const std::string HistoryVideo = _apiBase + "/x/web-interface/history/cursor";
const std::string BroadcastServers = _apiBase + "/x/web-interface/broadcast/servers";
const std::string CollectionList = _apiBase + "/x/v3/fav/folder/created/list";
const std::string CollectionListAll = _apiBase + "/x/v3/fav/folder/created/list-all";
const std::string CollectionVideoList = _apiBase + "/x/v3/fav/resource/list";
Expand Down
28 changes: 25 additions & 3 deletions wiliwili/include/api/bilibili/result/inbox_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(FeedLikeResultWrapper, total);
class InboxMessageResult {
public:
uint64_t sender_uid, receiver_id;
uint64_t msg_seqno;
uint64_t msg_seqno, msg_key;
std::vector<uint64_t> at_uids;
int msg_type, msg_source;
nlohmann::json content;
Expand All @@ -125,8 +125,8 @@ inline void from_json(const nlohmann::json& nlohmann_json_j, InboxMessageResult&
if (nlohmann_json_j.contains("content") && nlohmann_json_j.at("content").is_string()) {
nlohmann::json::parse(nlohmann_json_j.at("content").get<std::string>()).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));
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, sender_uid, receiver_id, msg_seqno, msg_key, msg_type,
msg_source, timestamp));
}

typedef std::vector<InboxMessageResult> InboxMessageListResult;
Expand Down Expand Up @@ -156,6 +156,19 @@ inline void from_json(const nlohmann::json& nlohmann_json_j, InboxMessageResultW
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, has_more, max_seqno));
}

class InboxSendResult {
public:
std::vector<InboxEmote> e_infos;
std::string msg_content;
uint64_t msg_key;
};
inline void from_json(const nlohmann::json& nlohmann_json_j, InboxSendResult& nlohmann_json_t) {
if (nlohmann_json_j.contains("e_infos") && nlohmann_json_j.at("e_infos").is_array()) {
nlohmann_json_j.at("e_infos").get_to(nlohmann_json_t.e_infos);
}
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, msg_content, msg_key));
}

class InboxAccountInfo {
public:
std::string name;
Expand Down Expand Up @@ -195,4 +208,13 @@ inline void from_json(const nlohmann::json& nlohmann_json_j, InboxChatResultWrap
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, has_more));
}

class BroadcastServerResult {
public:
std::string domain;
int ws_port;
int wss_port;
int heartbeat;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(BroadcastServerResult, domain, ws_port, heartbeat);

} // namespace bilibili
3 changes: 3 additions & 0 deletions wiliwili/include/fragment/inbox_chat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ class InboxChat : public brls::Box, public InboxMsgRequest {

void onMsgList(const bilibili::InboxMessageResultWrapper& result, bool refresh) override;

void onSendMsg(const bilibili::InboxSendResult& result) override;

void onError(const std::string& error) override;

private:
BRLS_BIND(RecyclingGrid, recyclingGrid, "inbox/msgList");
BRLS_BIND(brls::Label, labelTalker, "inbox/talker");
BRLS_BIND(brls::Box, inputReply, "inbox/reply/hint");
};
4 changes: 4 additions & 0 deletions wiliwili/include/presenter/inbox_msg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ class InboxMsgRequest : public Presenter {
public:
virtual void onMsgList(const bilibili::InboxMessageResultWrapper& result, bool refresh);

virtual void onSendMsg(const bilibili::InboxSendResult& result);

virtual void onError(const std::string& error);

void setTalkerId(uint64_t mid);

void requestData(bool refresh = false, int session_type = 1);

void sendMsg(const std::string& text);

protected:
uint64_t talkerId = 0;
uint64_t msgSeq = 0;
Expand Down
24 changes: 24 additions & 0 deletions wiliwili/source/api/mine_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ void BilibiliClient::fetch_inbox_msgs(const std::string& talker_id, size_t size,
}, callback, error);
}

void BilibiliClient::send_inbox_msg(const std::string& sender_id,
const std::string& receiver_id,
const std::string& message,
const std::string& csrf,
const std::function<void(InboxSendResult)>& callback,
const ErrorCallback& error) {
cpr::Payload payload = {
{"msg[msg_type]", "1"},
{"msg[content]", message},
{"msg[sender_uid]", sender_id},
{"msg[receiver_id]", receiver_id},
{"msg[receiver_type]", "1"},
{"msg[msg_status]", "0"},
{"msg[timestamp]", std::to_string(wiliwili::unix_time())},
{"msg[dev_id]", "0"},
{"msg[new_face_version]", "1"},
{"csrf", csrf},
};
HTTP::postResultAsync<InboxSendResult>(Api::ChatSendMsg, {
{"w_sender_uid", sender_id},
{"w_receiver_id", receiver_id},
}, payload, callback, error);
}

void BilibiliClient::msg_feed_reply(const MsgFeedCursor& cursor,
const std::function<void(FeedReplyResultWrapper)>& callback,
const ErrorCallback& error) {
Expand Down
33 changes: 27 additions & 6 deletions wiliwili/source/fragment/inbox_chat.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <borealis/core/touch/tap_gesture.hpp>
#include <borealis/core/thread.hpp>
#include <algorithm>

Expand Down Expand Up @@ -60,9 +61,9 @@ class DataSourceMsgList : public RecyclingGridDataSource {

void onItemSelected(RecyclingGrid* recycler, size_t index) override {}

void appendData(const bilibili::InboxMessageListResult& data) {
void appendData(const bilibili::InboxMessageResultWrapper& result) {
bool skip = false;
for (const auto& i : data) {
for (const auto& i : result.messages) {
skip = false;
for (const auto& j : this->list) {
if (j.msg_seqno == i.msg_seqno) {
Expand All @@ -74,6 +75,10 @@ class DataSourceMsgList : public RecyclingGridDataSource {
this->list.push_back(i);
}
}

for (auto& e : result.e_infos) {
this->emotes[e.text] = std::make_shared<bilibili::InboxEmote>(e);
}
}

void clearData() override { this->list.clear(); }
Expand Down Expand Up @@ -102,9 +107,20 @@ InboxChat::InboxChat(const bilibili::InboxChatResult& r) {
});
recyclingGrid->registerCell("Notice", []() { return new InboxNoticeCard(); });
recyclingGrid->onNextPage([this, r]() { this->requestData(false, r.session_type); });
recyclingGrid->setRefreshAction([this]() { this->recyclingGrid->forceRequestNextPage(); });

labelTalker->setText(r.account_info.name);

inputReply->registerClickAction([this](...) {
return brls::Application::getImeManager()->openForText(
[this](const std::string& text) {
if (text.empty()) return;
this->sendMsg(text);
},
"wiliwili/inbox/chat/hint"_i18n, "", 500, "", 0);
});
inputReply->addGestureRecognizer(new brls::TapGestureRecognizer(this->inputReply));

this->requestData(true, r.session_type);
}

Expand All @@ -119,13 +135,18 @@ void InboxChat::onMsgList(const bilibili::InboxMessageResultWrapper& result, boo
auto* datasource = dynamic_cast<DataSourceMsgList*>(recyclingGrid->getDataSource());
if (datasource && !refresh) {
if (!result.messages.empty()) {
datasource->appendData(result.messages);
datasource->appendData(result);
recyclingGrid->notifyDataChanged();
recyclingGrid->selectRowAt(datasource->getItemCount() - 1, true);
}
} else {
auto dataSource = new DataSourceMsgList(result, this->talkerId);
recyclingGrid->setDefaultCellFocus(dataSource->getItemCount() - 1);
recyclingGrid->setDataSource(dataSource);
datasource = new DataSourceMsgList(result, this->talkerId);
recyclingGrid->setDefaultCellFocus(datasource->getItemCount() - 1);
recyclingGrid->setDataSource(datasource);
}
});
}

void InboxChat::onSendMsg(const bilibili::InboxSendResult& result) {
brls::Threading::sync([this]() { this->recyclingGrid->forceRequestNextPage(); });
}
46 changes: 28 additions & 18 deletions wiliwili/source/presenter/inbox_chat.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#include "bilibili.h"
#include "presenter/inbox_chat.hpp"
#include "utils/number_helper.hpp"
#include "utils/config_helper.hpp"

void InboxChatRequest::onChatList(const bilibili::InboxChatListResult& result, bool refresh) {}

void InboxChatRequest::onError(const std::string& error) {}

void InboxChatRequest::requestData(bool refresh) {
CHECK_AND_SET_REQUEST

BILI::new_inbox_sessions(
refresh ? 0 : this->last_time,
[this, refresh](const bilibili::InboxChatResultWrapper& result) {
Expand All @@ -16,26 +19,33 @@ void InboxChatRequest::requestData(bool refresh) {
uids.push_back(std::to_string(s.talker_id));
}
}
uids.push_back(ProgramConfig::instance().getUserID());
this->last_time = wiliwili::unix_time() * 1000000;
if (uids.size() > 0) {
BILI::get_user_cards(
uids,
[this, result, refresh](const bilibili::UserCardListResult& users) {
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.pic_url = it->second.face;
}
BILI::get_user_cards(
uids,
[this, result, refresh](const bilibili::UserCardListResult& users) {
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.pic_url = it->second.face;
}
this->onChatList(list, refresh);
},
[this](BILI_ERR) { this->onError(error); });
}
}
this->onChatList(list, refresh);
UNSET_REQUEST
},
[this](BILI_ERR) {
this->onError(error);
UNSET_REQUEST
});
},
[this](BILI_ERR) { this->onError(error); });
[this](BILI_ERR) {
this->onError(error);
UNSET_REQUEST
});
}
36 changes: 30 additions & 6 deletions wiliwili/source/presenter/inbox_feed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,43 @@ void InboxFeedRequest::onError(const std::string& error) {}
void InboxFeedRequest::requestData(MsgFeedMode mode, bool refresh) {
switch (mode) {
case MsgFeedMode::REPLY:
CHECK_AND_SET_REQUEST
BILI::msg_feed_reply(
this->cursor, [this](const bilibili::FeedReplyResultWrapper &result) { this->onFeedReplyList(result); },
[this](BILI_ERR) { this->onError(error); });
this->cursor,
[this](const bilibili::FeedReplyResultWrapper& result) {
this->onFeedReplyList(result);
UNSET_REQUEST
},
[this](BILI_ERR) {
this->onError(error);
UNSET_REQUEST
});
break;
case MsgFeedMode::AT:
CHECK_AND_SET_REQUEST
BILI::msg_feed_at(
this->cursor, [this](const bilibili::FeedAtResultWrapper &result) { this->onFeedAtList(result); },
[this](BILI_ERR) { this->onError(error); });
this->cursor,
[this](const bilibili::FeedAtResultWrapper& result) {
this->onFeedAtList(result);
UNSET_REQUEST
},
[this](BILI_ERR) {
this->onError(error);
UNSET_REQUEST
});
break;
case MsgFeedMode::LIKE:
CHECK_AND_SET_REQUEST
BILI::msg_feed_like(
this->cursor, [this](const bilibili::FeedLikeResultWrapper &result) { this->onFeedLikeList(result); },
[this](BILI_ERR) { this->onError(error); });
this->cursor,
[this](const bilibili::FeedLikeResultWrapper& result) {
this->onFeedLikeList(result);
UNSET_REQUEST
},
[this](BILI_ERR) {
this->onError(error);
UNSET_REQUEST
});
break;
default:;
}
Expand Down
Loading

0 comments on commit c38a175

Please sign in to comment.