forked from OpenGamers/abaddon
basic window to view threads
This commit is contained in:
10
abaddon.cpp
10
abaddon.cpp
@@ -15,6 +15,7 @@
|
|||||||
#include "windows/guildsettingswindow.hpp"
|
#include "windows/guildsettingswindow.hpp"
|
||||||
#include "windows/profilewindow.hpp"
|
#include "windows/profilewindow.hpp"
|
||||||
#include "windows/pinnedwindow.hpp"
|
#include "windows/pinnedwindow.hpp"
|
||||||
|
#include "windows/threadswindow.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma comment(lib, "crypt32.lib")
|
#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_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_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_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_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));
|
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();
|
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) {
|
bool Abaddon::ShowConfirm(const Glib::ustring &prompt, Gtk::Window *window) {
|
||||||
ConfirmDialog dlg(window != nullptr ? *window : *m_main_window);
|
ConfirmDialog dlg(window != nullptr ? *window : *m_main_window);
|
||||||
dlg.SetConfirmText(prompt);
|
dlg.SetConfirmText(prompt);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public:
|
|||||||
void ActionGuildSettings(Snowflake id);
|
void ActionGuildSettings(Snowflake id);
|
||||||
void ActionAddRecipient(Snowflake channel_id);
|
void ActionAddRecipient(Snowflake channel_id);
|
||||||
void ActionViewPins(Snowflake channel_id);
|
void ActionViewPins(Snowflake channel_id);
|
||||||
|
void ActionViewThreads(Snowflake channel_id);
|
||||||
|
|
||||||
bool ShowConfirm(const Glib::ustring &prompt, Gtk::Window *window = nullptr);
|
bool ShowConfirm(const Glib::ustring &prompt, Gtk::Window *window = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -308,7 +308,8 @@ void ChannelList::SetActiveChannel(Snowflake id) {
|
|||||||
if (channel_iter) {
|
if (channel_iter) {
|
||||||
m_view.expand_to_path(m_model->get_path(channel_iter));
|
m_view.expand_to_path(m_model->get_path(channel_iter));
|
||||||
m_view.get_selection()->select(channel_iter);
|
m_view.get_selection()->select(channel_iter);
|
||||||
}
|
} else
|
||||||
|
m_view.get_selection()->unselect_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild) {
|
Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild) {
|
||||||
|
|||||||
@@ -249,6 +249,10 @@ std::set<Snowflake> DiscordClient::GetChannelsInGuild(Snowflake id) const {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ChannelData> DiscordClient::GetPublicThreads(Snowflake channel_id) const {
|
||||||
|
return m_store.GetThreads(channel_id);
|
||||||
|
}
|
||||||
|
|
||||||
bool DiscordClient::HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const {
|
bool DiscordClient::HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const {
|
||||||
const auto base = ComputePermissions(user_id, guild_id);
|
const auto base = ComputePermissions(user_id, guild_id);
|
||||||
return (base & perm) == perm;
|
return (base & perm) == perm;
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public:
|
|||||||
std::optional<RoleData> GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const;
|
std::optional<RoleData> GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const;
|
||||||
std::set<Snowflake> GetUsersInGuild(Snowflake id) const;
|
std::set<Snowflake> GetUsersInGuild(Snowflake id) const;
|
||||||
std::set<Snowflake> GetChannelsInGuild(Snowflake id) const;
|
std::set<Snowflake> GetChannelsInGuild(Snowflake id) const;
|
||||||
|
std::vector<ChannelData> GetPublicThreads(Snowflake channel_id) const;
|
||||||
|
|
||||||
bool HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const;
|
bool HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const;
|
||||||
|
|
||||||
|
|||||||
@@ -499,6 +499,25 @@ std::vector<Message> Store::GetPinnedMessages(Snowflake channel_id) const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ChannelData> Store::GetThreads(Snowflake channel_id) const {
|
||||||
|
std::vector<ChannelData> 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<ChannelData> Store::GetChannel(Snowflake id) const {
|
std::optional<ChannelData> Store::GetChannel(Snowflake id) const {
|
||||||
Bind(m_get_chan_stmt, 1, id);
|
Bind(m_get_chan_stmt, 1, id);
|
||||||
if (!FetchOne(m_get_chan_stmt)) {
|
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
|
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);
|
m_db_err = sqlite3_prepare_v2(m_db, set_user, -1, &m_set_user_stmt, nullptr);
|
||||||
if (m_db_err != SQLITE_OK) {
|
if (m_db_err != SQLITE_OK) {
|
||||||
fprintf(stderr, "failed to prepare set user statement: %s\n", sqlite3_errstr(m_db_err));
|
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);
|
m_db_err = sqlite3_prepare_v2(m_db, get_pins, -1, &m_get_pins_stmt, nullptr);
|
||||||
if (m_db_err != SQLITE_OK) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1358,6 +1387,7 @@ void Store::Cleanup() {
|
|||||||
sqlite3_finalize(m_get_last_msgs_stmt);
|
sqlite3_finalize(m_get_last_msgs_stmt);
|
||||||
sqlite3_finalize(m_get_msg_ids_stmt);
|
sqlite3_finalize(m_get_msg_ids_stmt);
|
||||||
sqlite3_finalize(m_get_pins_stmt);
|
sqlite3_finalize(m_get_pins_stmt);
|
||||||
|
sqlite3_finalize(m_get_threads_stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Store::Bind(sqlite3_stmt *stmt, int index, int num) const {
|
void Store::Bind(sqlite3_stmt *stmt, int index, int num) const {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
std::vector<Message> GetLastMessages(Snowflake id, size_t num) const;
|
std::vector<Message> GetLastMessages(Snowflake id, size_t num) const;
|
||||||
std::vector<Snowflake> GetChannelMessageIDs(Snowflake id) const;
|
std::vector<Snowflake> GetChannelMessageIDs(Snowflake id) const;
|
||||||
std::vector<Message> GetPinnedMessages(Snowflake channel_id) const;
|
std::vector<Message> GetPinnedMessages(Snowflake channel_id) const;
|
||||||
|
std::vector<ChannelData> GetThreads(Snowflake channel_id) const; // public
|
||||||
|
|
||||||
void ClearGuild(Snowflake id);
|
void ClearGuild(Snowflake id);
|
||||||
void ClearChannel(Snowflake id);
|
void ClearChannel(Snowflake id);
|
||||||
@@ -135,6 +136,7 @@ private:
|
|||||||
mutable sqlite3_stmt *m_get_last_msgs_stmt;
|
mutable sqlite3_stmt *m_get_last_msgs_stmt;
|
||||||
mutable sqlite3_stmt *m_get_msg_ids_stmt;
|
mutable sqlite3_stmt *m_get_msg_ids_stmt;
|
||||||
mutable sqlite3_stmt *m_get_pins_stmt;
|
mutable sqlite3_stmt *m_get_pins_stmt;
|
||||||
|
mutable sqlite3_stmt *m_get_threads_stmt;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ MainWindow::MainWindow()
|
|||||||
m_menu_view.set_submenu(m_menu_view_sub);
|
m_menu_view.set_submenu(m_menu_view_sub);
|
||||||
m_menu_view_friends.set_label("Friends");
|
m_menu_view_friends.set_label("Friends");
|
||||||
m_menu_view_pins.set_label("Pins");
|
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_friends);
|
||||||
m_menu_view_sub.append(m_menu_view_pins);
|
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_view_sub.signal_popped_up().connect(sigc::mem_fun(*this, &MainWindow::OnViewSubmenuPopup));
|
||||||
|
|
||||||
m_menu_bar.append(m_menu_file);
|
m_menu_bar.append(m_menu_file);
|
||||||
@@ -92,6 +94,10 @@ MainWindow::MainWindow()
|
|||||||
m_signal_action_view_pins.emit(GetChatActiveChannel());
|
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_hexpand(true);
|
||||||
m_content_box.set_vexpand(true);
|
m_content_box.set_vexpand(true);
|
||||||
m_content_box.show();
|
m_content_box.show();
|
||||||
@@ -243,8 +249,12 @@ void MainWindow::OnViewSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gd
|
|||||||
auto channel_id = GetChatActiveChannel();
|
auto channel_id = GetChatActiveChannel();
|
||||||
auto channel = Abaddon::Get().GetDiscordClient().GetChannel(channel_id);
|
auto channel = Abaddon::Get().GetDiscordClient().GetChannel(channel_id);
|
||||||
m_menu_view_pins.set_sensitive(false);
|
m_menu_view_pins.set_sensitive(false);
|
||||||
if (channel.has_value())
|
m_menu_view_threads.set_sensitive(false);
|
||||||
m_menu_view_pins.set_sensitive(channel->Type == ChannelType::GUILD_TEXT);
|
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() {
|
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() {
|
MainWindow::type_signal_action_view_pins MainWindow::signal_action_view_pins() {
|
||||||
return m_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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,8 +35,10 @@ public:
|
|||||||
typedef sigc::signal<void> type_signal_action_reload_css;
|
typedef sigc::signal<void> type_signal_action_reload_css;
|
||||||
typedef sigc::signal<void> type_signal_action_join_guild;
|
typedef sigc::signal<void> type_signal_action_join_guild;
|
||||||
typedef sigc::signal<void> type_signal_action_set_status;
|
typedef sigc::signal<void> type_signal_action_set_status;
|
||||||
|
// this should probably be removed
|
||||||
typedef sigc::signal<void, Snowflake> type_signal_action_add_recipient; // channel id
|
typedef sigc::signal<void, Snowflake> type_signal_action_add_recipient; // channel id
|
||||||
typedef sigc::signal<void, Snowflake> type_signal_action_view_pins; // channel id
|
typedef sigc::signal<void, Snowflake> type_signal_action_view_pins; // channel id
|
||||||
|
typedef sigc::signal<void, Snowflake> type_signal_action_view_threads; // channel id
|
||||||
|
|
||||||
type_signal_action_connect signal_action_connect();
|
type_signal_action_connect signal_action_connect();
|
||||||
type_signal_action_disconnect signal_action_disconnect();
|
type_signal_action_disconnect signal_action_disconnect();
|
||||||
@@ -46,6 +48,7 @@ public:
|
|||||||
type_signal_action_set_status signal_action_set_status();
|
type_signal_action_set_status signal_action_set_status();
|
||||||
type_signal_action_add_recipient signal_action_add_recipient();
|
type_signal_action_add_recipient signal_action_add_recipient();
|
||||||
type_signal_action_view_pins signal_action_view_pins();
|
type_signal_action_view_pins signal_action_view_pins();
|
||||||
|
type_signal_action_view_threads signal_action_view_threads();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
type_signal_action_connect m_signal_action_connect;
|
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_set_status m_signal_action_set_status;
|
||||||
type_signal_action_add_recipient m_signal_action_add_recipient;
|
type_signal_action_add_recipient m_signal_action_add_recipient;
|
||||||
type_signal_action_view_pins m_signal_action_view_pins;
|
type_signal_action_view_pins m_signal_action_view_pins;
|
||||||
|
type_signal_action_view_threads m_signal_action_view_threads;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gtk::Box m_main_box;
|
Gtk::Box m_main_box;
|
||||||
@@ -90,5 +94,6 @@ protected:
|
|||||||
Gtk::Menu m_menu_view_sub;
|
Gtk::Menu m_menu_view_sub;
|
||||||
Gtk::MenuItem m_menu_view_friends;
|
Gtk::MenuItem m_menu_view_friends;
|
||||||
Gtk::MenuItem m_menu_view_pins;
|
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);
|
void OnViewSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user