summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2021-12-05 03:57:26 -0500
committerouwou <26526779+ouwou@users.noreply.github.com>2021-12-05 03:57:26 -0500
commitaf567847970121765674dc8d0542b9c4a1f89ed1 (patch)
treea67af688c82fb3e49fee9fe60d5ab69ac2173b20 /src/components
parent246140688714936820b5c977665ad2a904fa7222 (diff)
downloadabaddon-portaudio-af567847970121765674dc8d0542b9c4a1f89ed1.tar.gz
abaddon-portaudio-af567847970121765674dc8d0542b9c4a1f89ed1.zip
basic unread indicators for channels
Diffstat (limited to 'src/components')
-rw-r--r--src/components/channels.cpp28
-rw-r--r--src/components/channels.hpp3
-rw-r--r--src/components/channelscellrenderer.cpp8
-rw-r--r--src/components/channelscellrenderer.hpp7
-rw-r--r--src/components/unreadrenderer.cpp15
-rw-r--r--src/components/unreadrenderer.hpp9
6 files changed, 62 insertions, 8 deletions
diff --git a/src/components/channels.cpp b/src/components/channels.cpp
index 455d3b1..f61abd2 100644
--- a/src/components/channels.cpp
+++ b/src/components/channels.cpp
@@ -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;
diff --git a/src/components/channels.hpp b/src/components/channels.hpp
index 6ab8174..99eff5f 100644
--- a/src/components/channels.hpp
+++ b/src/components/channels.hpp
@@ -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;
diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp
index 2526753..f4cd33c 100644
--- a/src/components/channelscellrenderer.cpp
+++ b/src/components/channelscellrenderer.cpp
@@ -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
diff --git a/src/components/channelscellrenderer.hpp b/src/components/channelscellrenderer.hpp
index ce8da54..4a9d428 100644
--- a/src/components/channelscellrenderer.hpp
+++ b/src/components/channelscellrenderer.hpp
@@ -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
diff --git a/src/components/unreadrenderer.cpp b/src/components/unreadrenderer.cpp
new file mode 100644
index 0000000..4e508fc
--- /dev/null
+++ b/src/components/unreadrenderer.cpp
@@ -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();
+ }
+}
diff --git a/src/components/unreadrenderer.hpp b/src/components/unreadrenderer.hpp
new file mode 100644
index 0000000..e333543
--- /dev/null
+++ b/src/components/unreadrenderer.hpp
@@ -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);
+};