From 5703d06c7396814b239a621d03ef983372491d34 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 4 Nov 2023 20:54:15 -0400 Subject: show animated reactions --- src/components/chatmessage.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/components') diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp index 44396a2..d884077 100644 --- a/src/components/chatmessage.cpp +++ b/src/components/chatmessage.cpp @@ -620,7 +620,11 @@ Gtk::Widget *ChatMessageItemContainer::CreateReactionsComponent(const Message &d } else { // custom ev->set_tooltip_text(reaction.Emoji.Name); - auto img = Gtk::manage(new LazyImage(reaction.Emoji.GetURL(), 16, 16)); + auto *img = Gtk::make_managed(reaction.Emoji.GetURL(), 16, 16); + if (reaction.Emoji.IsEmojiAnimated() && Abaddon::Get().GetSettings().ShowAnimations) { + img->SetURL(reaction.Emoji.GetURL("gif")); + img->SetAnimated(true); + } img->set_can_focus(false); box->add(*img); } -- cgit v1.2.3 From cb83e30a76d76705c034541c0c1e9ef08b7b4946 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Thu, 9 Nov 2023 02:20:42 -0500 Subject: message input theme tweaking --- res/css/bare.css | 5 +++++ src/components/chatinput.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/components') diff --git a/res/css/bare.css b/res/css/bare.css index 80ef2f8..ec5b9a1 100644 --- a/res/css/bare.css +++ b/res/css/bare.css @@ -33,3 +33,8 @@ .status-indicator.idle { color: #FAA61A; } + +/* make room for attachment icon */ +.message-input.with-browse-icon { + padding-left: 30px; +} diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp index c802413..af092e1 100644 --- a/src/components/chatinput.cpp +++ b/src/components/chatinput.cpp @@ -20,7 +20,7 @@ ChatInputText::ChatInputText() { m_textview.signal_key_press_event().connect(cb, false); m_textview.set_hexpand(false); m_textview.set_halign(Gtk::ALIGN_FILL); - m_textview.set_valign(Gtk::ALIGN_CENTER); + m_textview.set_valign(Gtk::ALIGN_FILL); m_textview.set_wrap_mode(Gtk::WRAP_WORD_CHAR); m_textview.show(); add(m_textview); -- cgit v1.2.3 From 5cca270eb1c627ae59cf294c9670d31b288b768c Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Thu, 9 Nov 2023 22:08:14 -0500 Subject: more making message input look better --- res/css/bare.css | 9 ++++--- src/components/chatinput.cpp | 59 ++++++++++---------------------------------- src/components/chatinput.hpp | 6 ++--- 3 files changed, 22 insertions(+), 52 deletions(-) (limited to 'src/components') diff --git a/res/css/bare.css b/res/css/bare.css index ec5b9a1..595fd04 100644 --- a/res/css/bare.css +++ b/res/css/bare.css @@ -34,7 +34,10 @@ color: #FAA61A; } -/* make room for attachment icon */ -.message-input.with-browse-icon { - padding-left: 30px; +.message-input textview, .message-input textview text { + background-color: inherit; +} + +.message-input textview { + padding: 10px 5px; } diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp index af092e1..b6beaa5 100644 --- a/src/components/chatinput.cpp +++ b/src/components/chatinput.cpp @@ -113,30 +113,25 @@ ChatInputTextContainer::ChatInputTextContainer() { }; m_input.signal_key_press_proxy().connect(cb); + m_upload_button.set_image(m_upload_img); + m_upload_button.set_halign(Gtk::ALIGN_CENTER); + m_upload_button.set_valign(Gtk::ALIGN_CENTER); + m_upload_button.get_style_context()->add_class(GTK_STYLE_CLASS_FLAT); + m_upload_img.property_icon_name() = "document-send-symbolic"; m_upload_img.property_icon_size() = Gtk::ICON_SIZE_LARGE_TOOLBAR; m_upload_img.get_style_context()->add_class("message-input-browse-icon"); - AddPointerCursor(m_upload_ev); - - m_upload_ev.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool { - if (ev->button == GDK_BUTTON_PRIMARY) { - ShowFileChooser(); - // return focus - m_input.grab_focus(); - return true; - } - return false; + m_upload_button.signal_clicked().connect([this]() { + ShowFileChooser(); + m_input.grab_focus(); }); - m_upload_ev.add(m_upload_img); - add_overlay(m_upload_ev); - add(m_input); + m_upload_box.pack_start(m_upload_button); + pack_start(m_upload_box, false, false); + pack_start(m_input); show_all_children(); - - // stop the overlay from using (start) padding - signal_get_child_position().connect(sigc::mem_fun(*this, &ChatInputTextContainer::GetChildPosition), false); } void ChatInputTextContainer::ShowFileChooser() { @@ -160,39 +155,11 @@ ChatInputText &ChatInputTextContainer::Get() { } void ChatInputTextContainer::ShowChooserIcon() { - m_upload_ev.show(); + m_upload_button.show(); } void ChatInputTextContainer::HideChooserIcon() { - m_upload_ev.hide(); -} - -bool ChatInputTextContainer::GetChildPosition(Gtk::Widget *child, Gdk::Rectangle &pos) { - Gtk::Allocation main_alloc; - { - auto *grandchild = m_input.get_child(); - int x, y; - if (grandchild->translate_coordinates(m_input, 0, 0, x, y)) { - main_alloc.set_x(x); - main_alloc.set_y(y); - } else { - main_alloc.set_x(0); - main_alloc.set_y(0); - } - main_alloc.set_width(grandchild->get_allocated_width()); - main_alloc.set_height(grandchild->get_allocated_height()); - } - - Gtk::Requisition min, req; - child->get_preferred_size(min, req); - - // let css move it around - pos.set_x(0); - pos.set_y(0); - pos.set_width(std::max(min.width, std::min(main_alloc.get_width(), req.width))); - pos.set_height(std::max(min.height, std::min(main_alloc.get_height(), req.height))); - - return true; + m_upload_button.hide(); } ChatInputTextContainer::type_signal_add_attachment ChatInputTextContainer::signal_add_attachment() { diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp index a3c9742..7ee3921 100644 --- a/src/components/chatinput.hpp +++ b/src/components/chatinput.hpp @@ -98,7 +98,7 @@ private: }; // file upload, text -class ChatInputTextContainer : public Gtk::Overlay { +class ChatInputTextContainer : public Gtk::Box { public: ChatInputTextContainer(); @@ -110,9 +110,9 @@ public: private: void ShowFileChooser(); - bool GetChildPosition(Gtk::Widget *child, Gdk::Rectangle &pos); - Gtk::EventBox m_upload_ev; + Gtk::Box m_upload_box; + Gtk::Button m_upload_button; Gtk::Image m_upload_img; ChatInputText m_input; -- cgit v1.2.3 From 3d2f5abce4c591e35d64d428cc1df06407128211 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 17 Nov 2023 01:24:57 -0500 Subject: reimplement status indicator in member list --- README.md | 5 -- src/components/cellrenderermemberlist.cpp | 34 ++++++++- src/components/cellrenderermemberlist.hpp | 3 + src/components/channels.cpp | 1 - src/components/memberlist.cpp | 19 ++++- src/components/memberlist.hpp | 3 + src/components/statusindicator.cpp | 122 ------------------------------ src/components/statusindicator.hpp | 29 ------- 8 files changed, 56 insertions(+), 160 deletions(-) delete mode 100644 src/components/statusindicator.cpp delete mode 100644 src/components/statusindicator.hpp (limited to 'src/components') diff --git a/README.md b/README.md index 0038f1f..89e7d3d 100644 --- a/README.md +++ b/README.md @@ -199,11 +199,6 @@ spam filter's wrath: | `.embed-field-value` | The value of an embed field | | `.embed-footer` | The footer of an embed | | `.member-list` | Container of the member list | -| `.status-indicator` | The status indicator | -| `.online` | Applied to status indicators when the associated user is online | -| `.idle` | Applied to status indicators when the associated user is away | -| `.dnd` | Applied to status indicators when the associated user is on do not disturb | -| `.offline` | Applied to status indicators when the associated user is offline | | `.typing-indicator` | The typing indicator (also used for replies) | Used in reorderable list implementation: diff --git a/src/components/cellrenderermemberlist.cpp b/src/components/cellrenderermemberlist.cpp index 66b223e..ee1ea3e 100644 --- a/src/components/cellrenderermemberlist.cpp +++ b/src/components/cellrenderermemberlist.cpp @@ -6,7 +6,8 @@ CellRendererMemberList::CellRendererMemberList() , m_property_id(*this, "id") , m_property_name(*this, "name") , m_property_pixbuf(*this, "pixbuf") - , m_property_color(*this, "color") { + , m_property_color(*this, "color") + , m_property_status(*this, "status") { property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; property_xpad() = 2; property_ypad() = 2; @@ -35,6 +36,10 @@ Glib::PropertyProxy CellRendererMemberList::property_color() { return m_property_color.get_proxy(); } +Glib::PropertyProxy CellRendererMemberList::property_status() { + return m_property_status.get_proxy(); +} + void CellRendererMemberList::get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const { switch (m_property_type.get_value()) { case MemberListRenderType::Role: @@ -117,8 +122,9 @@ void CellRendererMemberList::get_preferred_height_for_width_vfunc_member(Gtk::Wi } void CellRendererMemberList::render_vfunc_member(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) { + // Text Gdk::Rectangle text_cell_area = cell_area; - text_cell_area.set_x(22); + text_cell_area.set_x(31); const auto color = m_property_color.get_value(); if (color.get_alpha_u() > 0) { m_renderer_text.property_foreground_rgba().set_value(color); @@ -126,6 +132,30 @@ void CellRendererMemberList::render_vfunc_member(const Cairo::RefPtrbegin_new_path(); + switch (m_property_status.get_value()) { + case PresenceStatus::Online: + cr->set_source_rgb(33.0 / 255.0, 157.0 / 255.0, 86.0 / 255.0); + break; + case PresenceStatus::Idle: + cr->set_source_rgb(230.0 / 255.0, 170.0 / 255.0, 48.0 / 255.0); + break; + case PresenceStatus::DND: + cr->set_source_rgb(233.0 / 255.0, 61.0 / 255.0, 65.0 / 255.0); + break; + case PresenceStatus::Offline: + cr->set_source_rgb(122.0 / 255.0, 126.0 / 255.0, 135.0 / 255.0); + break; + } + + cr->arc(background_area.get_x() + 6.0 + 16.0 + 6.0, background_area.get_y() + background_area.get_height() / 2.0, 2.0, 0.0, 2 * (4 * std::atan(1))); + cr->close_path(); + cr->fill_preserve(); + cr->stroke(); + + // Icon const double icon_x = background_area.get_x() + 6.0; const double icon_y = background_area.get_y() + background_area.get_height() / 2.0 - 8.0; Gdk::Cairo::set_source_pixbuf(cr, m_property_pixbuf.get_value(), icon_x, icon_y); diff --git a/src/components/cellrenderermemberlist.hpp b/src/components/cellrenderermemberlist.hpp index 7a49ccf..79d32e3 100644 --- a/src/components/cellrenderermemberlist.hpp +++ b/src/components/cellrenderermemberlist.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include "discord/activity.hpp" enum class MemberListRenderType : uint8_t { Role, @@ -16,6 +17,7 @@ public: Glib::PropertyProxy property_name(); Glib::PropertyProxy> property_pixbuf(); Glib::PropertyProxy property_color(); + Glib::PropertyProxy property_status(); protected: void get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const override; @@ -56,6 +58,7 @@ private: Glib::Property m_property_name; Glib::Property> m_property_pixbuf; Glib::Property m_property_color; + Glib::Property m_property_status; using type_signal_render = sigc::signal; type_signal_render m_signal_render; diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 9fd4abd..6ed3ca4 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -1,6 +1,5 @@ #include "channels.hpp" #include "imgmanager.hpp" -#include "statusindicator.hpp" #include #include #include diff --git a/src/components/memberlist.cpp b/src/components/memberlist.cpp index b082daa..7046b52 100644 --- a/src/components/memberlist.cpp +++ b/src/components/memberlist.cpp @@ -28,6 +28,7 @@ MemberList::MemberList() column->add_attribute(renderer->property_name(), m_columns.m_name); column->add_attribute(renderer->property_pixbuf(), m_columns.m_pixbuf); column->add_attribute(renderer->property_color(), m_columns.m_color); + column->add_attribute(renderer->property_status(), m_columns.m_status); m_view.append_column(*column); m_model->set_sort_column(m_columns.m_sort, Gtk::SORT_ASCENDING); @@ -44,6 +45,8 @@ MemberList::MemberList() m_menu_role_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])); }); + + Abaddon::Get().GetDiscordClient().signal_presence_update().connect(sigc::mem_fun(*this, &MemberList::OnPresenceUpdate)); } Gtk::Widget *MemberList::GetRoot() { @@ -73,6 +76,7 @@ void MemberList::UpdateMemberList() { row[m_columns.m_color] = color_transparent; row[m_columns.m_av_requested] = false; row[m_columns.m_pixbuf] = Abaddon::Get().GetImageManager().GetPlaceholder(16); + row[m_columns.m_status] = Abaddon::Get().GetDiscordClient().GetUserStatus(user.ID); m_pending_avatars[user.ID] = row_iter; } } @@ -126,6 +130,7 @@ void MemberList::UpdateMemberList() { row[m_columns.m_id] = user.ID; row[m_columns.m_name] = user.GetDisplayNameEscaped(); row[m_columns.m_pixbuf] = Abaddon::Get().GetImageManager().GetPlaceholder(16); + row[m_columns.m_status] = Abaddon::Get().GetDiscordClient().GetUserStatus(user.ID); row[m_columns.m_av_requested] = false; if (const auto iter = user_to_color.find(user.ID); iter != user_to_color.end()) { row[m_columns.m_color] = IntToRGBA(iter->second); @@ -241,12 +246,24 @@ int MemberList::SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::TreeModel return 0; } +void MemberList::OnPresenceUpdate(const UserData &user, PresenceStatus status) { + for (auto &role : m_model->children()) { + for (auto &member : role.children()) { + if ((*member)[m_columns.m_id] == user.ID) { + (*member)[m_columns.m_status] = status; + return; + } + } + } +} + MemberList::ModelColumns::ModelColumns() { add(m_type); add(m_id); add(m_name); add(m_pixbuf); - add(m_av_requested); add(m_color); + add(m_status); add(m_sort); + add(m_av_requested); } diff --git a/src/components/memberlist.hpp b/src/components/memberlist.hpp index cb6c191..1c4aaf4 100644 --- a/src/components/memberlist.hpp +++ b/src/components/memberlist.hpp @@ -26,6 +26,8 @@ private: int SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::TreeModel::iterator &b); + void OnPresenceUpdate(const UserData &user, PresenceStatus status); + class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns(); @@ -35,6 +37,7 @@ private: Gtk::TreeModelColumn m_name; Gtk::TreeModelColumn> m_pixbuf; Gtk::TreeModelColumn m_color; + Gtk::TreeModelColumn m_status; Gtk::TreeModelColumn m_sort; Gtk::TreeModelColumn m_av_requested; diff --git a/src/components/statusindicator.cpp b/src/components/statusindicator.cpp deleted file mode 100644 index 47e8b44..0000000 --- a/src/components/statusindicator.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "statusindicator.hpp" - -static const constexpr int Diameter = 8; - -StatusIndicator::StatusIndicator(Snowflake user_id) - : Glib::ObjectBase("statusindicator") - , Gtk::Widget() - , m_id(user_id) - , m_status(static_cast(-1)) { - set_has_window(true); - set_name("status-indicator"); - - get_style_context()->add_class("status-indicator"); - - Abaddon::Get().GetDiscordClient().signal_guild_member_list_update().connect(sigc::hide(sigc::mem_fun(*this, &StatusIndicator::CheckStatus))); - auto cb = [this](const UserData &user, PresenceStatus status) { - if (user.ID == m_id) CheckStatus(); - }; - Abaddon::Get().GetDiscordClient().signal_presence_update().connect(sigc::track_obj(cb, *this)); - - CheckStatus(); -} - -void StatusIndicator::CheckStatus() { - const auto status = Abaddon::Get().GetDiscordClient().GetUserStatus(m_id); - const auto last_status = m_status; - get_style_context()->remove_class("online"); - get_style_context()->remove_class("dnd"); - get_style_context()->remove_class("idle"); - get_style_context()->remove_class("offline"); - get_style_context()->add_class(GetPresenceString(status)); - m_status = status; - - if (last_status != m_status) - queue_draw(); -} - -Gtk::SizeRequestMode StatusIndicator::get_request_mode_vfunc() const { - return Gtk::Widget::get_request_mode_vfunc(); -} - -void StatusIndicator::get_preferred_width_vfunc(int &minimum_width, int &natural_width) const { - minimum_width = 0; - natural_width = Diameter; -} - -void StatusIndicator::get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const { - minimum_height = 0; - natural_height = Diameter; -} - -void StatusIndicator::get_preferred_height_vfunc(int &minimum_height, int &natural_height) const { - minimum_height = 0; - natural_height = Diameter; -} - -void StatusIndicator::get_preferred_width_for_height_vfunc(int height, int &minimum_width, int &natural_width) const { - minimum_width = 0; - natural_width = Diameter; -} - -void StatusIndicator::on_size_allocate(Gtk::Allocation &allocation) { - set_allocation(allocation); - - if (m_window) - m_window->move_resize(allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height()); -} - -void StatusIndicator::on_map() { - Gtk::Widget::on_map(); -} - -void StatusIndicator::on_unmap() { - Gtk::Widget::on_unmap(); -} - -void StatusIndicator::on_realize() { - set_realized(true); - - if (!m_window) { - GdkWindowAttr attributes; - std::memset(&attributes, 0, sizeof(attributes)); - - auto allocation = get_allocation(); - - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); - - attributes.event_mask = get_events() | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - - m_window = Gdk::Window::create(get_parent_window(), &attributes, GDK_WA_X | GDK_WA_Y); - set_window(m_window); - - m_window->set_user_data(gobj()); - } -} - -void StatusIndicator::on_unrealize() { - m_window.reset(); - - Gtk::Widget::on_unrealize(); -} - -bool StatusIndicator::on_draw(const Cairo::RefPtr &cr) { - const auto allocation = get_allocation(); - const auto width = allocation.get_width(); - const auto height = allocation.get_height(); - - const auto color = get_style_context()->get_color(Gtk::STATE_FLAG_NORMAL); - - cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue()); - cr->arc(width / 2.0, height / 2.0, width / 3.0, 0.0, 2 * (4 * std::atan(1))); - cr->close_path(); - cr->fill_preserve(); - cr->stroke(); - - return true; -} diff --git a/src/components/statusindicator.hpp b/src/components/statusindicator.hpp deleted file mode 100644 index edd64ea..0000000 --- a/src/components/statusindicator.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "discord/snowflake.hpp" -#include "discord/activity.hpp" - -class StatusIndicator : public Gtk::Widget { -public: - StatusIndicator(Snowflake user_id); - ~StatusIndicator() override = default; - -protected: - Gtk::SizeRequestMode get_request_mode_vfunc() const override; - void get_preferred_width_vfunc(int &minimum_width, int &natural_width) const override; - void get_preferred_width_for_height_vfunc(int height, int &minimum_width, int &natural_width) const override; - void get_preferred_height_vfunc(int &minimum_height, int &natural_height) const override; - void get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const override; - void on_size_allocate(Gtk::Allocation &allocation) override; - void on_map() override; - void on_unmap() override; - void on_realize() override; - void on_unrealize() override; - bool on_draw(const Cairo::RefPtr &cr) override; - - Glib::RefPtr m_window; - - void CheckStatus(); - - Snowflake m_id; - PresenceStatus m_status; -}; -- cgit v1.2.3 From 3ab6055898c2d6b2809b62ebf6a174f35352c204 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 17 Nov 2023 01:49:30 -0500 Subject: disable foreground set on channel renderer, get rid of stray property_sensitive=false --- src/components/channelscellrenderer.cpp | 41 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index ac98512..c344bb1 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -243,12 +243,12 @@ void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr(text_h)); static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor); - m_renderer_text.property_foreground_rgba() = color; + // m_renderer_text.property_foreground_rgba() = color; m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); const bool hover_only = Abaddon::Get().GetSettings().AnimatedGuildHoverOnly; @@ -465,15 +465,15 @@ void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr 0) { AddUnreadIndicator(cr, background_area); } - m_renderer_text.property_foreground_rgba() = color; + // m_renderer_text.property_foreground_rgba() = color; } m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); - m_renderer_text.property_foreground_set() = false; + // m_renderer_text.property_foreground_set() = false; } // text channel @@ -511,22 +511,21 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr & muted.set_red(muted.get_red() * 0.5); muted.set_green(muted.get_green() * 0.5); muted.set_blue(muted.get_blue() * 0.5); - m_renderer_text.property_foreground_rgba() = muted; + // m_renderer_text.property_foreground_rgba() = muted; } else { - m_renderer_text.property_foreground_rgba() = color; + // m_renderer_text.property_foreground_rgba() = color; } m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); - m_renderer_text.property_foreground_set() = false; + // m_renderer_text.property_foreground_set() = false; Gdk::Cairo::set_source_pixbuf(cr, m_property_pixbuf.get_value(), icon_x, icon_y); cr->rectangle(icon_x, icon_y, icon_w, icon_h); -- cgit v1.2.3 From 2b8fc6a495703ba5a3b8d2db2451fd047b34b819 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:38:54 -0500 Subject: dim channel color on mute by alpha --- src/components/channelscellrenderer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index c344bb1..52bc57e 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -523,7 +523,14 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtrget_color(Gtk::STATE_FLAG_NORMAL); + color.set_alpha(0.6); + m_renderer_text.property_foreground_rgba() = color; + } m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); + m_renderer_text.property_foreground_set() = false; // unset foreground to default so properties dont bleed // m_renderer_text.property_foreground_set() = false; -- cgit v1.2.3 From c61feb9f010caa9536e318e2aedb3a4ed739a91d Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 26 Nov 2023 19:46:02 -0500 Subject: code deduplication unread indicator --- src/components/channelscellrenderer.cpp | 42 ++++++++++++--------------------- 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 52bc57e..35c6137 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -7,6 +7,17 @@ constexpr static double M_PI = 3.14159265358979; constexpr static double M_PI_H = M_PI / 2.0; constexpr static double M_PI_3_2 = M_PI * 3.0 / 2.0; +void AddUnreadIndicator(const Cairo::RefPtr &cr, const Gdk::Rectangle &background_area) { + static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor); + cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue()); + const auto x = background_area.get_x(); + const auto y = background_area.get_y(); + const auto w = background_area.get_width(); + const auto h = background_area.get_height(); + cr->rectangle(x, y, 3, h); + cr->fill(); +} + CellRendererChannels::CellRendererChannels() : Glib::ObjectBase(typeid(CellRendererChannels)) , Gtk::CellRenderer() @@ -373,14 +384,9 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtrset_source_rgb(color.get_red(), color.get_green(), color.get_blue()); - const auto x = background_area.get_x(); - const auto y = background_area.get_y(); - const auto w = background_area.get_width(); - const auto h = background_area.get_height(); - cr->rectangle(x, y + h / 2.0 - 24.0 / 2.0, 3.0, 24.0); - cr->fill(); + auto area = background_area; + area.set_y(area.get_y() + area.get_height() / 2.0 - 24.0 / 2.0); + AddUnreadIndicator(cr, area); } if (total_mentions < 1) return; @@ -410,17 +416,6 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_category(Gtk::Wi m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height); } -void AddUnreadIndicator(const Cairo::RefPtr &cr, const Gdk::Rectangle &background_area) { - static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor); - cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue()); - const auto x = background_area.get_x(); - const auto y = background_area.get_y(); - const auto w = background_area.get_width(); - const auto h = background_area.get_height(); - cr->rectangle(x, y, 3, h); - cr->fill(); -} - void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) { // todo: figure out how Gtk::Arrow is rendered because i like it better :^) constexpr static int len = 5; @@ -927,14 +922,7 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr & if (unread_state < 0) return; if (!is_muted) { - static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor); - cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue()); - const auto x = background_area.get_x(); - const auto y = background_area.get_y(); - const auto w = background_area.get_width(); - const auto h = background_area.get_height(); - cr->rectangle(x, y, 3, h); - cr->fill(); + AddUnreadIndicator(cr, background_area); } } -- cgit v1.2.3 From 260fc2a745afd4dca4e628e6c407b7757dbcf5f0 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:50:16 -0500 Subject: show @ in reply markup if reply is a mention --- src/components/chatmessage.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/components') diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp index d884077..6eccba2 100644 --- a/src/components/chatmessage.cpp +++ b/src/components/chatmessage.cpp @@ -661,7 +661,12 @@ Gtk::Widget *ChatMessageItemContainer::CreateReplyComponent(const Message &data) if (role.has_value()) { const auto author = discord.GetUser(author_id); if (author.has_value()) { - return "Color) + "\">" + author->GetDisplayNameEscaped(guild_id) + ""; + const auto is_mention = !data.Interaction.has_value() && data.DoesMention(author_id); + if (is_mention) { + return "Color) + "\">@" + author->GetDisplayNameEscaped(guild_id) + ""; + } else { + return "Color) + "\">" + author->GetDisplayNameEscaped(guild_id) + ""; + } } } } @@ -717,16 +722,12 @@ Gtk::Widget *ChatMessageItemContainer::CreateReplyComponent(const Message &data) HandleChannelMentions(buf); text = Glib::Markup::escape_text(buf->get_text()); } - // getting markup out of a textbuffer seems like something that to me should be really simple - // but actually is horribly annoying. replies won't have mention colors because you can't do this - // also no emojis because idk how to make a textview act like a label - // which of course would not be an issue if i could figure out how to get fonts to work on this god-forsaken framework - // oh well - // but ill manually get colors for the user who is being replied to - if (referenced.GuildID.has_value()) + + if (referenced.GuildID.has_value()) { lbl->set_markup(get_author_markup(referenced.Author.ID, *referenced.GuildID) + ": " + text); - else + } else { lbl->set_markup(get_author_markup(referenced.Author.ID) + ": " + text); + } } } else { lbl->set_markup("reply unavailable"); -- cgit v1.2.3 From e21b678220ce6ca7712a46ee9fe674320e148bab Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:19:02 -0500 Subject: get link color from theme --- src/components/chatmessage.cpp | 5 +++-- src/settings.cpp | 2 -- src/settings.hpp | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/components') diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp index d884077..4b195aa 100644 --- a/src/components/chatmessage.cpp +++ b/src/components/chatmessage.cpp @@ -361,7 +361,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb } return false; }); - static auto color = Abaddon::Get().GetSettings().LinkColor; + const auto color = title_label->get_style_context()->get_color(Gtk::STATE_FLAG_LINK); title_label->override_color(Gdk::RGBA(color)); title_label->set_markup("" + Glib::Markup::escape_text(*embed.Title) + ""); } @@ -852,7 +852,8 @@ void ChatMessageItemContainer::HandleLinks(Gtk::TextView &tv) { std::string link = match.fetch(0); auto tag = buf->create_tag(); m_link_tagmap[tag] = link; - tag->property_foreground_rgba() = Gdk::RGBA(Abaddon::Get().GetSettings().LinkColor); + const auto color = tv.get_style_context()->get_color(Gtk::STATE_FLAG_LINK); + tag->property_foreground_rgba() = color; tag->set_property("underline", 1); // stupid workaround for vcpkg bug (i think) const auto chars_start = g_utf8_pointer_to_offset(text.c_str(), text.c_str() + mstart); diff --git a/src/settings.cpp b/src/settings.cpp index c824a34..368d5bb 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -68,7 +68,6 @@ void SettingsManager::ReadSettings() { SMINT("http", "concurrent", CacheHTTPConcurrency); SMSTR("http", "user_agent", UserAgent); SMSTR("style", "expandercolor", ChannelsExpanderColor); - SMSTR("style", "linkcolor", LinkColor); SMSTR("style", "nsfwchannelcolor", NSFWChannelColor); SMSTR("style", "channelcolor", ChannelColor); SMSTR("style", "mentionbadgecolor", MentionBadgeColor); @@ -159,7 +158,6 @@ void SettingsManager::Close() { SMINT("http", "concurrent", CacheHTTPConcurrency); SMSTR("http", "user_agent", UserAgent); SMSTR("style", "expandercolor", ChannelsExpanderColor); - SMSTR("style", "linkcolor", LinkColor); SMSTR("style", "nsfwchannelcolor", NSFWChannelColor); SMSTR("style", "channelcolor", ChannelColor); SMSTR("style", "mentionbadgecolor", MentionBadgeColor); diff --git a/src/settings.hpp b/src/settings.hpp index 037233b..67ba515 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -39,7 +39,6 @@ public: // [style] // TODO: convert to StyleProperty... or maybe not? i still cant figure out what the "correct" method is for this - std::string LinkColor { "rgba(40, 200, 180, 255)" }; std::string ChannelsExpanderColor { "rgba(255, 83, 112, 255)" }; std::string NSFWChannelColor { "#ed6666" }; std::string ChannelColor { "#fbfbfb" }; -- cgit v1.2.3 From 8324172a90752403edcec2203a2abb386046cc8f Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Thu, 7 Dec 2023 21:53:05 -0500 Subject: hide progress bar when not actually mid-upload --- src/components/chatwindow.cpp | 10 ++++++++-- src/components/progressbar.cpp | 19 ++++++++++++++++++- src/components/progressbar.hpp | 11 +++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) (limited to 'src/components') diff --git a/src/components/chatwindow.cpp b/src/components/chatwindow.cpp index aeed4ed..9a2493d 100644 --- a/src/components/chatwindow.cpp +++ b/src/components/chatwindow.cpp @@ -5,7 +5,7 @@ #include "chatlist.hpp" #include "constants.hpp" #ifdef WITH_LIBHANDY - #include "channeltabswitcherhandy.hpp" +#include "channeltabswitcherhandy.hpp" #endif ChatWindow::ChatWindow() { @@ -109,7 +109,13 @@ ChatWindow::ChatWindow() { m_main->add(*m_meta); m_main->add(m_progress); - m_progress.show(); + m_progress.signal_start().connect([this]() { + m_progress.show(); + }); + + m_progress.signal_stop().connect([this]() { + m_progress.hide(); + }); m_main->show(); } diff --git a/src/components/progressbar.cpp b/src/components/progressbar.cpp index 75f86bb..65abfae 100644 --- a/src/components/progressbar.cpp +++ b/src/components/progressbar.cpp @@ -5,12 +5,19 @@ MessageUploadProgressBar::MessageUploadProgressBar() { auto &discord = Abaddon::Get().GetDiscordClient(); discord.signal_message_progress().connect([this](const std::string &nonce, float percent) { if (nonce == m_last_nonce) { + if (!m_active) { + m_active = true; + m_signal_start.emit(); + } set_fraction(percent); } }); discord.signal_message_send_fail().connect([this](const std::string &nonce, float) { - if (nonce == m_last_nonce) + if (nonce == m_last_nonce) { set_fraction(0.0); + m_active = false; + m_signal_stop.emit(); + } }); discord.signal_message_create().connect([this](const Message &msg) { if (msg.IsPending) { @@ -18,6 +25,16 @@ MessageUploadProgressBar::MessageUploadProgressBar() { } else if (msg.Nonce.has_value() && (*msg.Nonce == m_last_nonce)) { m_last_nonce = ""; set_fraction(0.0); + m_active = false; + m_signal_stop.emit(); } }); } + +MessageUploadProgressBar::type_signal_start MessageUploadProgressBar::signal_start() { + return m_signal_start; +} + +MessageUploadProgressBar::type_signal_stop MessageUploadProgressBar::signal_stop() { + return m_signal_stop; +} diff --git a/src/components/progressbar.hpp b/src/components/progressbar.hpp index 483ee47..8efb87a 100644 --- a/src/components/progressbar.hpp +++ b/src/components/progressbar.hpp @@ -6,5 +6,16 @@ public: MessageUploadProgressBar(); private: + bool m_active = false; std::string m_last_nonce; + + using type_signal_start = sigc::signal; + using type_signal_stop = sigc::signal; + + type_signal_start m_signal_start; + type_signal_stop m_signal_stop; + +public: + type_signal_start signal_start(); + type_signal_stop signal_stop(); }; -- cgit v1.2.3 From 23bf237e4e7dd008df8ff32da31878d1b990f5bf Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 13 Dec 2023 21:59:45 -0500 Subject: view image alt text on hover --- src/components/chatmessage.cpp | 3 +++ src/discord/message.cpp | 2 ++ src/discord/message.hpp | 5 +++-- src/discord/store.cpp | 5 ++++- 4 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/components') diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp index 6eccba2..2c2f9dd 100644 --- a/src/components/chatmessage.cpp +++ b/src/components/chatmessage.cpp @@ -46,6 +46,9 @@ ChatMessageItemContainer *ChatMessageItemContainer::FromMessage(const Message &d for (const auto &a : data.Attachments) { if (IsURLViewableImage(a.ProxyURL) && a.Width.has_value() && a.Height.has_value()) { auto *widget = container->CreateImageComponent(a.ProxyURL, a.URL, *a.Width, *a.Height); + if (a.Description.has_value()) { + widget->set_tooltip_text(*a.Description); + } container->m_main.add(*widget); } else { auto *widget = container->CreateAttachmentComponent(a); diff --git a/src/discord/message.cpp b/src/discord/message.cpp index bc4c6c8..8a0e271 100644 --- a/src/discord/message.cpp +++ b/src/discord/message.cpp @@ -128,6 +128,7 @@ void to_json(nlohmann::json &j, const AttachmentData &m) { j["proxy_url"] = m.ProxyURL; JS_IF("height", m.Height); JS_IF("width", m.Width); + JS_IF("description", m.Description); } void from_json(const nlohmann::json &j, AttachmentData &m) { @@ -138,6 +139,7 @@ void from_json(const nlohmann::json &j, AttachmentData &m) { JS_D("proxy_url", m.ProxyURL); JS_ON("height", m.Height); JS_ON("width", m.Width); + JS_ON("description", m.Description); } void from_json(const nlohmann::json &j, MessageReferenceData &m) { diff --git a/src/discord/message.hpp b/src/discord/message.hpp index b71c158..1e836d0 100644 --- a/src/discord/message.hpp +++ b/src/discord/message.hpp @@ -168,8 +168,9 @@ struct AttachmentData { int Bytes; std::string URL; std::string ProxyURL; - std::optional Height; // null - std::optional Width; // null + std::optional Height; // null + std::optional Width; // null + std::optional Description; // alt text friend void to_json(nlohmann::json &j, const AttachmentData &m); friend void from_json(const nlohmann::json &j, AttachmentData &m); diff --git a/src/discord/store.cpp b/src/discord/store.cpp index 0e1ba48..bf630aa 100644 --- a/src/discord/store.cpp +++ b/src/discord/store.cpp @@ -368,6 +368,7 @@ void Store::SetMessage(Snowflake id, const Message &message) { s->Bind(6, a.ProxyURL); s->Bind(7, a.Height); s->Bind(8, a.Width); + s->Bind(9, a.Description); if (!s->Insert()) fprintf(stderr, "message attachment insert failed for %" PRIu64 "/%" PRIu64 ": %s\n", static_cast(id), static_cast(a.ID), m_db.ErrStr()); s->Reset(); @@ -1021,6 +1022,7 @@ Message Store::GetMessageBound(std::unique_ptr &s) const { s->Get(5, q.ProxyURL); s->Get(6, q.Height); s->Get(7, q.Width); + s->Get(8, q.Description); } s->Reset(); } @@ -1509,6 +1511,7 @@ bool Store::CreateTables() { proxy TEXT NOT NULL, height INTEGER, width INTEGER, + description TEXT, PRIMARY KEY(message, id) ) )"; @@ -2212,7 +2215,7 @@ bool Store::CreateStatements() { m_stmt_set_attachment = std::make_unique(m_db, R"( REPLACE INTO attachments VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? + ?, ?, ?, ?, ?, ?, ?, ?, ? ) )"); if (!m_stmt_set_attachment->OK()) { -- cgit v1.2.3 From 4bce7b7523caa26023b1a2f5e02e6646ed29f5e0 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 15 Dec 2023 01:16:11 -0500 Subject: add ability to set image alt text (closes #253) --- src/components/chatinput.cpp | 21 ++++++++++++++++++++- src/components/chatinput.hpp | 14 ++++++++++---- src/discord/chatsubmitparams.hpp | 2 ++ src/discord/discord.cpp | 10 ++++++++-- src/discord/objects.cpp | 6 ++++++ src/discord/objects.hpp | 8 ++++++++ 6 files changed, 54 insertions(+), 7 deletions(-) (limited to 'src/components') diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp index c802413..10896fb 100644 --- a/src/components/chatinput.cpp +++ b/src/components/chatinput.cpp @@ -295,7 +295,7 @@ std::vector ChatInputAttachmentContainer::GetAttac for (auto *x : m_attachments) { if (!x->GetFile()->query_exists()) puts("bad!"); - ret.push_back({ x->GetFile(), x->GetType(), x->GetFilename() }); + ret.push_back({ x->GetFile(), x->GetType(), x->GetFilename(), x->GetDescription() }); } return ret; } @@ -343,6 +343,7 @@ ChatInputAttachmentItem::ChatInputAttachmentItem(const Glib::RefPtr & , m_img(Gtk::make_managed()) , m_type(is_extant ? ChatSubmitParams::ExtantFile : ChatSubmitParams::PastedImage) , m_filename("unknown.png") + , m_is_image(true) , m_label("unknown.png") , m_box(Gtk::ORIENTATION_VERTICAL) { get_style_context()->add_class("attachment-item"); @@ -389,10 +390,18 @@ std::string ChatInputAttachmentItem::GetFilename() const { return m_filename; } +std::optional ChatInputAttachmentItem::GetDescription() const { + return m_description.empty() ? std::nullopt : std::optional(m_description); +} + bool ChatInputAttachmentItem::IsTemp() const noexcept { return m_type == ChatSubmitParams::PastedImage; } +bool ChatInputAttachmentItem::IsImage() const noexcept { + return m_is_image; +} + void ChatInputAttachmentItem::RemoveIfTemp() { if (IsTemp()) m_file->remove(); @@ -420,12 +429,22 @@ void ChatInputAttachmentItem::SetupMenu() { } }); + m_menu_set_alt_text.set_label("Change Alt-Text"); + m_menu_set_alt_text.signal_activate().connect([this]() { + const auto description = Abaddon::Get().ShowTextPrompt("Enter description (alt-text) for attachment", "Enter alt-text", m_description); + if (description.has_value()) { + m_description = *description; + } + }); + m_menu.add(m_menu_set_filename); + m_menu.add(m_menu_set_alt_text); m_menu.add(m_menu_remove); m_menu.show_all(); signal_button_press_event().connect([this](GdkEventButton *ev) -> bool { if (ev->button == GDK_BUTTON_SECONDARY) { + m_menu_set_alt_text.set_visible(IsImage()); m_menu.popup_at_pointer(reinterpret_cast(ev)); return true; } diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp index a3c9742..be8c141 100644 --- a/src/components/chatinput.hpp +++ b/src/components/chatinput.hpp @@ -7,10 +7,13 @@ public: ChatInputAttachmentItem(const Glib::RefPtr &file); ChatInputAttachmentItem(const Glib::RefPtr &file, const Glib::RefPtr &pb, bool is_extant = false); - [[nodiscard]] Glib::RefPtr GetFile() const; - [[nodiscard]] ChatSubmitParams::AttachmentType GetType() const; - [[nodiscard]] std::string GetFilename() const; - [[nodiscard]] bool IsTemp() const noexcept; + Glib::RefPtr GetFile() const; + ChatSubmitParams::AttachmentType GetType() const; + std::string GetFilename() const; + std::optional GetDescription() const; + bool IsTemp() const noexcept; + bool IsImage() const noexcept; + void RemoveIfTemp(); private: @@ -21,6 +24,7 @@ private: Gtk::Menu m_menu; Gtk::MenuItem m_menu_remove; Gtk::MenuItem m_menu_set_filename; + Gtk::MenuItem m_menu_set_alt_text; Gtk::Box m_box; Gtk::Label m_label; @@ -29,6 +33,8 @@ private: Glib::RefPtr m_file; ChatSubmitParams::AttachmentType m_type; std::string m_filename; + std::string m_description; + bool m_is_image = false; private: using type_signal_item_removed = sigc::signal; diff --git a/src/discord/chatsubmitparams.hpp b/src/discord/chatsubmitparams.hpp index e195189..45fbb2a 100644 --- a/src/discord/chatsubmitparams.hpp +++ b/src/discord/chatsubmitparams.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -15,6 +16,7 @@ struct ChatSubmitParams { Glib::RefPtr File; AttachmentType Type; std::string Filename; + std::optional Description; }; bool Silent = false; diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 0618e72..ac7e2f2 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -518,6 +518,7 @@ void DiscordClient::SendChatMessageAttachments(const ChatSubmitParams ¶ms, c CreateMessageObject obj; obj.Content = params.Message; obj.Nonce = nonce; + obj.Attachments.emplace(); if (params.Silent) { obj.Flags |= MessageFlags::SUPPRESS_NOTIFICATIONS; } @@ -541,11 +542,16 @@ void DiscordClient::SendChatMessageAttachments(const ChatSubmitParams ¶ms, c m_generic_dispatch.emit(); }); req.make_form(); - req.add_field("payload_json", nlohmann::json(obj).dump().c_str(), CURL_ZERO_TERMINATED); + for (size_t i = 0; i < params.Attachments.size(); i++) { + auto &attachment = params.Attachments.at(i); const auto field_name = "files[" + std::to_string(i) + "]"; - req.add_file(field_name, params.Attachments.at(i).File, params.Attachments.at(i).Filename); + req.add_file(field_name, attachment.File, attachment.Filename); + obj.Attachments->push_back({ static_cast(i), attachment.Description }); } + + req.add_field("payload_json", nlohmann::json(obj).dump().c_str(), CURL_ZERO_TERMINATED); + m_http.Execute(std::move(req), [this, params, nonce, callback](const http::response_type &res) { for (const auto &attachment : params.Attachments) { if (attachment.Type == ChatSubmitParams::AttachmentType::PastedImage) { diff --git a/src/discord/objects.cpp b/src/discord/objects.cpp index 4ad17c3..804f10d 100644 --- a/src/discord/objects.cpp +++ b/src/discord/objects.cpp @@ -306,9 +306,15 @@ void to_json(nlohmann::json &j, const HeartbeatMessage &m) { j["d"] = m.Sequence; } +void to_json(nlohmann::json &j, const CreateMessageAttachmentObject &m) { + j["id"] = m.ID; + JS_IF("description", m.Description); +} + void to_json(nlohmann::json &j, const CreateMessageObject &m) { j["content"] = m.Content; j["flags"] = m.Flags; + JS_IF("attachments", m.Attachments); JS_IF("message_reference", m.MessageReference); JS_IF("nonce", m.Nonce); } diff --git a/src/discord/objects.hpp b/src/discord/objects.hpp index 603a9c7..dfe99f0 100644 --- a/src/discord/objects.hpp +++ b/src/discord/objects.hpp @@ -433,11 +433,19 @@ struct HeartbeatMessage : GatewayMessage { friend void to_json(nlohmann::json &j, const HeartbeatMessage &m); }; +struct CreateMessageAttachmentObject { + int ID; + std::optional Description; + + friend void to_json(nlohmann::json &j, const CreateMessageAttachmentObject &m); +}; + struct CreateMessageObject { std::string Content; MessageFlags Flags = MessageFlags::NONE; std::optional MessageReference; std::optional Nonce; + std::optional> Attachments; friend void to_json(nlohmann::json &j, const CreateMessageObject &m); }; -- cgit v1.2.3 From 5ea80d1a147c445468293277a517558e727dd4f9 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:46:36 -0500 Subject: use selected bg for expander color --- src/components/channelscellrenderer.cpp | 102 +++++++++----------------------- 1 file changed, 29 insertions(+), 73 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 35c6137..bbe19e7 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -18,6 +18,32 @@ void AddUnreadIndicator(const Cairo::RefPtr &cr, const Gdk::Rect cr->fill(); } +void RenderExpander(int x_offset, const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, bool is_expanded) { + constexpr static int len = 5; + int x1, y1, x2, y2, x3, y3; + if (is_expanded) { + x1 = background_area.get_x() + x_offset; + y1 = background_area.get_y() + background_area.get_height() / 2 - len; + x2 = background_area.get_x() + x_offset + len; + y2 = background_area.get_y() + background_area.get_height() / 2 + len; + x3 = background_area.get_x() + x_offset + len * 2; + y3 = background_area.get_y() + background_area.get_height() / 2 - len; + } else { + x1 = background_area.get_x() + x_offset; + y1 = background_area.get_y() + background_area.get_height() / 2 - len; + x2 = background_area.get_x() + x_offset + len * 2; + y2 = background_area.get_y() + background_area.get_height() / 2; + x3 = background_area.get_x() + x_offset; + y3 = background_area.get_y() + background_area.get_height() / 2 + len; + } + cr->move_to(x1, y1); + cr->line_to(x2, y2); + cr->line_to(x3, y3); + const auto expander_color = widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue()); + cr->stroke(); +} + CellRendererChannels::CellRendererChannels() : Glib::ObjectBase(typeid(CellRendererChannels)) , Gtk::CellRenderer() @@ -218,30 +244,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_folder(Gtk::Widg } void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) { - constexpr static int len = 5; - int x1, y1, x2, y2, x3, y3; - if (property_expanded()) { - x1 = background_area.get_x() + 7; - y1 = background_area.get_y() + background_area.get_height() / 2 - len; - x2 = background_area.get_x() + 7 + len; - y2 = background_area.get_y() + background_area.get_height() / 2 + len; - x3 = background_area.get_x() + 7 + len * 2; - y3 = background_area.get_y() + background_area.get_height() / 2 - len; - } else { - x1 = background_area.get_x() + 7; - y1 = background_area.get_y() + background_area.get_height() / 2 - len; - x2 = background_area.get_x() + 7 + len * 2; - y2 = background_area.get_y() + background_area.get_height() / 2; - x3 = background_area.get_x() + 7; - y3 = background_area.get_y() + background_area.get_height() / 2 + len; - } - cr->move_to(x1, y1); - cr->line_to(x2, y2); - cr->line_to(x3, y3); - const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor); - cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue()); - cr->stroke(); - + RenderExpander(7, cr, widget, background_area, property_expanded()); Gtk::Requisition text_minimum, text_natural; m_renderer_text.get_preferred_size(widget, text_minimum, text_natural); @@ -417,30 +420,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_category(Gtk::Wi } void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) { - // todo: figure out how Gtk::Arrow is rendered because i like it better :^) - constexpr static int len = 5; - int x1, y1, x2, y2, x3, y3; - if (property_expanded()) { - x1 = background_area.get_x() + 7; - y1 = background_area.get_y() + background_area.get_height() / 2 - len; - x2 = background_area.get_x() + 7 + len; - y2 = background_area.get_y() + background_area.get_height() / 2 + len; - x3 = background_area.get_x() + 7 + len * 2; - y3 = background_area.get_y() + background_area.get_height() / 2 - len; - } else { - x1 = background_area.get_x() + 7; - y1 = background_area.get_y() + background_area.get_height() / 2 - len; - x2 = background_area.get_x() + 7 + len * 2; - y2 = background_area.get_y() + background_area.get_height() / 2; - x3 = background_area.get_x() + 7; - y3 = background_area.get_y() + background_area.get_height() / 2 + len; - } - cr->move_to(x1, y1); - cr->line_to(x2, y2); - cr->line_to(x3, y3); - const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor); - cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue()); - cr->stroke(); + RenderExpander(7, cr, widget, background_area, property_expanded()); Gtk::Requisition text_minimum, text_natural; m_renderer_text.get_preferred_size(widget, text_minimum, text_natural); @@ -668,31 +648,7 @@ void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtrshow_in_cairo_context(cr); - // expander - constexpr static int len = 5; - constexpr static int offset = 24; - int x1, y1, x2, y2, x3, y3; - if (property_expanded()) { - x1 = background_area.get_x() + offset; - y1 = background_area.get_y() + background_area.get_height() / 2 - len; - x2 = background_area.get_x() + offset + len; - y2 = background_area.get_y() + background_area.get_height() / 2 + len; - x3 = background_area.get_x() + offset + len * 2; - y3 = background_area.get_y() + background_area.get_height() / 2 - len; - } else { - x1 = background_area.get_x() + offset; - y1 = background_area.get_y() + background_area.get_height() / 2 - len; - x2 = background_area.get_x() + offset + len * 2; - y2 = background_area.get_y() + background_area.get_height() / 2; - x3 = background_area.get_x() + offset; - y3 = background_area.get_y() + background_area.get_height() / 2 + len; - } - cr->move_to(x1, y1); - cr->line_to(x2, y2); - cr->line_to(x3, y3); - const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor); - cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue()); - cr->stroke(); + RenderExpander(24, cr, widget, background_area, property_expanded()); } // voice participant -- cgit v1.2.3 From 19282c8642f5bc1c064a8f8645b2d5380d2014b4 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 15 Dec 2023 21:44:58 -0500 Subject: allow override expander color --- src/components/channelscellrenderer.cpp | 5 ++++- src/settings.hpp | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index bbe19e7..3f10330 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -39,7 +39,10 @@ void RenderExpander(int x_offset, const Cairo::RefPtr &cr, Gtk:: cr->move_to(x1, y1); cr->line_to(x2, y2); cr->line_to(x3, y3); - const auto expander_color = widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor); + if (expander_color.get_alpha_u() == 0) { + expander_color = widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + } cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue()); cr->stroke(); } diff --git a/src/settings.hpp b/src/settings.hpp index 67ba515..a51d93b 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -38,8 +38,7 @@ public: std::string UserAgent { "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36" }; // [style] - // TODO: convert to StyleProperty... or maybe not? i still cant figure out what the "correct" method is for this - std::string ChannelsExpanderColor { "rgba(255, 83, 112, 255)" }; + std::string ChannelsExpanderColor { "rgba(255, 83, 112, 0)" }; std::string NSFWChannelColor { "#ed6666" }; std::string ChannelColor { "#fbfbfb" }; std::string MentionBadgeColor { "#b82525" }; -- cgit v1.2.3 From 0187e6958464f9a9d5c8bc1143d6dfac60e862b1 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 15 Dec 2023 22:06:16 -0500 Subject: remove channel color style setting --- src/components/channelscellrenderer.cpp | 57 ++------------------------------- src/settings.cpp | 2 -- src/settings.hpp | 1 - 3 files changed, 3 insertions(+), 57 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 3f10330..7fd97da 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -258,14 +258,11 @@ void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr(text_w), static_cast(text_h)); - static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor); - // m_renderer_text.property_foreground_rgba() = color; m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); const bool hover_only = Abaddon::Get().GetSettings().AnimatedGuildHoverOnly; @@ -435,23 +430,14 @@ void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr 0) { AddUnreadIndicator(cr, background_area); } - // m_renderer_text.property_foreground_rgba() = color; } m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); - // m_renderer_text.property_foreground_set() = false; } // text channel @@ -487,20 +473,7 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtrget_color(Gtk::STATE_FLAG_NORMAL); @@ -509,8 +482,6 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr & const auto id = m_property_id.get_value(); const bool is_muted = discord.IsChannelMuted(id); - static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor); - if (Abaddon::Get().GetDiscordClient().IsChannelMuted(m_property_id.get_value())) { - auto muted = color; - muted.set_red(muted.get_red() * 0.5); - muted.set_green(muted.get_green() * 0.5); - muted.set_blue(muted.get_blue() * 0.5); - // m_renderer_text.property_foreground_rgba() = muted; - } else { - // m_renderer_text.property_foreground_rgba() = color; - } m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); - // m_renderer_text.property_foreground_set() = false; Gdk::Cairo::set_source_pixbuf(cr, m_property_pixbuf.get_value(), icon_x, icon_y); cr->rectangle(icon_x, icon_y, icon_w, icon_h); diff --git a/src/settings.cpp b/src/settings.cpp index 368d5bb..d1dff3f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -69,7 +69,6 @@ void SettingsManager::ReadSettings() { SMSTR("http", "user_agent", UserAgent); SMSTR("style", "expandercolor", ChannelsExpanderColor); SMSTR("style", "nsfwchannelcolor", NSFWChannelColor); - SMSTR("style", "channelcolor", ChannelColor); SMSTR("style", "mentionbadgecolor", MentionBadgeColor); SMSTR("style", "mentionbadgetextcolor", MentionBadgeTextColor); SMSTR("style", "unreadcolor", UnreadIndicatorColor); @@ -159,7 +158,6 @@ void SettingsManager::Close() { SMSTR("http", "user_agent", UserAgent); SMSTR("style", "expandercolor", ChannelsExpanderColor); SMSTR("style", "nsfwchannelcolor", NSFWChannelColor); - SMSTR("style", "channelcolor", ChannelColor); SMSTR("style", "mentionbadgecolor", MentionBadgeColor); SMSTR("style", "mentionbadgetextcolor", MentionBadgeTextColor); SMSTR("style", "unreadcolor", UnreadIndicatorColor); diff --git a/src/settings.hpp b/src/settings.hpp index a51d93b..99e1adc 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -40,7 +40,6 @@ public: // [style] std::string ChannelsExpanderColor { "rgba(255, 83, 112, 0)" }; std::string NSFWChannelColor { "#ed6666" }; - std::string ChannelColor { "#fbfbfb" }; std::string MentionBadgeColor { "#b82525" }; std::string MentionBadgeTextColor { "#fbfbfb" }; std::string UnreadIndicatorColor { "#ffffff" }; -- cgit v1.2.3 From 618cd27d94a23a23674fe759bdc74f938ac3d6fe Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 16 Dec 2023 20:01:56 -0500 Subject: draw nsfw channels red again --- src/components/channelscellrenderer.cpp | 10 +++++----- src/settings.hpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 7fd97da..d612812 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -475,11 +475,11 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtrget_color(Gtk::STATE_FLAG_NORMAL); - color.set_alpha(0.6); - m_renderer_text.property_foreground_rgba() = color; - } + auto color = widget.get_style_context()->get_color(Gtk::STATE_FLAG_NORMAL); + if (property_nsfw()) color = nsfw_color; + if (is_muted) color.set_alpha(0.6); + + m_renderer_text.property_foreground_rgba() = color; m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); m_renderer_text.property_foreground_set() = false; diff --git a/src/settings.hpp b/src/settings.hpp index 99e1adc..c51e635 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -39,7 +39,7 @@ public: // [style] std::string ChannelsExpanderColor { "rgba(255, 83, 112, 0)" }; - std::string NSFWChannelColor { "#ed6666" }; + std::string NSFWChannelColor { "#970d0d" }; std::string MentionBadgeColor { "#b82525" }; std::string MentionBadgeTextColor { "#fbfbfb" }; std::string UnreadIndicatorColor { "#ffffff" }; -- cgit v1.2.3 From 6d7ddcd42fd1de1f0ea3eda83e3c76f2d34b6a12 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 16 Dec 2023 20:38:46 -0500 Subject: use background style colors for unread indicator and mention badges --- src/components/channelscellrenderer.cpp | 31 +++++++++++++++---------------- src/settings.hpp | 6 +++--- 2 files changed, 18 insertions(+), 19 deletions(-) (limited to 'src/components') diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index d612812..bf84a9b 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -7,8 +7,11 @@ constexpr static double M_PI = 3.14159265358979; constexpr static double M_PI_H = M_PI / 2.0; constexpr static double M_PI_3_2 = M_PI * 3.0 / 2.0; -void AddUnreadIndicator(const Cairo::RefPtr &cr, const Gdk::Rectangle &background_area) { - static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor); +void AddUnreadIndicator(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area) { + static const auto color_setting = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor); + + const auto color = color_setting.get_alpha_u() > 0 ? color_setting : widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue()); const auto x = background_area.get_x(); const auto y = background_area.get_y(); @@ -387,7 +390,7 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr 0) { - AddUnreadIndicator(cr, background_area); + AddUnreadIndicator(cr, widget, background_area); } } m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); @@ -490,7 +493,7 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtrset_source_rgb(color.get_red(), color.get_green(), color.get_blue()); - const auto x = background_area.get_x(); - const auto y = background_area.get_y(); - const auto w = background_area.get_width(); - const auto h = background_area.get_height(); - cr->rectangle(x, y, 3, h); - cr->fill(); + AddUnreadIndicator(cr, widget, background_area); } if (unread_state < 1) return; @@ -830,7 +826,7 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr & if (unread_state < 0) return; if (!is_muted) { - AddUnreadIndicator(cr, background_area); + AddUnreadIndicator(cr, widget, background_area); } } @@ -857,8 +853,11 @@ void CellRendererChannels::unread_render_mentions(const Cairo::RefPtrget_pixel_size(width, height); { - static const auto bg = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeColor); - static const auto text = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeTextColor); + static const auto badge_setting = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeColor); + static const auto text_setting = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeTextColor); + + auto bg = badge_setting.get_alpha_u() > 0 ? badge_setting : widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED); + auto text = text_setting.get_alpha_u() > 0 ? text_setting : widget.get_style_context()->get_color(Gtk::STATE_FLAG_SELECTED); const auto x = cell_area.get_x() + edge - width - MentionsRightPad; const auto y = cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0 - 1; diff --git a/src/settings.hpp b/src/settings.hpp index c51e635..419734c 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -40,9 +40,9 @@ public: // [style] std::string ChannelsExpanderColor { "rgba(255, 83, 112, 0)" }; std::string NSFWChannelColor { "#970d0d" }; - std::string MentionBadgeColor { "#b82525" }; - std::string MentionBadgeTextColor { "#fbfbfb" }; - std::string UnreadIndicatorColor { "#ffffff" }; + std::string MentionBadgeColor { "rgba(184, 37, 37, 0)" }; + std::string MentionBadgeTextColor { "rgba(251, 251, 251, 0)" }; + std::string UnreadIndicatorColor { "rgba(255, 255, 255, 0)" }; // [notifications] #ifdef _WIN32 -- cgit v1.2.3