start friends list

This commit is contained in:
ouwou 2021-05-07 01:57:08 -04:00
parent a74f66513b
commit 86ab14e5ec
8 changed files with 278 additions and 2 deletions

View File

@ -84,13 +84,13 @@ public:
void ShowUserMenu(const GdkEvent *event, Snowflake id, Snowflake guild_id);
void ManageHeapWindow(Gtk::Window *window);
protected:
void ShowGuildVerificationGateDialog(Snowflake guild_id);
void SetupUserMenu();
void ManageHeapWindow(Gtk::Window *window);
Snowflake m_shown_user_menu_id;
Snowflake m_shown_user_menu_guild_id;

173
components/friendslist.cpp Normal file
View File

@ -0,0 +1,173 @@
#include "friendslist.hpp"
#include "../abaddon.hpp"
FriendsList::FriendsList()
: Gtk::Box(Gtk::ORIENTATION_VERTICAL)
, m_filter_mode(FILTER_FRIENDS) {
for (const auto &[id, type] : Abaddon::Get().GetDiscordClient().GetRelationships()) {
const auto user = Abaddon::Get().GetDiscordClient().GetUser(id);
if (!user.has_value()) continue;
auto *row = Gtk::manage(new FriendsListFriendRow(type, *user));
m_list.add(*row);
row->show();
}
constexpr static std::array<const char *, 4> strs = {
"Friends",
"Online",
"Pending",
"Blocked",
};
for (const auto &x : strs) {
auto *btn = Gtk::manage(new Gtk::RadioButton(m_group, x));
m_buttons.add(*btn);
btn->show();
btn->signal_toggled().connect([this, btn, str = x] {
if (!btn->get_active()) return;
switch (str[0]) { // hehe
case 'F':
m_filter_mode = FILTER_FRIENDS;
break;
case 'O':
m_filter_mode = FILTER_ONLINE;
break;
case 'P':
m_filter_mode = FILTER_PENDING;
break;
case 'B':
m_filter_mode = FILTER_BLOCKED;
break;
}
m_list.invalidate_filter();
});
}
m_buttons.set_homogeneous(true);
m_buttons.set_halign(Gtk::ALIGN_CENTER);
m_add.set_halign(Gtk::ALIGN_CENTER);
m_add.set_margin_top(5);
m_add.set_margin_bottom(5);
m_scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_list.set_sort_func(sigc::mem_fun(*this, &FriendsList::ListSortFunc));
m_list.set_filter_func(sigc::mem_fun(*this, &FriendsList::ListFilterFunc));
m_list.set_selection_mode(Gtk::SELECTION_NONE);
m_list.set_hexpand(true);
m_list.set_vexpand(true);
m_scroll.add(m_list);
add(m_add);
add(m_buttons);
add(m_scroll);
m_add.show();
m_scroll.show();
m_buttons.show();
m_list.show();
}
int FriendsList::ListSortFunc(Gtk::ListBoxRow *a_, Gtk::ListBoxRow *b_) {
auto *a = dynamic_cast<FriendsListFriendRow *>(a_);
auto *b = dynamic_cast<FriendsListFriendRow *>(b_);
if (a == nullptr || b == nullptr) return 0;
return a->Name.compare(b->Name);
}
bool FriendsList::ListFilterFunc(Gtk::ListBoxRow *row_) {
auto *row = dynamic_cast<FriendsListFriendRow *>(row_);
if (row == nullptr) return false;
switch (m_filter_mode) {
case FILTER_FRIENDS:
return row->Type == RelationshipType::Friend;
case FILTER_ONLINE:
return false; // blah
case FILTER_PENDING:
return row->Type == RelationshipType::PendingIncoming || row->Type == RelationshipType::PendingOutgoing;
case FILTER_BLOCKED:
return row->Type == RelationshipType::Blocked;
default:
return false;
}
}
FriendsListAddComponent::FriendsListAddComponent()
: Gtk::Box(Gtk::ORIENTATION_VERTICAL)
, m_label("Add a Friend", Gtk::ALIGN_START)
, m_box(Gtk::ORIENTATION_HORIZONTAL)
, m_add("Add")
, m_status("Failed to whatever lol", Gtk::ALIGN_START) {
m_box.add(m_entry);
m_box.add(m_add);
m_box.add(m_status);
m_label.set_halign(Gtk::ALIGN_CENTER);
m_entry.set_placeholder_text("Enter a Username#1234");
add(m_label);
add(m_box);
show_all_children();
}
FriendsListFriendRow::FriendsListFriendRow(RelationshipType type, const UserData &data)
: Name(data.Username + "#" + data.Discriminator)
, Type(type)
, ID(data.ID) {
auto *ev = Gtk::manage(new Gtk::EventBox);
auto *box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
auto *img = Gtk::manage(new Gtk::Image(Abaddon::Get().GetImageManager().GetPlaceholder(32)));
auto *namelbl = Gtk::manage(new Gtk::Label(Name, Gtk::ALIGN_START));
const auto status = Abaddon::Get().GetDiscordClient().GetUserStatus(data.ID);
auto *statuslbl = Gtk::manage(new Gtk::Label(GetPresenceDisplayString(status), Gtk::ALIGN_START));
auto *lblbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
AddWidgetMenuHandler(ev, m_menu, [this] {
switch (Type) {
case RelationshipType::Blocked:
case RelationshipType::Friend:
m_remove.set_label("Remove");
break;
case RelationshipType::PendingIncoming:
m_remove.set_label("Ignore");
break;
case RelationshipType::PendingOutgoing:
m_remove.set_label("Cancel");
break;
default:
break;
}
});
m_remove.signal_activate().connect([this] {
m_signal_remove.emit();
});
m_menu.append(m_remove);
m_menu.show_all();
lblbox->set_valign(Gtk::ALIGN_CENTER);
img->set_margin_end(5);
lblbox->add(*namelbl);
lblbox->add(*statuslbl);
box->add(*img);
box->add(*lblbox);
ev->add(*box);
add(*ev);
show_all_children();
}
FriendsListFriendRow::type_signal_remove FriendsListFriendRow::signal_action_remove() {
return m_signal_remove;
}
FriendsListWindow::FriendsListWindow() {
add(m_friends);
set_default_size(500, 500);
get_style_context()->add_class("app-window");
get_style_context()->add_class("app-popup");
m_friends.show();
}

