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

ProfileWindow::ProfileWindow(Snowflake user_id)
    : ID(user_id)
    , m_main(Gtk::ORIENTATION_VERTICAL)
    , m_upper(Gtk::ORIENTATION_HORIZONTAL)
    , m_badges(Gtk::ORIENTATION_HORIZONTAL)
    , m_pane_info(user_id)
    , m_pane_guilds(user_id)
    , m_pane_friends(user_id) {
    auto &discord = Abaddon::Get().GetDiscordClient();
    auto user = *discord.GetUser(ID);

    discord.FetchUserProfile(user_id, sigc::mem_fun(*this, &ProfileWindow::OnFetchProfile));

    set_name("user-profile");
    set_default_size(450, 375);
    set_title(user.Username + "#" + user.Discriminator);
    set_position(Gtk::WIN_POS_CENTER);
    get_style_context()->add_class("app-window");
    get_style_context()->add_class("app-popup");
    get_style_context()->add_class("user-profile-window");
    m_main.get_style_context()->add_class("profile-main-container");
    m_avatar.get_style_context()->add_class("profile-avatar");
    m_username.get_style_context()->add_class("profile-username");
    m_switcher.get_style_context()->add_class("profile-switcher");
    m_stack.get_style_context()->add_class("profile-stack");
    m_badges.get_style_context()->add_class("profile-badges");

    m_scroll.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
    m_scroll.set_vexpand(true);
    m_scroll.set_propagate_natural_height(true);

    if (user.HasAvatar())
        AddPointerCursor(m_avatar_ev);
    m_avatar_ev.signal_button_press_event().connect([this, user](GdkEventButton *event) -> bool {
        if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) {
            if (user.HasAnimatedAvatar())
                LaunchBrowser(user.GetAvatarURL("gif", "512"));
            else
                LaunchBrowser(user.GetAvatarURL("png", "512"));
        }
        return false;
    });

    static const bool show_animations = Abaddon::Get().GetSettings().GetShowAnimations();
    auto &img = Abaddon::Get().GetImageManager();
    m_avatar.property_pixbuf() = img.GetPlaceholder(64);
    auto icon_cb = [this](const Glib::RefPtr<Gdk::Pixbuf> &pb) {
        set_icon(pb);
    };
    img.LoadFromURL(user.GetAvatarURL("png", "64"), sigc::track_obj(icon_cb, *this));

    if (show_animations && user.HasAnimatedAvatar()) {
        auto cb = [this](const Glib::RefPtr<Gdk::PixbufAnimation> &pb) {
            m_avatar.property_pixbuf_animation() = pb;
        };
        img.LoadAnimationFromURL(user.GetAvatarURL("gif", "64"), 64, 64, sigc::track_obj(cb, *this));
    } else {
        auto cb = [this](const Glib::RefPtr<Gdk::Pixbuf> &pb) {
            m_avatar.property_pixbuf() = pb->scale_simple(64, 64, Gdk::INTERP_BILINEAR);
        };
        img.LoadFromURL(user.GetAvatarURL("png", "64"), sigc::track_obj(cb, *this));
    }

    m_username.set_markup(user.GetEscapedString());

    m_switcher.set_stack(m_stack);
    m_switcher.set_halign(Gtk::ALIGN_START);
    m_switcher.set_hexpand(true);

    m_stack.add(m_pane_info, "info", "User Info");
    m_stack.add(m_pane_guilds, "guilds", "Mutual Servers");
    m_stack.add(m_pane_friends, "friends", "Mutual Friends");

    m_badges.set_valign(Gtk::ALIGN_CENTER);
    m_badges_scroll.set_hexpand(true);
    m_badges_scroll.set_propagate_natural_width(true);
    m_badges_scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER);

    m_upper.set_halign(Gtk::ALIGN_START);
    m_avatar.set_halign(Gtk::ALIGN_START);
    m_username.set_halign(Gtk::ALIGN_START);
    m_avatar_ev.add(m_avatar);
    m_upper.add(m_avatar_ev);
    m_upper.add(m_username);
    m_badges_scroll.add(m_badges);
    m_upper.add(m_badges_scroll);
    m_main.add(m_upper);
    m_main.add(m_switcher);
    m_scroll.add(m_stack);
    m_main.add(m_scroll);
    add(m_main);
    show_all_children();
}

void ProfileWindow::OnFetchProfile(const UserProfileData &data) {
    m_pane_info.SetConnections(data.ConnectedAccounts);
    m_pane_guilds.SetMutualGuilds(data.MutualGuilds);

    for (auto child : m_badges.get_children())
        delete child;

    if (!data.User.PublicFlags.has_value()) return;
    const auto x = *data.User.PublicFlags;
    for (uint64_t i = 1; i <= UserData::MaxFlag; i <<= 1) {
        if (!(x & i)) continue;
        const std::string name = UserData::GetFlagName(i);
        if (name == "unknown") continue;
        Glib::RefPtr<Gdk::Pixbuf> pixbuf;
        try {
            if (name == "verifiedbot")
                pixbuf = Gdk::Pixbuf::create_from_file("./res/checkmark.png", 24, 24);
            else
                pixbuf = Gdk::Pixbuf::create_from_file("./res/" + name + ".png", 24, 24);
        } catch (const Glib::Exception &e) {
            pixbuf = Abaddon::Get().GetImageManager().GetPlaceholder(24);
        }
        if (!pixbuf) continue;
        auto *image = Gtk::manage(new Gtk::Image(pixbuf));
        image->get_style_context()->add_class("profile-badge");
        image->set_tooltip_text(UserData::GetFlagReadableName(i));
        image->show();
        m_badges.add(*image);
    }
}