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 ++++++++++ abaddon.hpp | 1 + components/channels.cpp | 3 ++- discord/discord.cpp | 4 ++++ discord/discord.hpp | 1 + discord/store.cpp | 32 +++++++++++++++++++++++++++++++- discord/store.hpp | 2 ++ windows/mainwindow.cpp | 18 ++++++++++++++++-- windows/mainwindow.hpp | 5 +++++ 9 files changed, 72 insertions(+), 4 deletions(-) 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); diff --git a/abaddon.hpp b/abaddon.hpp index 320f621..0bd5d97 100644 --- a/abaddon.hpp +++ b/abaddon.hpp @@ -47,6 +47,7 @@ public: void ActionGuildSettings(Snowflake id); void ActionAddRecipient(Snowflake channel_id); void ActionViewPins(Snowflake channel_id); + void ActionViewThreads(Snowflake channel_id); bool ShowConfirm(const Glib::ustring &prompt, Gtk::Window *window = nullptr); diff --git a/components/channels.cpp b/components/channels.cpp index 644e090..f12d56a 100644 --- a/components/channels.cpp +++ b/components/channels.cpp @@ -308,7 +308,8 @@ void ChannelList::SetActiveChannel(Snowflake id) { if (channel_iter) { m_view.expand_to_path(m_model->get_path(channel_iter)); m_view.get_selection()->select(channel_iter); - } + } else + m_view.get_selection()->unselect_all(); } Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild) { diff --git a/discord/discord.cpp b/discord/discord.cpp index 82d2131..49684ae 100644 --- a/discord/discord.cpp +++ b/discord/discord.cpp @@ -249,6 +249,10 @@ std::set DiscordClient::GetChannelsInGuild(Snowflake id) const { return {}; } +std::vector DiscordClient::GetPublicThreads(Snowflake channel_id) const { + return m_store.GetThreads(channel_id); +} + bool DiscordClient::HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const { const auto base = ComputePermissions(user_id, guild_id); return (base & perm) == perm; diff --git a/discord/discord.hpp b/discord/discord.hpp index 619a898..fa4b4c3 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 GetPublicThreads(Snowflake channel_id) const; bool HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const; diff --git a/discord/store.cpp b/discord/store.cpp index 3cac46e..ba8e59a 100644 --- a/discord/store.cpp +++ b/discord/store.cpp @@ -499,6 +499,25 @@ std::vector Store::GetPinnedMessages(Snowflake channel_id) const { return ret; } +std::vector Store::GetThreads(Snowflake channel_id) const { + std::vector ret; + + Bind(m_get_threads_stmt, 1, channel_id); + while (FetchOne(m_get_threads_stmt)) { + Snowflake x; + Get(m_get_threads_stmt, 0, x); + auto chan = GetChannel(x); + if (chan.has_value()) + ret.push_back(*chan); + } + + Reset(m_get_threads_stmt); + + if (m_db_err != SQLITE_DONE) + fprintf(stderr, "error while fetching threads: %s\n", sqlite3_errstr(m_db_err)); + return ret; +} + std::optional Store::GetChannel(Snowflake id) const { Bind(m_get_chan_stmt, 1, id); if (!FetchOne(m_get_chan_stmt)) { @@ -1186,6 +1205,10 @@ bool Store::CreateStatements() { SELECT id FROM messages WHERE channel_id = ? AND pinned = 1 ORDER BY id ASC )"; + const char *get_threads = R"( + SELECT id FROM channels WHERE parent_id = ? AND type = 11 + )"; + m_db_err = sqlite3_prepare_v2(m_db, set_user, -1, &m_set_user_stmt, nullptr); if (m_db_err != SQLITE_OK) { fprintf(stderr, "failed to prepare set user statement: %s\n", sqlite3_errstr(m_db_err)); @@ -1326,7 +1349,13 @@ bool Store::CreateStatements() { m_db_err = sqlite3_prepare_v2(m_db, get_pins, -1, &m_get_pins_stmt, nullptr); if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare getp ins statement: %s\n", sqlite3_errstr(m_db_err)); + fprintf(stderr, "failed to prepare get pins statement: %s\n", sqlite3_errstr(m_db_err)); + return false; + } + + m_db_err = sqlite3_prepare_v2(m_db, get_threads, -1, &m_get_threads_stmt, nullptr); + if (m_db_err != SQLITE_OK) { + fprintf(stderr, "failed to prepare get threads statement: %s\n", sqlite3_errstr(m_db_err)); return false; } @@ -1358,6 +1387,7 @@ void Store::Cleanup() { sqlite3_finalize(m_get_last_msgs_stmt); sqlite3_finalize(m_get_msg_ids_stmt); sqlite3_finalize(m_get_pins_stmt); + sqlite3_finalize(m_get_threads_stmt); } void Store::Bind(sqlite3_stmt *stmt, int index, int num) const { diff --git a/discord/store.hpp b/discord/store.hpp index 7e7d6ea..76c8a8e 100644 --- a/discord/store.hpp +++ b/discord/store.hpp @@ -44,6 +44,7 @@ public: std::vector GetLastMessages(Snowflake id, size_t num) const; std::vector GetChannelMessageIDs(Snowflake id) const; std::vector GetPinnedMessages(Snowflake channel_id) const; + std::vector GetThreads(Snowflake channel_id) const; // public void ClearGuild(Snowflake id); void ClearChannel(Snowflake id); @@ -135,6 +136,7 @@ private: mutable sqlite3_stmt *m_get_last_msgs_stmt; mutable sqlite3_stmt *m_get_msg_ids_stmt; mutable sqlite3_stmt *m_get_pins_stmt; + mutable sqlite3_stmt *m_get_threads_stmt; }; template diff --git a/windows/mainwindow.cpp b/windows/mainwindow.cpp index 0d77e96..7ddaaf2 100644 --- a/windows/mainwindow.cpp +++ b/windows/mainwindow.cpp @@ -41,8 +41,10 @@ MainWindow::MainWindow() m_menu_view.set_submenu(m_menu_view_sub); m_menu_view_friends.set_label("Friends"); m_menu_view_pins.set_label("Pins"); + m_menu_view_threads.set_label("Threads"); m_menu_view_sub.append(m_menu_view_friends); m_menu_view_sub.append(m_menu_view_pins); + m_menu_view_sub.append(m_menu_view_threads); m_menu_view_sub.signal_popped_up().connect(sigc::mem_fun(*this, &MainWindow::OnViewSubmenuPopup)); m_menu_bar.append(m_menu_file); @@ -92,6 +94,10 @@ MainWindow::MainWindow() m_signal_action_view_pins.emit(GetChatActiveChannel()); }); + m_menu_view_threads.signal_activate().connect([this] { + m_signal_action_view_threads.emit(GetChatActiveChannel()); + }); + m_content_box.set_hexpand(true); m_content_box.set_vexpand(true); m_content_box.show(); @@ -243,8 +249,12 @@ void MainWindow::OnViewSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gd auto channel_id = GetChatActiveChannel(); auto channel = Abaddon::Get().GetDiscordClient().GetChannel(channel_id); m_menu_view_pins.set_sensitive(false); - if (channel.has_value()) - m_menu_view_pins.set_sensitive(channel->Type == ChannelType::GUILD_TEXT); + m_menu_view_threads.set_sensitive(false); + if (channel.has_value()) { + const bool b = channel->Type == ChannelType::GUILD_TEXT; + m_menu_view_pins.set_sensitive(b); + m_menu_view_threads.set_sensitive(b); + } } ChannelList *MainWindow::GetChannelList() { @@ -290,3 +300,7 @@ MainWindow::type_signal_action_add_recipient MainWindow::signal_action_add_recip MainWindow::type_signal_action_view_pins MainWindow::signal_action_view_pins() { return m_signal_action_view_pins; } + +MainWindow::type_signal_action_view_threads MainWindow::signal_action_view_threads() { + return m_signal_action_view_threads; +} diff --git a/windows/mainwindow.hpp b/windows/mainwindow.hpp index d037796..3b41d16 100644 --- a/windows/mainwindow.hpp +++ b/windows/mainwindow.hpp @@ -35,8 +35,10 @@ public: typedef sigc::signal type_signal_action_reload_css; typedef sigc::signal type_signal_action_join_guild; typedef sigc::signal type_signal_action_set_status; + // this should probably be removed typedef sigc::signal type_signal_action_add_recipient; // channel id typedef sigc::signal type_signal_action_view_pins; // channel id + typedef sigc::signal type_signal_action_view_threads; // channel id type_signal_action_connect signal_action_connect(); type_signal_action_disconnect signal_action_disconnect(); @@ -46,6 +48,7 @@ public: type_signal_action_set_status signal_action_set_status(); type_signal_action_add_recipient signal_action_add_recipient(); type_signal_action_view_pins signal_action_view_pins(); + type_signal_action_view_threads signal_action_view_threads(); protected: type_signal_action_connect m_signal_action_connect; @@ -56,6 +59,7 @@ protected: type_signal_action_set_status m_signal_action_set_status; type_signal_action_add_recipient m_signal_action_add_recipient; type_signal_action_view_pins m_signal_action_view_pins; + type_signal_action_view_threads m_signal_action_view_threads; protected: Gtk::Box m_main_box; @@ -90,5 +94,6 @@ protected: Gtk::Menu m_menu_view_sub; Gtk::MenuItem m_menu_view_friends; Gtk::MenuItem m_menu_view_pins; + Gtk::MenuItem m_menu_view_threads; void OnViewSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y); }; -- cgit v1.2.3