summaryrefslogtreecommitdiff
path: root/components/channels.hpp
blob: 3847af752e081b6ad18a33f6947d00902217d9fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#pragma once
#include <gtkmm.h>
#include <string>
#include <queue>
#include <mutex>
#include <unordered_set>
#include <unordered_map>
#include <sigc++/sigc++.h>
#include "../discord/discord.hpp"

static const constexpr int ChannelEmojiSize = 16;

class ChannelListRow : public Gtk::ListBoxRow {
public:
    bool IsUserCollapsed;
    Snowflake ID;
    std::unordered_set<ChannelListRow *> Children;
    ChannelListRow *Parent = nullptr;

    virtual void Collapse();
    virtual void Expand();

    static void MakeReadOnly(Gtk::TextView *tv);
};

class ChannelListRowDMHeader : public ChannelListRow {
public:
    ChannelListRowDMHeader();

protected:
    Gtk::EventBox *m_ev;
    Gtk::Box *m_box;
    Gtk::Label *m_lbl;
};

class ChannelListRowDMChannel : public ChannelListRow {
public:
    ChannelListRowDMChannel(const Channel *data);

protected:
    void OnImageLoad(Glib::RefPtr<Gdk::Pixbuf> buf);

    Gtk::EventBox *m_ev;
    Gtk::Box *m_box;
    Gtk::TextView *m_lbl;
    Gtk::Image *m_icon = nullptr;
};

class ChannelListRowGuild : public ChannelListRow {
public:
    ChannelListRowGuild(const Guild *data);

    int GuildIndex;

protected:
    void OnImageLoad(Glib::RefPtr<Gdk::Pixbuf> buf);

    Gtk::EventBox *m_ev;
    Gtk::Box *m_box;
    Gtk::TextView *m_lbl;
    Gtk::Image *m_icon;
};

class ChannelListRowCategory : public ChannelListRow {
public:
    ChannelListRowCategory(const Channel *data);

    virtual void Collapse();
    virtual void Expand();

protected:
    Gtk::EventBox *m_ev;
    Gtk::Box *m_box;
    Gtk::TextView *m_lbl;
    Gtk::Arrow *m_arrow;
};

class ChannelListRowChannel : public ChannelListRow {
public:
    ChannelListRowChannel(const Channel *data);

protected:
    Gtk::EventBox *m_ev;
    Gtk::Box *m_box;
    Gtk::TextView *m_lbl;
};

class ChannelList {
public:
    ChannelList();
    Gtk::Widget *GetRoot() const;
    void UpdateListing();
    void UpdateNewGuild(Snowflake id);
    void UpdateRemoveGuild(Snowflake id);
    void UpdateRemoveChannel(Snowflake id);
    void UpdateChannel(Snowflake id);
    void UpdateCreateDMChannel(Snowflake id);
    void UpdateCreateChannel(Snowflake id);
    void UpdateGuild(Snowflake id);
    void Clear();

    void SetActiveChannel(Snowflake id);

protected:
    Gtk::ListBox *m_list;
    Gtk::ScrolledWindow *m_main;

    ChannelListRowDMHeader *m_dm_header_row = nullptr;

    void CollapseRow(ChannelListRow *row);
    void ExpandRow(ChannelListRow *row);
    void DeleteRow(ChannelListRow *row);

    void UpdateChannelCategory(Snowflake id);

    void on_row_activated(Gtk::ListBoxRow *row);

    int m_guild_count;
    Gtk::Menu m_guild_menu;
    Gtk::MenuItem *m_guild_menu_copyid;
    Gtk::MenuItem *m_guild_menu_leave;
    void on_guild_menu_copyid();
    void on_guild_menu_leave();

    Gtk::Menu m_channel_menu;
    Gtk::MenuItem *m_channel_menu_copyid;
    void on_channel_menu_copyid();

    Glib::Dispatcher m_update_dispatcher;
    //mutable std::mutex m_update_mutex;
    //std::queue<std::unordered_set<Snowflake>> m_update_queue;

    // i would use one map but in really old guilds there can be a channel w/ same id as the guild so this hacky shit has to do
    std::unordered_map<Snowflake, ChannelListRow *> m_guild_id_to_row;
    std::unordered_map<Snowflake, ChannelListRow *> m_id_to_row;
    std::unordered_map<Snowflake, ChannelListRow *> m_dm_id_to_row;

    void InsertGuildAt(Snowflake id, int pos);

    void AddPrivateChannels(); // retard moment
    void UpdateListingInternal();
    void AttachGuildMenuHandler(Gtk::ListBoxRow *row);
    void AttachChannelMenuHandler(Gtk::ListBoxRow *row);

    void CheckBumpDM(Snowflake channel_id);

public:
    typedef sigc::signal<void, Snowflake> type_signal_action_channel_item_select;
    typedef sigc::signal<void, Snowflake> type_signal_action_guild_leave;

    type_signal_action_channel_item_select signal_action_channel_item_select();
    type_signal_action_guild_leave signal_action_guild_leave();

protected:
    type_signal_action_channel_item_select m_signal_action_channel_item_select;
    type_signal_action_guild_leave m_signal_action_guild_leave;
};