forked from OpenGamers/abaddon
make avatar loading a bit better
This commit is contained in:
@@ -128,6 +128,8 @@ add_executable(abaddon
|
|||||||
abaddon.cpp
|
abaddon.cpp
|
||||||
filecache.hpp
|
filecache.hpp
|
||||||
filecache.cpp
|
filecache.cpp
|
||||||
|
"imgmanager.hpp"
|
||||||
|
"imgmanager.cpp"
|
||||||
components/channels.hpp
|
components/channels.hpp
|
||||||
components/channels.cpp
|
components/channels.cpp
|
||||||
components/chatmessage.hpp
|
components/chatmessage.hpp
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ void Abaddon::ActionCopyGuildID(Snowflake id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Abaddon::ActionListChannelItemClick(Snowflake id) {
|
void Abaddon::ActionListChannelItemClick(Snowflake id) {
|
||||||
|
if (id == m_main_window->GetChatActiveChannel()) return;
|
||||||
|
|
||||||
auto *channel = m_discord.GetChannel(id);
|
auto *channel = m_discord.GetChannel(id);
|
||||||
if (channel->Type != ChannelType::DM && channel->Type != ChannelType::GROUP_DM)
|
if (channel->Type != ChannelType::DM && channel->Type != ChannelType::GROUP_DM)
|
||||||
m_discord.SendLazyLoad(id);
|
m_discord.SendLazyLoad(id);
|
||||||
@@ -283,8 +285,8 @@ void Abaddon::ActionReloadCSS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache &Abaddon::GetCache() {
|
ImageManager &Abaddon::GetImageManager() {
|
||||||
return m_cache;
|
return m_img_mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "discord/discord.hpp"
|
#include "discord/discord.hpp"
|
||||||
#include "windows/mainwindow.hpp"
|
#include "windows/mainwindow.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "filecache.hpp"
|
#include "imgmanager.hpp"
|
||||||
|
|
||||||
#define APP_TITLE "Abaddon"
|
#define APP_TITLE "Abaddon"
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
|
|
||||||
void ActionReloadCSS();
|
void ActionReloadCSS();
|
||||||
|
|
||||||
Cache &GetCache();
|
ImageManager &GetImageManager();
|
||||||
|
|
||||||
std::string GetDiscordToken() const;
|
std::string GetDiscordToken() const;
|
||||||
bool IsDiscordActive() const;
|
bool IsDiscordActive() const;
|
||||||
@@ -65,7 +65,7 @@ private:
|
|||||||
std::unordered_map<Snowflake, Snowflake> m_oldest_listed_message;
|
std::unordered_map<Snowflake, Snowflake> m_oldest_listed_message;
|
||||||
std::unordered_set<Snowflake> m_channels_history_loading;
|
std::unordered_set<Snowflake> m_channels_history_loading;
|
||||||
|
|
||||||
Cache m_cache;
|
ImageManager m_img_mgr;
|
||||||
|
|
||||||
mutable std::mutex m_mutex;
|
mutable std::mutex m_mutex;
|
||||||
Glib::RefPtr<Gtk::Application> m_gtk_app;
|
Glib::RefPtr<Gtk::Application> m_gtk_app;
|
||||||
|
|||||||
@@ -14,18 +14,16 @@ ChatMessageContainer::ChatMessageContainer(const Message *data) {
|
|||||||
m_author = Gtk::manage(new Gtk::Label);
|
m_author = Gtk::manage(new Gtk::Label);
|
||||||
m_timestamp = Gtk::manage(new Gtk::Label);
|
m_timestamp = Gtk::manage(new Gtk::Label);
|
||||||
|
|
||||||
static Glib::RefPtr<Gdk::Pixbuf> test = Gdk::Pixbuf::create_from_file("res/decamarks.png", 32, 32);
|
static auto placeholder = Gdk::Pixbuf::create_from_file("res/decamarks.png", 32, 32);
|
||||||
m_avatar = Gtk::manage(new Gtk::Image(test));
|
auto buf = Abaddon::Get().GetImageManager().GetFromURLIfCached(data->Author.GetAvatarURL());
|
||||||
|
if (buf)
|
||||||
|
m_avatar = Gtk::manage(new Gtk::Image(buf));
|
||||||
|
else
|
||||||
|
m_avatar = Gtk::manage(new Gtk::Image(placeholder));
|
||||||
|
|
||||||
m_avatar->set_valign(Gtk::ALIGN_START);
|
m_avatar->set_valign(Gtk::ALIGN_START);
|
||||||
m_avatar->set_margin_right(10);
|
m_avatar->set_margin_right(10);
|
||||||
|
|
||||||
if (data->Author.HasAvatar()) {
|
|
||||||
Abaddon::Get().GetCache().GetFileFromURL(data->Author.GetAvatarURL(), [this](std::string filepath) {
|
|
||||||
auto buf = Gdk::Pixbuf::create_from_file(filepath, 32, 32);
|
|
||||||
m_avatar->property_pixbuf() = buf;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get_style_context()->add_class("message-container");
|
get_style_context()->add_class("message-container");
|
||||||
m_author->get_style_context()->add_class("message-container-author");
|
m_author->get_style_context()->add_class("message-container-author");
|
||||||
m_timestamp->get_style_context()->add_class("message-container-timestamp");
|
m_timestamp->get_style_context()->add_class("message-container-timestamp");
|
||||||
@@ -67,6 +65,10 @@ ChatMessageContainer::ChatMessageContainer(const Message *data) {
|
|||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatMessageContainer::SetAvatarFromPixbuf(Glib::RefPtr<Gdk::Pixbuf> pixbuf) {
|
||||||
|
m_avatar->property_pixbuf() = pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
void ChatMessageContainer::Update() {
|
void ChatMessageContainer::Update() {
|
||||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||||
auto guild_id = discord.GetChannel(ChannelID)->GuildID;
|
auto guild_id = discord.GetChannel(ChannelID)->GuildID;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
|
|
||||||
ChatMessageContainer(const Message *data);
|
ChatMessageContainer(const Message *data);
|
||||||
void AddNewContent(Gtk::Widget *widget, bool prepend = false);
|
void AddNewContent(Gtk::Widget *widget, bool prepend = false);
|
||||||
|
void SetAvatarFromPixbuf(Glib::RefPtr<Gdk::Pixbuf> pixbuf);
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -115,6 +115,25 @@ void ChatWindow::ProcessMessage(const Message *data, bool prepend) {
|
|||||||
} else {
|
} else {
|
||||||
container = Gtk::manage(new ChatMessageContainer(data)); // only accesses timestamp and user
|
container = Gtk::manage(new ChatMessageContainer(data)); // only accesses timestamp and user
|
||||||
container->Update();
|
container->Update();
|
||||||
|
|
||||||
|
auto user_id = data->Author.ID;
|
||||||
|
const auto *user = Abaddon::Get().GetDiscordClient().GetUser(user_id);
|
||||||
|
if (user == nullptr) return;
|
||||||
|
Abaddon::Get().GetImageManager().LoadFromURL(user->GetAvatarURL(), [this, user_id](Glib::RefPtr<Gdk::Pixbuf> buf) {
|
||||||
|
// am i retarded?
|
||||||
|
Glib::signal_idle().connect([this, buf, user_id]() -> bool {
|
||||||
|
auto children = m_listbox->get_children();
|
||||||
|
for (auto child : children) {
|
||||||
|
auto *row = dynamic_cast<ChatMessageContainer *>(child);
|
||||||
|
if (row == nullptr) continue;
|
||||||
|
if (row->UserID == user_id) {
|
||||||
|
row->SetAvatarFromPixbuf(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
m_num_rows++;
|
m_num_rows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ struct User {
|
|||||||
friend void from_json(const nlohmann::json &j, User &m);
|
friend void from_json(const nlohmann::json &j, User &m);
|
||||||
|
|
||||||
bool HasAvatar() const;
|
bool HasAvatar() const;
|
||||||
std::string GetAvatarURL(std::string ext = "png", std::string size = "64") const;
|
std::string GetAvatarURL(std::string ext = "png", std::string size = "32") const;
|
||||||
};
|
};
|
||||||
|
|||||||
29
imgmanager.cpp
Normal file
29
imgmanager.cpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#include "imgmanager.hpp"
|
||||||
|
|
||||||
|
Cache &ImageManager::GetCache() {
|
||||||
|
return m_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageManager::LoadFromURL(std::string url, std::function<void(Glib::RefPtr<Gdk::Pixbuf>)> cb) {
|
||||||
|
if (m_pixs.find(url) != m_pixs.end()) {
|
||||||
|
cb(m_pixs.at(url));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cache.GetFileFromURL(url, [this, url, cb](std::string path) {
|
||||||
|
try {
|
||||||
|
auto buf = Gdk::Pixbuf::create_from_file(path);
|
||||||
|
m_pixs[url] = buf;
|
||||||
|
cb(buf);
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
fprintf(stderr, "err loading pixbuf from %s: %s\n", path.c_str(), e.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> ImageManager::GetFromURLIfCached(std::string url) {
|
||||||
|
if (m_pixs.find(url) != m_pixs.end())
|
||||||
|
return m_pixs.at(url);
|
||||||
|
|
||||||
|
return Glib::RefPtr<Gdk::Pixbuf>(nullptr);
|
||||||
|
}
|
||||||
17
imgmanager.hpp
Normal file
17
imgmanager.hpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
|
#include <gtkmm.h>
|
||||||
|
#include "filecache.hpp"
|
||||||
|
|
||||||
|
class ImageManager {
|
||||||
|
public:
|
||||||
|
Cache &GetCache();
|
||||||
|
void LoadFromURL(std::string url, std::function<void(Glib::RefPtr<Gdk::Pixbuf>)> cb);
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> GetFromURLIfCached(std::string url);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, Glib::RefPtr<Gdk::Pixbuf>> m_pixs;
|
||||||
|
Cache m_cache;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user