View File

@ -0,0 +1,66 @@
#pragma once
#include <gtkmm.h>
#include "../discord/relationship.hpp"
class FriendsListAddComponent : public Gtk::Box {
public:
FriendsListAddComponent();
private:
Gtk::Label m_label;
Gtk::Label m_status;
Gtk::Entry m_entry;
Gtk::Button m_add;
Gtk::Box m_box;
};
class FriendsList : public Gtk::Box {
public:
FriendsList();
private:
enum FilterMode {
FILTER_FRIENDS,
FILTER_ONLINE,
FILTER_PENDING,
FILTER_BLOCKED,
};
FilterMode m_filter_mode;
int ListSortFunc(Gtk::ListBoxRow *a, Gtk::ListBoxRow *b);
bool ListFilterFunc(Gtk::ListBoxRow *row);
FriendsListAddComponent m_add;
Gtk::RadioButtonGroup m_group;
Gtk::ButtonBox m_buttons;
Gtk::ScrolledWindow m_scroll;
Gtk::ListBox m_list;
};
class FriendsListFriendRow : public Gtk::ListBoxRow {
public:
FriendsListFriendRow(RelationshipType type, const UserData &str);
Snowflake ID;
RelationshipType Type;
Glib::ustring Name;
private:
Gtk::Menu m_menu;
Gtk::MenuItem m_remove; // or cancel or ignore
using type_signal_remove = sigc::signal<void>;
type_signal_remove m_signal_remove;
public:
type_signal_remove signal_action_remove();
};
class FriendsListWindow : public Gtk::Window {
public:
FriendsListWindow();
private:
FriendsList m_friends;
};

View File

@ -26,6 +26,20 @@ constexpr inline const char *GetPresenceString(PresenceStatus s) {
return "";
}
constexpr inline const char* GetPresenceDisplayString(PresenceStatus s) {
switch (s) {
case PresenceStatus::Online:
return "Online";
case PresenceStatus::Offline:
return "Offline";
case PresenceStatus::Idle:
return "Away";
case PresenceStatus::DND:
return "Do Not Disturb";
}
return "";
}
enum class ActivityType : int {
Game = 0,
Streaming = 1,

View File

@ -850,6 +850,10 @@ PresenceStatus DiscordClient::GetUserStatus(Snowflake id) const {
return PresenceStatus::Offline;
}
std::unordered_map<Snowflake, RelationshipType> DiscordClient::GetRelationships() const {
return m_user_relationships;
}
std::unordered_set<Snowflake> DiscordClient::GetRelationships(RelationshipType type) const {
std::unordered_set<Snowflake> ret;
for (const auto &[id, rtype] : m_user_relationships)

View File

@ -178,6 +178,7 @@ public:
PresenceStatus GetUserStatus(Snowflake id) const;
std::unordered_map<Snowflake, RelationshipType> GetRelationships() const;
std::unordered_set<Snowflake> GetRelationships(RelationshipType type) const;
private:

View File

@ -1,5 +1,6 @@
#include "mainwindow.hpp"
#include "../abaddon.hpp"
#include "../components/friendslist.hpp"
MainWindow::MainWindow()
: m_main_box(Gtk::ORIENTATION_VERTICAL)
@ -39,8 +40,14 @@ MainWindow::MainWindow()
m_menu_file_sub.append(m_menu_file_reload_css);
m_menu_file_sub.append(m_menu_file_clear_cache);
m_menu_view.set_label("View");
m_menu_view.set_submenu(m_menu_view_sub);
m_menu_view_friends.set_label("Friends");
m_menu_view_sub.append(m_menu_view_friends);
m_menu_bar.append(m_menu_file);
m_menu_bar.append(m_menu_discord);
m_menu_bar.append(m_menu_view);
m_menu_bar.show_all();
m_menu_discord_connect.signal_activate().connect([this] {
@ -79,6 +86,13 @@ MainWindow::MainWindow()
m_signal_action_add_recipient.emit(GetChatActiveChannel());
});
m_menu_view_friends.signal_activate().connect([this] {
auto *window = new FriendsListWindow;
window->set_position(Gtk::WIN_POS_CENTER);
window->show();
Abaddon::Get().ManageHeapWindow(window);
});
m_content_box.set_hexpand(true);
m_content_box.set_vexpand(true);
m_content_box.show();

View File

@ -93,4 +93,8 @@ protected:
Gtk::MenuItem m_menu_file_reload_settings;
Gtk::MenuItem m_menu_file_reload_css;
Gtk::MenuItem m_menu_file_clear_cache;
Gtk::MenuItem m_menu_view;
Gtk::Menu m_menu_view_sub;
Gtk::MenuItem m_menu_view_friends;
};