Skip to content

Commit

Permalink
chat-history: Add linear gradient to outgoing messages
Browse files Browse the repository at this point in the history
  • Loading branch information
yuraiz committed May 20, 2023
1 parent 5c68568 commit 1cba840
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 3 deletions.
5 changes: 5 additions & 0 deletions data/resources/style-dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ messagebubble.outgoing {
background-color: #2c52ac;
}

messagebubble.document.outgoing .file > overlay > image {
background: @accent_fg_color;
color: @accent_bg_color;
}

.event-row {
background-color: alpha(#404040, 0.8);
}
Expand Down
9 changes: 7 additions & 2 deletions data/resources/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ messagebubble.document .file > overlay > image {
}

messagebubble.document.outgoing .file > overlay > image {
background: @accent_fg_color;
color: @accent_bg_color;
/* depends on bubble color */
background: #79c271;
color: #eafcd2;
}

messagebubble.document .file:hover > overlay > image {
Expand Down Expand Up @@ -326,6 +327,10 @@ messagereply label.message {
color: @window_fg_color;
}

messagebubble.outgoing messagereply label.message {
color: currentColor;
}

messagesticker {
border-spacing: 6px;
}
Expand Down
85 changes: 84 additions & 1 deletion src/session/content/message_row/bubble.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use adw::prelude::*;
use glib::clone;
use gtk::subclass::prelude::*;
use gtk::{glib, CompositeTemplate};
use gtk::{gdk, glib, graphene, gsk, CompositeTemplate};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

Expand Down Expand Up @@ -28,6 +29,8 @@ mod imp {
using Adw 1;
template $MessageBubble {
overflow: hidden;
Overlay overlay {
Box {
orientation: vertical;
Expand Down Expand Up @@ -60,6 +63,7 @@ mod imp {
pub(crate) struct MessageBubble {
pub(super) sender_color_class: RefCell<Option<String>>,
pub(super) sender_binding: RefCell<Option<gtk::ExpressionWatch>>,
pub(super) parent_list_view: RefCell<glib::WeakRef<gtk::ListView>>,
#[template_child]
pub(super) overlay: TemplateChild<gtk::Overlay>,
#[template_child]
Expand Down Expand Up @@ -119,6 +123,45 @@ mod imp {
}

impl WidgetImpl for MessageBubble {
fn realize(&self) {
self.parent_realize();

let widget = self.obj();

if let Some(view) = widget.parent_list_view() {
self.parent_list_view.replace(view.downgrade());
view.vadjustment()
.unwrap()
.connect_value_notify(clone!(@weak widget => move |_| {
widget.queue_draw();
}));
}
}

fn snapshot(&self, snapshot: &gtk::Snapshot) {
let widget = self.obj();
if widget.has_css_class("outgoing") {
let width = widget.width() as f32;
let height = widget.height() as f32;

let bounds = graphene::Rect::new(0.0, 0.0, width, height);
let gradient_bounds = widget.gradient_bounds();
let [first, second] = widget.linear_gradient_colors();

snapshot.append_linear_gradient(
&bounds,
&graphene::Point::new(0.0, gradient_bounds.y()),
&graphene::Point::new(0.0, gradient_bounds.height()),
&[
gsk::ColorStop::new(0.0, first),
gsk::ColorStop::new(1.0, second),
],
);
}

self.parent_snapshot(snapshot);
}

fn measure(&self, orientation: gtk::Orientation, for_size: i32) -> (i32, i32, i32, i32) {
// Limit the widget width
if orientation == gtk::Orientation::Horizontal {
Expand Down Expand Up @@ -308,4 +351,44 @@ impl MessageBubble {
.set_indicators(Some(imp.indicators.clone()));
}
}

fn parent_list_view(&self) -> Option<gtk::ListView> {
let mut parent = self.parent()?;
loop {
match parent.downcast() {
Ok(list_view) => return Some(list_view),
Err(not_list_view) => parent = not_list_view.parent()?,
}
}
}

fn gradient_bounds(&self) -> graphene::Rect {
if let Some(view) = self.imp().parent_list_view.borrow().upgrade() {
let view_bounds = view.compute_bounds(self.imp().obj().as_ref()).unwrap();

graphene::Rect::new(
view_bounds.x(),
view_bounds.y(),
view_bounds.width() + view_bounds.x(),
view_bounds.height() + view_bounds.y(),
)
} else {
panic!("can't get parent ListView");
}
}

fn linear_gradient_colors(&self) -> [gdk::RGBA; 2] {
// default colors from iOS
if !adw::StyleManager::default().is_dark() {
[
gdk::RGBA::new(0.91764706, 0.9882353, 0.8235294, 1.0),
gdk::RGBA::new(0.91764706, 0.9882353, 0.8235294, 1.0),
]
} else {
[
gdk::RGBA::new(0.21960784, 0.32156864, 0.89411765, 1.0),
gdk::RGBA::new(0.63529414, 0.3372549, 0.58431375, 1.0),
]
}
}
}

0 comments on commit 1cba840

Please sign in to comment.