mirror of
https://github.com/celisej567/abaddon.git
synced 2026-09-19 20:11:59 +03:00
basic unread indicators for channels
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
#include "channels.hpp"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include "abaddon.hpp"
|
||||
#include "imgmanager.hpp"
|
||||
#include "util.hpp"
|
||||
#include "statusindicator.hpp"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
ChannelList::ChannelList()
|
||||
: Glib::ObjectBase(typeid(ChannelList))
|
||||
, Gtk::ScrolledWindow()
|
||||
, m_model(Gtk::TreeStore::create(m_columns))
|
||||
, m_menu_guild_copy_id("_Copy ID", true)
|
||||
, m_menu_guild_settings("View _Settings", true)
|
||||
, m_menu_guild_leave("_Leave", true)
|
||||
, m_menu_category_copy_id("_Copy ID", true)
|
||||
, m_menu_channel_copy_id("_Copy ID", true)
|
||||
, m_menu_channel_mark_as_read("Mark as _Read", true)
|
||||
, m_menu_dm_copy_id("_Copy ID", true)
|
||||
, m_menu_dm_close("") // changes depending on if group or not
|
||||
, m_menu_thread_copy_id("_Copy ID", true)
|
||||
@@ -24,6 +24,7 @@ ChannelList::ChannelList()
|
||||
, m_menu_thread_unarchive("_Unarchive", true) {
|
||||
get_style_context()->add_class("channel-list");
|
||||
|
||||
// todo: move to method
|
||||
const auto cb = [this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) {
|
||||
auto row = *m_model->get_iter(path);
|
||||
const auto type = row[m_columns.m_type];
|
||||
@@ -40,7 +41,9 @@ ChannelList::ChannelList()
|
||||
}
|
||||
|
||||
if (type == RenderType::TextChannel || type == RenderType::DM || type == RenderType::Thread) {
|
||||
m_signal_action_channel_item_select.emit(static_cast<Snowflake>(row[m_columns.m_id]));
|
||||
const auto id = static_cast<Snowflake>(row[m_columns.m_id]);
|
||||
m_signal_action_channel_item_select.emit(id);
|
||||
Abaddon::Get().GetDiscordClient().MarkAsRead(id, [](...) {});
|
||||
}
|
||||
};
|
||||
m_view.signal_row_activated().connect(cb, false);
|
||||
@@ -77,6 +80,7 @@ ChannelList::ChannelList()
|
||||
column->add_attribute(renderer->property_icon(), m_columns.m_icon);
|
||||
column->add_attribute(renderer->property_icon_animation(), m_columns.m_icon_anim);
|
||||
column->add_attribute(renderer->property_name(), m_columns.m_name);
|
||||
column->add_attribute(renderer->property_id(), m_columns.m_id);
|
||||
column->add_attribute(renderer->property_expanded(), m_columns.m_expanded);
|
||||
column->add_attribute(renderer->property_nsfw(), m_columns.m_nsfw);
|
||||
m_view.append_column(*column);
|
||||
@@ -98,13 +102,18 @@ ChannelList::ChannelList()
|
||||
m_menu_category_copy_id.signal_activate().connect([this] {
|
||||
Gtk::Clipboard::get()->set_text(std::to_string((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]));
|
||||
});
|
||||
|
||||
m_menu_category.append(m_menu_category_copy_id);
|
||||
m_menu_category.show_all();
|
||||
|
||||
m_menu_channel_copy_id.signal_activate().connect([this] {
|
||||
Gtk::Clipboard::get()->set_text(std::to_string((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]));
|
||||
});
|
||||
m_menu_channel_mark_as_read.signal_activate().connect([this] {
|
||||
Abaddon::Get().GetDiscordClient().MarkAsRead(static_cast<Snowflake>((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]), [](...) {});
|
||||
});
|
||||
m_menu_channel.append(m_menu_channel_copy_id);
|
||||
m_menu_channel.append(m_menu_channel_mark_as_read);
|
||||
m_menu_channel.show_all();
|
||||
|
||||
m_menu_dm_copy_id.signal_activate().connect([this] {
|
||||
@@ -159,6 +168,7 @@ ChannelList::ChannelList()
|
||||
discord.signal_added_to_thread().connect(sigc::mem_fun(*this, &ChannelList::OnThreadJoined));
|
||||
discord.signal_removed_from_thread().connect(sigc::mem_fun(*this, &ChannelList::OnThreadRemoved));
|
||||
discord.signal_guild_update().connect(sigc::mem_fun(*this, &ChannelList::UpdateGuild));
|
||||
discord.signal_message_ack().connect(sigc::mem_fun(*this, &ChannelList::OnMessageAck));
|
||||
}
|
||||
|
||||
void ChannelList::UpdateListing() {
|
||||
@@ -658,7 +668,7 @@ void ChannelList::UpdateCreateDMChannel(const ChannelData &dm) {
|
||||
|
||||
std::optional<UserData> top_recipient;
|
||||
const auto recipients = dm.GetDMRecipients();
|
||||
if (recipients.size() > 0)
|
||||
if (!recipients.empty())
|
||||
top_recipient = recipients[0];
|
||||
|
||||
auto iter = m_model->append(header_row->children());
|
||||
@@ -682,6 +692,12 @@ void ChannelList::UpdateCreateDMChannel(const ChannelData &dm) {
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelList::OnMessageAck(const MessageAckData &data) {
|
||||
// trick renderer into redrawing
|
||||
auto iter = GetIteratorForChannelFromID(data.ChannelID);
|
||||
if (iter) m_model->row_changed(m_model->get_path(iter), iter);
|
||||
}
|
||||
|
||||
void ChannelList::OnMessageCreate(const Message &msg) {
|
||||
const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(msg.ChannelID);
|
||||
if (!channel.has_value()) return;
|
||||
|
||||
@@ -89,6 +89,8 @@ protected:
|
||||
void AddPrivateChannels();
|
||||
void UpdateCreateDMChannel(const ChannelData &channel);
|
||||
|
||||
void OnMessageAck(const MessageAckData &data);
|
||||
|
||||
void OnMessageCreate(const Message &msg);
|
||||
Gtk::TreeModel::Path m_path_for_menu;
|
||||
|
||||
@@ -105,6 +107,7 @@ protected:
|
||||
|
||||
Gtk::Menu m_menu_channel;
|
||||
Gtk::MenuItem m_menu_channel_copy_id;
|
||||
Gtk::MenuItem m_menu_channel_mark_as_read;
|
||||
|
||||
Gtk::Menu m_menu_dm;
|
||||
Gtk::MenuItem m_menu_dm_copy_id;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "channelscellrenderer.hpp"
|
||||
#include "abaddon.hpp"
|
||||
#include <gtkmm.h>
|
||||
#include "unreadrenderer.hpp"
|
||||
|
||||
CellRendererChannels::CellRendererChannels()
|
||||
: Glib::ObjectBase(typeid(CellRendererChannels))
|
||||
, Gtk::CellRenderer()
|
||||
, m_property_type(*this, "render-type")
|
||||
, m_property_id(*this, "id")
|
||||
, m_property_name(*this, "name")
|
||||
, m_property_pixbuf(*this, "pixbuf")
|
||||
, m_property_pixbuf_animation(*this, "pixbuf-animation")
|
||||
@@ -26,6 +28,10 @@ Glib::PropertyProxy<RenderType> CellRendererChannels::property_type() {
|
||||
return m_property_type.get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<uint64_t> CellRendererChannels::property_id() {
|
||||
return m_property_id.get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<Glib::ustring> CellRendererChannels::property_name() {
|
||||
return m_property_name.get_proxy();
|
||||
}
|
||||
@@ -328,6 +334,8 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
|
||||
// setting property_foreground_rgba() sets this to true which makes non-nsfw cells use the property too which is bad
|
||||
// so unset it
|
||||
m_renderer_text.property_foreground_set() = false;
|
||||
|
||||
UnreadRenderer::RenderUnreadOnChannel(m_property_id.get_value(), cr, background_area, cell_area);
|
||||
}
|
||||
|
||||
// thread
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <gdkmm/pixbufanimation.h>
|
||||
#include <glibmm/property.h>
|
||||
#include <map>
|
||||
#include "discord/snowflake.hpp"
|
||||
|
||||
enum class RenderType : uint8_t {
|
||||
Guild,
|
||||
@@ -20,6 +21,7 @@ public:
|
||||
virtual ~CellRendererChannels();
|
||||
|
||||
Glib::PropertyProxy<RenderType> property_type();
|
||||
Glib::PropertyProxy<uint64_t> property_id();
|
||||
Glib::PropertyProxy<Glib::ustring> property_name();
|
||||
Glib::PropertyProxy<Glib::RefPtr<Gdk::Pixbuf>> property_icon();
|
||||
Glib::PropertyProxy<Glib::RefPtr<Gdk::PixbufAnimation>> property_icon_animation();
|
||||
@@ -106,8 +108,9 @@ protected:
|
||||
private:
|
||||
Gtk::CellRendererText m_renderer_text;
|
||||
|
||||
Glib::Property<RenderType> m_property_type; // all
|
||||
Glib::Property<Glib::ustring> m_property_name; // all
|
||||
Glib::Property<RenderType> m_property_type; // all
|
||||
Glib::Property<Glib::ustring> m_property_name; // all
|
||||
Glib::Property<uint64_t> m_property_id;
|
||||
Glib::Property<Glib::RefPtr<Gdk::Pixbuf>> m_property_pixbuf; // guild, dm
|
||||
Glib::Property<Glib::RefPtr<Gdk::PixbufAnimation>> m_property_pixbuf_animation; // guild
|
||||
Glib::Property<bool> m_property_expanded; // category
|
||||
|
||||
15
src/components/unreadrenderer.cpp
Normal file
15
src/components/unreadrenderer.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "unreadrenderer.hpp"
|
||||
#include "abaddon.hpp"
|
||||
|
||||
void UnreadRenderer::RenderUnreadOnChannel(Snowflake id, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area) {
|
||||
const auto state = Abaddon::Get().GetDiscordClient().GetUnreadStateForChannel(id);
|
||||
if (state >= 0) {
|
||||
cr->set_source_rgb(1.0, 1.0, 1.0);
|
||||
const auto x = cell_area.get_x() + 1;
|
||||
const auto y = cell_area.get_y();
|
||||
const auto w = cell_area.get_width();
|
||||
const auto h = cell_area.get_height();
|
||||
cr->rectangle(x, y, 3, h);
|
||||
cr->fill();
|
||||
}
|
||||
}
|
||||
9
src/components/unreadrenderer.hpp
Normal file
9
src/components/unreadrenderer.hpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <cairomm/context.h>
|
||||
#include <gdkmm/rectangle.h>
|
||||
#include "discord/snowflake.hpp"
|
||||
|
||||
class UnreadRenderer {
|
||||
public:
|
||||
static void RenderUnreadOnChannel(Snowflake id, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area);
|
||||
};
|
||||
Reference in New Issue
Block a user