From 40897ece3ced8bfc051708a8d85f413f330631a9 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 4 Aug 2021 21:30:24 -0400 Subject: basic window to view threads --- abaddon.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'abaddon.cpp') diff --git a/abaddon.cpp b/abaddon.cpp index ad33e45..22ca576 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -15,6 +15,7 @@ #include "windows/guildsettingswindow.hpp" #include "windows/profilewindow.hpp" #include "windows/pinnedwindow.hpp" +#include "windows/threadswindow.hpp" #ifdef _WIN32 #pragma comment(lib, "crypt32.lib") @@ -94,6 +95,7 @@ int Abaddon::StartGTK() { m_main_window->signal_action_set_status().connect(sigc::mem_fun(*this, &Abaddon::ActionSetStatus)); m_main_window->signal_action_add_recipient().connect(sigc::mem_fun(*this, &Abaddon::ActionAddRecipient)); m_main_window->signal_action_view_pins().connect(sigc::mem_fun(*this, &Abaddon::ActionViewPins)); + m_main_window->signal_action_view_threads().connect(sigc::mem_fun(*this, &Abaddon::ActionViewThreads)); m_main_window->GetChannelList()->signal_action_channel_item_select().connect(sigc::mem_fun(*this, &Abaddon::ActionChannelOpened)); m_main_window->GetChannelList()->signal_action_guild_leave().connect(sigc::mem_fun(*this, &Abaddon::ActionLeaveGuild)); @@ -616,6 +618,14 @@ void Abaddon::ActionViewPins(Snowflake channel_id) { window->show(); } +void Abaddon::ActionViewThreads(Snowflake channel_id) { + const auto data = m_discord.GetChannel(channel_id); + if (!data.has_value()) return; + auto window = new ThreadsWindow(*data); + ManageHeapWindow(window); + window->show(); +} + bool Abaddon::ShowConfirm(const Glib::ustring &prompt, Gtk::Window *window) { ConfirmDialog dlg(window != nullptr ? *window : *m_main_window); dlg.SetConfirmText(prompt); -- cgit v1.2.3 From 2a45d7173ab58e60b63ce1e1183d719442988a32 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:13:51 -0400 Subject: proper member list in threads --- abaddon.cpp | 5 ++++- components/memberlist.cpp | 7 ++++++- discord/discord.cpp | 35 +++++++++++++++++++++++++++++++++++ discord/discord.hpp | 9 +++++++++ discord/objects.cpp | 22 +++++++++++++++++++--- discord/objects.hpp | 28 +++++++++++++++++++++++----- 6 files changed, 96 insertions(+), 10 deletions(-) (limited to 'abaddon.cpp') diff --git a/abaddon.cpp b/abaddon.cpp index 22ca576..6e7a9a5 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -36,6 +36,7 @@ Abaddon::Abaddon() m_discord.signal_message_delete().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageDelete)); m_discord.signal_message_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageUpdate)); m_discord.signal_guild_member_list_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildMemberListUpdate)); + m_discord.signal_thread_member_list_update().connect([this](...) { m_main_window->UpdateMembers(); }); m_discord.signal_reaction_add().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReactionAdd)); m_discord.signal_reaction_remove().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReactionRemove)); m_discord.signal_guild_join_request_create().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildJoinRequestCreate)); @@ -472,7 +473,9 @@ void Abaddon::ActionChannelOpened(Snowflake id) { m_main_window->UpdateChatWindowContents(); } - if (channel->Type != ChannelType::DM && channel->Type != ChannelType::GROUP_DM && channel->GuildID.has_value()) { + if (channel->IsThread()) { + m_discord.SendThreadLazyLoad(id); + } else if (channel->Type != ChannelType::DM && channel->Type != ChannelType::GROUP_DM && channel->GuildID.has_value()) { m_discord.SendLazyLoad(id); if (m_discord.IsVerificationRequired(*channel->GuildID)) diff --git a/components/memberlist.cpp b/components/memberlist.cpp index e91ce88..804f443 100644 --- a/components/memberlist.cpp +++ b/components/memberlist.cpp @@ -127,7 +127,12 @@ void MemberList::UpdateMemberList() { return; } - auto ids = discord.GetUsersInGuild(m_guild_id); + std::set ids; + if (chan->IsThread()) { + const auto x = discord.GetUsersInThread(m_chan_id); + ids = { x.begin(), x.end() }; + } else + ids = discord.GetUsersInGuild(m_guild_id); // process all the shit first so its in proper order std::map pos_to_role; diff --git a/discord/discord.cpp b/discord/discord.cpp index c4276dc..d30e57d 100644 --- a/discord/discord.cpp +++ b/discord/discord.cpp @@ -265,6 +265,12 @@ std::set DiscordClient::GetChannelsInGuild(Snowflake id) const { return {}; } +std::vector DiscordClient::GetUsersInThread(Snowflake id) const { + if (auto it = m_thread_members.find(id); it != m_thread_members.end()) + return it->second; + return {}; +} + // there is an endpoint for this but it should be synced before this is called anyways std::vector DiscordClient::GetActiveThreads(Snowflake channel_id) const { return m_store.GetActiveThreads(channel_id); @@ -472,6 +478,14 @@ void DiscordClient::SendLazyLoad(Snowflake id) { m_websocket.Send(msg); } +void DiscordClient::SendThreadLazyLoad(Snowflake id) { + LazyLoadRequestMessage msg; + msg.GuildID = *GetChannel(id)->GuildID; + msg.ThreadIDs.emplace().push_back(id); + + m_websocket.Send(msg); +} + void DiscordClient::JoinGuild(std::string code) { m_http.MakePOST("/invites/" + code, "", [](auto) {}); } @@ -1223,6 +1237,9 @@ void DiscordClient::HandleGatewayMessage(std::string str) { case GatewayEvent::THREAD_UPDATE: { HandleGatewayThreadUpdate(m); } break; + case GatewayEvent::THREAD_MEMBER_LIST_UPDATE: { + HandleGatewayThreadMemberListUpdate(m); + } break; } } break; default: @@ -1758,6 +1775,19 @@ void DiscordClient::HandleGatewayThreadUpdate(const GatewayMessage &msg) { m_signal_thread_update.emit(data); } +void DiscordClient::HandleGatewayThreadMemberListUpdate(const GatewayMessage &msg) { + ThreadMemberListUpdateData data = msg.Data; + m_store.BeginTransaction(); + for (const auto &entry : data.Members) { + m_thread_members[data.ThreadID].push_back(entry.UserID); + if (entry.Member.User.has_value()) + m_store.SetUser(entry.Member.User->ID, *entry.Member.User); + m_store.SetGuildMember(data.GuildID, entry.Member.User->ID, entry.Member); + } + m_store.EndTransaction(); + m_signal_thread_member_list_update.emit(data); +} + void DiscordClient::HandleGatewayReadySupplemental(const GatewayMessage &msg) { ReadySupplementalData data = msg.Data; for (const auto &p : data.MergedPresences.Friends) { @@ -2126,6 +2156,7 @@ void DiscordClient::LoadEventMap() { m_event_map["THREAD_MEMBERS_UPDATE"] = GatewayEvent::THREAD_MEMBERS_UPDATE; m_event_map["THREAD_MEMBER_UPDATE"] = GatewayEvent::THREAD_MEMBER_UPDATE; m_event_map["THREAD_UPDATE"] = GatewayEvent::THREAD_UPDATE; + m_event_map["THREAD_MEMBER_LIST_UPDATE"] = GatewayEvent::THREAD_MEMBER_LIST_UPDATE; } DiscordClient::type_signal_gateway_ready DiscordClient::signal_gateway_ready() { @@ -2284,6 +2315,10 @@ DiscordClient::type_signal_thread_update DiscordClient::signal_thread_update() { return m_signal_thread_update; } +DiscordClient::type_signal_thread_member_list_update DiscordClient::signal_thread_member_list_update() { + return m_signal_thread_member_list_update; +} + DiscordClient::type_signal_added_to_thread DiscordClient::signal_added_to_thread() { return m_signal_added_to_thread; } diff --git a/discord/discord.hpp b/discord/discord.hpp index a9dc62e..f80d264 100644 --- a/discord/discord.hpp +++ b/discord/discord.hpp @@ -86,6 +86,7 @@ public: std::optional GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const; std::set GetUsersInGuild(Snowflake id) const; std::set GetChannelsInGuild(Snowflake id) const; + std::vector GetUsersInThread(Snowflake id) const; std::vector GetActiveThreads(Snowflake channel_id) const; void GetArchivedPublicThreads(Snowflake channel_id, sigc::slot callback); @@ -105,6 +106,7 @@ public: void DeleteMessage(Snowflake channel_id, Snowflake id); void EditMessage(Snowflake channel_id, Snowflake id, std::string content); void SendLazyLoad(Snowflake id); + void SendThreadLazyLoad(Snowflake id); void JoinGuild(std::string code); void LeaveGuild(Snowflake id); void KickUser(Snowflake user_id, Snowflake guild_id); @@ -246,6 +248,7 @@ private: void HandleGatewayThreadMembersUpdate(const GatewayMessage &msg); void HandleGatewayThreadMemberUpdate(const GatewayMessage &msg); void HandleGatewayThreadUpdate(const GatewayMessage &msg); + void HandleGatewayThreadMemberListUpdate(const GatewayMessage &msg); void HandleGatewayReadySupplemental(const GatewayMessage &msg); void HandleGatewayReconnect(const GatewayMessage &msg); void HandleGatewayInvalidSession(const GatewayMessage &msg); @@ -270,6 +273,7 @@ private: std::map m_user_to_status; std::map m_user_relationships; std::set m_joined_threads; + std::map> m_thread_members; UserData m_user_data; UserSettings m_user_settings; @@ -342,6 +346,7 @@ public: typedef sigc::signal type_signal_thread_list_sync; typedef sigc::signal type_signal_thread_members_update; typedef sigc::signal type_signal_thread_update; + typedef sigc::signal type_signal_thread_member_list_update; // not discord dispatch events typedef sigc::signal type_signal_added_to_thread; @@ -391,6 +396,8 @@ public: type_signal_thread_list_sync signal_thread_list_sync(); type_signal_thread_members_update signal_thread_members_update(); type_signal_thread_update signal_thread_update(); + type_signal_thread_member_list_update signal_thread_member_list_update(); + type_signal_added_to_thread signal_added_to_thread(); type_signal_removed_from_thread signal_removed_from_thread(); type_signal_message_sent signal_message_sent(); @@ -436,6 +443,8 @@ protected: type_signal_thread_list_sync m_signal_thread_list_sync; type_signal_thread_members_update m_signal_thread_members_update; type_signal_thread_update m_signal_thread_update; + type_signal_thread_member_list_update m_signal_thread_member_list_update; + type_signal_removed_from_thread m_signal_removed_from_thread; type_signal_added_to_thread m_signal_added_to_thread; type_signal_message_sent m_signal_message_sent; diff --git a/discord/objects.cpp b/discord/objects.cpp index fb713f4..725cba5 100644 --- a/discord/objects.cpp +++ b/discord/objects.cpp @@ -85,11 +85,16 @@ void to_json(nlohmann::json &j, const LazyLoadRequestMessage &m) { for (const auto &[key, chans] : *m.Channels) j["d"]["channels"][std::to_string(key)] = chans; } - j["d"]["typing"] = m.ShouldGetTyping; - j["d"]["activities"] = m.ShouldGetActivities; - j["d"]["threads"] = m.ShouldGetThreads; + if (m.ShouldGetTyping) + j["d"]["typing"] = *m.ShouldGetTyping; + if (m.ShouldGetActivities) + j["d"]["activities"] = *m.ShouldGetActivities; + if (m.ShouldGetThreads) + j["d"]["threads"] = *m.ShouldGetThreads; if (m.Members.has_value()) j["d"]["members"] = *m.Members; + if (m.ThreadIDs.has_value()) + j["d"]["thread_member_lists"] = *m.ThreadIDs; } void to_json(nlohmann::json &j, const UpdateStatusMessage &m) { @@ -511,3 +516,14 @@ void from_json(const nlohmann::json &j, ThreadMemberUpdateData &m) { void from_json(const nlohmann::json &j, ThreadUpdateData &m) { m.Thread = j; } + +void from_json(const nlohmann::json &j, ThreadMemberListUpdateData::UserEntry &m) { + JS_D("user_id", m.UserID); + JS_D("member", m.Member); +} + +void from_json(const nlohmann::json &j, ThreadMemberListUpdateData &m) { + JS_D("thread_id", m.ThreadID); + JS_D("guild_id", m.GuildID); + JS_D("members", m.Members); +} diff --git a/discord/objects.hpp b/discord/objects.hpp index daaa9b2..4613a85 100644 --- a/discord/objects.hpp +++ b/discord/objects.hpp @@ -77,6 +77,7 @@ enum class GatewayEvent : int { THREAD_LIST_SYNC, THREAD_MEMBER_UPDATE, THREAD_MEMBERS_UPDATE, + THREAD_MEMBER_LIST_UPDATE, }; enum class GatewayCloseCode : uint16_t { @@ -204,11 +205,12 @@ struct GuildMemberListUpdateMessage { struct LazyLoadRequestMessage { Snowflake GuildID; - bool ShouldGetTyping = false; - bool ShouldGetActivities = false; - bool ShouldGetThreads = false; - std::optional> Members; // snowflake? - std::optional>>> Channels; // channel ID -> range of sidebar + std::optional ShouldGetTyping; + std::optional ShouldGetActivities; + std::optional ShouldGetThreads; + std::optional> Members; // snowflake? + std::optional>>> Channels; // channel ID -> range of sidebar + std::optional> ThreadIDs; friend void to_json(nlohmann::json &j, const LazyLoadRequestMessage &m); }; @@ -720,3 +722,19 @@ struct ThreadUpdateData { friend void from_json(const nlohmann::json &j, ThreadUpdateData &m); }; + +struct ThreadMemberListUpdateData { + struct UserEntry { + Snowflake UserID; + // PresenceData Presence; + GuildMember Member; + + friend void from_json(const nlohmann::json &j, UserEntry &m); + }; + + Snowflake ThreadID; + Snowflake GuildID; + std::vector Members; + + friend void from_json(const nlohmann::json &j, ThreadMemberListUpdateData &m); +}; -- cgit v1.2.3 From 8059e524f166cdcb08f5ee7f3a3c8e72ffdd5d5b Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:42:59 -0400 Subject: fix build --- abaddon.cpp | 6 +++++- abaddon.hpp | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'abaddon.cpp') diff --git a/abaddon.cpp b/abaddon.cpp index 6e7a9a5..dcbc7d3 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -36,7 +36,7 @@ Abaddon::Abaddon() m_discord.signal_message_delete().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageDelete)); m_discord.signal_message_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageUpdate)); m_discord.signal_guild_member_list_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildMemberListUpdate)); - m_discord.signal_thread_member_list_update().connect([this](...) { m_main_window->UpdateMembers(); }); + m_discord.signal_thread_member_list_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnThreadMemberListUpdate)); m_discord.signal_reaction_add().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReactionAdd)); m_discord.signal_reaction_remove().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReactionRemove)); m_discord.signal_guild_join_request_create().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildJoinRequestCreate)); @@ -193,6 +193,10 @@ void Abaddon::DiscordOnGuildMemberListUpdate(Snowflake guild_id) { m_main_window->UpdateMembers(); } +void Abaddon::DiscordOnThreadMemberListUpdate(const ThreadMemberListUpdateData &data) { + m_main_window->UpdateMembers(); +} + void Abaddon::DiscordOnReactionAdd(Snowflake message_id, const Glib::ustring ¶m) { m_main_window->UpdateChatReactionAdd(message_id, param); } diff --git a/abaddon.hpp b/abaddon.hpp index 0bd5d97..2f203f7 100644 --- a/abaddon.hpp +++ b/abaddon.hpp @@ -66,6 +66,7 @@ public: void DiscordOnMessageDelete(Snowflake id, Snowflake channel_id); void DiscordOnMessageUpdate(Snowflake id, Snowflake channel_id); void DiscordOnGuildMemberListUpdate(Snowflake guild_id); + void DiscordOnThreadMemberListUpdate(const ThreadMemberListUpdateData &data); void DiscordOnReactionAdd(Snowflake message_id, const Glib::ustring ¶m); void DiscordOnReactionRemove(Snowflake message_id, const Glib::ustring ¶m); void DiscordOnGuildJoinRequestCreate(const GuildJoinRequestCreateData &data); -- cgit v1.2.3 From b0d609d3861ccf1c04a4be98ac3fdd7cf8dc53d6 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 22 Aug 2021 01:36:49 -0400 Subject: allow viewing all threads from within a thread --- abaddon.cpp | 6 +++++- windows/mainwindow.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'abaddon.cpp') diff --git a/abaddon.cpp b/abaddon.cpp index dcbc7d3..b40909d 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -626,8 +626,12 @@ void Abaddon::ActionViewPins(Snowflake channel_id) { } void Abaddon::ActionViewThreads(Snowflake channel_id) { - const auto data = m_discord.GetChannel(channel_id); + auto data = m_discord.GetChannel(channel_id); if (!data.has_value()) return; + if (data->IsThread()) { + data = m_discord.GetChannel(*data->ParentID); + if (!data.has_value()) return; + } auto window = new ThreadsWindow(*data); ManageHeapWindow(window); window->show(); diff --git a/windows/mainwindow.cpp b/windows/mainwindow.cpp index 0bfff7c..356be59 100644 --- a/windows/mainwindow.cpp +++ b/windows/mainwindow.cpp @@ -251,7 +251,7 @@ void MainWindow::OnViewSubmenuPopup(const Gdk::Rectangle* flipped_rect, const Gd m_menu_view_pins.set_sensitive(false); m_menu_view_threads.set_sensitive(false); if (channel.has_value()) { - m_menu_view_threads.set_sensitive(channel->Type == ChannelType::GUILD_TEXT); + m_menu_view_threads.set_sensitive(channel->Type == ChannelType::GUILD_TEXT || channel->IsThread()); m_menu_view_pins.set_sensitive(channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::DM || channel->Type == ChannelType::GROUP_DM); } } -- cgit v1.2.3 From af0cbcf2c18e385643778f8cf401a6aafadee75c Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Tue, 24 Aug 2021 01:18:37 -0400 Subject: dont try to open channels if they arent in store --- abaddon.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'abaddon.cpp') diff --git a/abaddon.cpp b/abaddon.cpp index b40909d..4ffa89a 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -454,6 +454,7 @@ void Abaddon::ActionChannelOpened(Snowflake id) { if (id == m_main_window->GetChatActiveChannel()) return; const auto channel = m_discord.GetChannel(id); + if (!channel.has_value()) return; if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS) m_main_window->set_title(std::string(APP_TITLE) + " - #" + *channel->Name); else { -- cgit v1.2.3 From 002004cb5f01d22601047433cc868359cf022842 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 3 Sep 2021 04:04:51 -0400 Subject: add notice for archived threads at top of chatwindow --- abaddon.cpp | 14 ++++++++++++++ abaddon.hpp | 1 + components/chatwindow.cpp | 11 +++++++++++ components/chatwindow.hpp | 4 ++++ 4 files changed, 30 insertions(+) (limited to 'abaddon.cpp') diff --git a/abaddon.cpp b/abaddon.cpp index 4ffa89a..5bf6771 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -40,6 +40,7 @@ Abaddon::Abaddon() m_discord.signal_reaction_add().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReactionAdd)); m_discord.signal_reaction_remove().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReactionRemove)); m_discord.signal_guild_join_request_create().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildJoinRequestCreate)); + m_discord.signal_thread_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnThreadUpdate)); m_discord.signal_message_sent().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageSent)); m_discord.signal_disconnected().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnDisconnect)); if (m_settings.GetPrefetch()) @@ -237,6 +238,15 @@ void Abaddon::DiscordOnDisconnect(bool is_reconnecting, GatewayCloseCode close_c } } +void Abaddon::DiscordOnThreadUpdate(const ThreadUpdateData &data) { + if (data.Thread.ID == m_main_window->GetChatActiveChannel()) { + if (data.Thread.ThreadMetadata->IsArchived) + m_main_window->GetChatWindow()->SetTopic("This thread is archived. Sending a message will unarchive it"); + else + m_main_window->GetChatWindow()->SetTopic(""); + } +} + const SettingsManager &Abaddon::GetSettings() const { return m_settings; } @@ -453,6 +463,8 @@ void Abaddon::ActionJoinGuildDialog() { void Abaddon::ActionChannelOpened(Snowflake id) { if (id == m_main_window->GetChatActiveChannel()) return; + m_main_window->GetChatWindow()->SetTopic(""); + const auto channel = m_discord.GetChannel(id); if (!channel.has_value()) return; if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS) @@ -480,6 +492,8 @@ void Abaddon::ActionChannelOpened(Snowflake id) { if (channel->IsThread()) { m_discord.SendThreadLazyLoad(id); + if (channel->ThreadMetadata->IsArchived) + m_main_window->GetChatWindow()->SetTopic("This thread is archived. Sending a message will unarchive it"); } else if (channel->Type != ChannelType::DM && channel->Type != ChannelType::GROUP_DM && channel->GuildID.has_value()) { m_discord.SendLazyLoad(id); diff --git a/abaddon.hpp b/abaddon.hpp index 2f203f7..92485fb 100644 --- a/abaddon.hpp +++ b/abaddon.hpp @@ -72,6 +72,7 @@ public: void DiscordOnGuildJoinRequestCreate(const GuildJoinRequestCreateData &data); void DiscordOnMessageSent(const Message &data); void DiscordOnDisconnect(bool is_reconnecting, GatewayCloseCode close_code); + void DiscordOnThreadUpdate(const ThreadUpdateData &data); const SettingsManager &GetSettings() const; diff --git a/components/chatwindow.cpp b/components/chatwindow.cpp index 57b412b..c2bd688 100644 --- a/components/chatwindow.cpp +++ b/components/chatwindow.cpp @@ -31,6 +31,11 @@ ChatWindow::ChatWindow() { m_main->set_hexpand(true); m_main->set_vexpand(true); + m_topic.get_style_context()->add_class("channel-topic"); + m_topic.add(m_topic_text); + m_topic_text.set_halign(Gtk::ALIGN_START); + m_topic_text.show(); + m_input->signal_submit().connect(sigc::mem_fun(*this, &ChatWindow::OnInputSubmit)); m_input->signal_escape().connect([this]() { if (m_is_replying) @@ -84,6 +89,7 @@ ChatWindow::ChatWindow() { m_meta->add(*m_input_indicator); m_meta->add(*m_rate_limit_indicator); //m_scroll->add(*m_list); + m_main->add(m_topic); m_main->add(*m_chat); m_main->add(m_completer); m_main->add(*m_input); @@ -140,6 +146,11 @@ void ChatWindow::UpdateReactions(Snowflake id) { m_chat->UpdateMessageReactions(id); } +void ChatWindow::SetTopic(const std::string &text) { + m_topic_text.set_text(text); + m_topic.set_visible(text.length() > 0); +} + Snowflake ChatWindow::GetActiveChannel() const { return m_active_channel; } diff --git a/components/chatwindow.hpp b/components/chatwindow.hpp index ee2eef6..5ef8bad 100644 --- a/components/chatwindow.hpp +++ b/components/chatwindow.hpp @@ -28,6 +28,7 @@ public: void InsertChatInput(std::string text); Snowflake GetOldestListedMessage(); // oldest message that is currently in the ListBox void UpdateReactions(Snowflake id); + void SetTopic(const std::string &text); protected: bool m_is_replying = false; @@ -49,6 +50,9 @@ protected: //Gtk::ListBox *m_list; //Gtk::ScrolledWindow *m_scroll; + Gtk::EventBox m_topic; // todo probably make everything else go on the stack + Gtk::Label m_topic_text; + ChatList *m_chat; ChatInput *m_input; -- cgit v1.2.3