summaryrefslogtreecommitdiff
path: root/windows/guildsettings/invitespane.cpp
blob: a47460f99acb04cebf873375488073bb1de174bf (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
#include "invitespane.hpp"
#include "../../abaddon.hpp"

GuildSettingsInvitesPane::GuildSettingsInvitesPane(Snowflake id)
    : GuildID(id)
    , m_model(Gtk::ListStore::create(m_columns))
    , m_menu_delete("Delete") {
    set_name("guild-invites-pane");
    set_hexpand(true);
    set_vexpand(true);

    m_view.signal_button_press_event().connect(sigc::mem_fun(*this, &GuildSettingsInvitesPane::OnTreeButtonPress), false);

    m_menu_delete.signal_activate().connect(sigc::mem_fun(*this, &GuildSettingsInvitesPane::OnMenuDelete));
    m_menu.append(m_menu_delete);
    m_menu.show_all();

    auto &discord = Abaddon::Get().GetDiscordClient();
    const auto self_id = discord.GetUserData().ID;

    if (discord.HasGuildPermission(self_id, GuildID, Permission::MANAGE_GUILD))
        discord.FetchGuildInvites(GuildID, sigc::mem_fun(*this, &GuildSettingsInvitesPane::OnInvitesFetch));

    discord.signal_invite_create().connect(sigc::mem_fun(*this, &GuildSettingsInvitesPane::OnInviteCreate));
    discord.signal_invite_delete().connect(sigc::mem_fun(*this, &GuildSettingsInvitesPane::OnInviteDelete));

    m_view.show();
    add(m_view);

    m_view.set_model(m_model);
    m_view.append_column("Code", m_columns.m_col_code);
    m_view.append_column("Expires", m_columns.m_col_expires);
    m_view.append_column("Created by", m_columns.m_col_inviter);
    m_view.append_column("Uses", m_columns.m_col_uses);
    m_view.append_column("Max uses", m_columns.m_col_max_uses);
    m_view.append_column("Grants temporary membership", m_columns.m_col_temporary);

    for (const auto column : m_view.get_columns())
        column->set_resizable(true);
}

void GuildSettingsInvitesPane::AppendInvite(const InviteData &invite) {
    auto &discord = Abaddon::Get().GetDiscordClient();
    auto &row = *m_model->append();
    row[m_columns.m_col_code] = invite.Code;
    if (invite.Inviter.has_value())
        row[m_columns.m_col_inviter] = invite.Inviter->Username + "#" + invite.Inviter->Discriminator;

    if (invite.MaxAge.has_value())
        if (*invite.MaxAge == 0)
            row[m_columns.m_col_expires] = "Never";
        else
            row[m_columns.m_col_expires] = FormatISO8601(*invite.CreatedAt, *invite.MaxAge);

    row[m_columns.m_col_uses] = *invite.Uses;
    if (*invite.MaxUses == 0)
        row[m_columns.m_col_max_uses] = "Unlimited";
    else
        row[m_columns.m_col_max_uses] = std::to_string(*invite.MaxUses);

    row[m_columns.m_col_temporary] = *invite.IsTemporary ? "Yes" : "No";
}

void GuildSettingsInvitesPane::OnInviteFetch(const std::optional<InviteData> &invite) {
    if (!invite.has_value()) return;
    AppendInvite(*invite);
}

void GuildSettingsInvitesPane::OnInvitesFetch(const std::vector<InviteData> &invites) {
    auto &discord = Abaddon::Get().GetDiscordClient();
    for (const auto &invite : invites)
        AppendInvite(invite);
}

void GuildSettingsInvitesPane::OnInviteCreate(const InviteData &invite) {
    if (invite.Guild->ID == GuildID)
        OnInviteFetch(std::make_optional(invite));
}

void GuildSettingsInvitesPane::OnInviteDelete(const InviteDeleteObject &data) {
    if (*data.GuildID == GuildID)
        for (auto &row : m_model->children())
            if (row[m_columns.m_col_code] == data.Code)
                m_model->erase(row);
}

void GuildSettingsInvitesPane::OnMenuDelete() {
    auto selected_row = *m_view.get_selection()->get_selected();
    if (selected_row) {
        auto code = static_cast<Glib::ustring>(selected_row[m_columns.m_col_code]);
        auto cb = [this](const bool success) {
            if (!success) {
                Gtk::MessageDialog dlg("Failed to delete invite", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
                dlg.run();
            }
        };
        Abaddon::Get().GetDiscordClient().DeleteInvite(code, sigc::track_obj(cb, *this));
    }
}

bool GuildSettingsInvitesPane::OnTreeButtonPress(GdkEventButton *event) {
    if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY) {
        auto &discord = Abaddon::Get().GetDiscordClient();
        const auto self_id = discord.GetUserData().ID;
        const auto can_manage = discord.HasGuildPermission(self_id, GuildID, Permission::MANAGE_GUILD);
        m_menu_delete.set_sensitive(can_manage);
        auto selection = m_view.get_selection();
        Gtk::TreeModel::Path path;
        if (m_view.get_path_at_pos(event->x, event->y, path)) {
            m_view.get_selection()->select(path);
            m_menu.popup_at_pointer(reinterpret_cast<GdkEvent *>(event));
        }

        return true;
    }

    return false;
}

GuildSettingsInvitesPane::ModelColumns::ModelColumns() {
    add(m_col_code);
    add(m_col_expires);
    add(m_col_inviter);
    add(m_col_temporary);
    add(m_col_uses);
    add(m_col_max_uses);
}