room-history: Show tooltip for read receipts details

This commit is contained in:
Kévin Commaille 2023-10-28 13:52:21 +02:00
parent 24d6a7ce32
commit 4fcaa2da7f
No known key found for this signature in database
GPG key ID: 29A48C1F03620416
3 changed files with 59 additions and 2 deletions

View file

@ -91,6 +91,7 @@ src/session/view/content/room_history/message_toolbar/mod.rs
src/session/view/content/room_history/message_toolbar/mod.ui src/session/view/content/room_history/message_toolbar/mod.ui
src/session/view/content/room_history/mod.rs src/session/view/content/room_history/mod.rs
src/session/view/content/room_history/mod.ui src/session/view/content/room_history/mod.ui
src/session/view/content/room_history/read_receipts_list/mod.rs
src/session/view/content/room_history/state_row/creation.rs src/session/view/content/room_history/state_row/creation.rs
src/session/view/content/room_history/state_row/creation.ui src/session/view/content/room_history/state_row/creation.ui
src/session/view/content/room_history/state_row/mod.rs src/session/view/content/room_history/state_row/mod.rs

View file

@ -6,8 +6,9 @@ mod member_read_receipt;
use self::member_read_receipt::MemberReadReceipt; use self::member_read_receipt::MemberReadReceipt;
use crate::{ use crate::{
components::{Avatar, OverlappingBox}, components::{Avatar, OverlappingBox},
i18n::{gettext_f, ngettext_f},
prelude::*, prelude::*,
session::model::{MemberList, UserReadReceipt}, session::model::{Member, MemberList, UserReadReceipt},
utils::BoundObjectWeakRef, utils::BoundObjectWeakRef,
}; };
@ -28,6 +29,8 @@ mod imp {
resource = "/org/gnome/Fractal/ui/session/view/content/room_history/read_receipts_list/mod.ui" resource = "/org/gnome/Fractal/ui/session/view/content/room_history/read_receipts_list/mod.ui"
)] )]
pub struct ReadReceiptsList { pub struct ReadReceiptsList {
#[template_child]
pub container: TemplateChild<gtk::Box>,
#[template_child] #[template_child]
pub label: TemplateChild<gtk::Label>, pub label: TemplateChild<gtk::Label>,
#[template_child] #[template_child]
@ -38,16 +41,20 @@ mod imp {
pub list: gio::ListStore, pub list: gio::ListStore,
/// The read receipts used as a source. /// The read receipts used as a source.
pub source: BoundObjectWeakRef<gio::ListStore>, pub source: BoundObjectWeakRef<gio::ListStore>,
/// The displayed member if there is only one receipt.
pub receipt_member: BoundObjectWeakRef<Member>,
} }
impl Default for ReadReceiptsList { impl Default for ReadReceiptsList {
fn default() -> Self { fn default() -> Self {
Self { Self {
container: Default::default(),
label: Default::default(), label: Default::default(),
overlapping_box: Default::default(), overlapping_box: Default::default(),
members: Default::default(), members: Default::default(),
list: gio::ListStore::new::<MemberReadReceipt>(), list: gio::ListStore::new::<MemberReadReceipt>(),
source: Default::default(), source: Default::default(),
receipt_member: Default::default(),
} }
} }
} }
@ -122,6 +129,7 @@ mod imp {
self.list self.list
.connect_items_changed(clone!(@weak obj => move |_, _,_,_| { .connect_items_changed(clone!(@weak obj => move |_, _,_,_| {
obj.update_tooltip();
obj.update_label(); obj.update_label();
})); }));
} }
@ -214,6 +222,54 @@ impl ReadReceiptsList {
self.list().splice(pos, removed, &new_receipts); self.list().splice(pos, removed, &new_receipts);
} }
fn update_tooltip(&self) {
let imp = self.imp();
imp.receipt_member.disconnect_signals();
let n_items = self.list().n_items();
if n_items == 1 {
if let Some(member) = self
.list()
.item(0)
.and_downcast::<MemberReadReceipt>()
.and_then(|r| r.member())
{
// Listen to changes of the display name.
let handler_id = member.connect_notify_local(
Some("display-name"),
clone!(@weak self as obj => move |member, _| {
obj.update_member_tooltip(member);
}),
);
imp.receipt_member.set(&member, vec![handler_id]);
self.update_member_tooltip(&member);
return;
}
}
let text = (n_items > 0).then(|| {
ngettext_f(
// Translators: Do NOT translate the content between '{' and '}', this is a
// variable name.
"Seen by 1 member",
"Seen by {n} members",
n_items,
&[("n", &n_items.to_string())],
)
});
self.imp().container.set_tooltip_text(text.as_deref())
}
fn update_member_tooltip(&self, member: &Member) {
// Translators: Do NOT translate the content between '{' and '}', this is a
// variable name.
let text = gettext_f("Seen by {name}", &[("name", &member.display_name())]);
self.imp().container.set_tooltip_text(Some(&text));
}
fn update_label(&self) { fn update_label(&self) {
let label = &self.imp().label; let label = &self.imp().label;
let n_items = self.list().n_items(); let n_items = self.list().n_items();

View file

@ -2,7 +2,7 @@
<interface> <interface>
<template class="ContentReadReceiptsList" parent="AdwBin"> <template class="ContentReadReceiptsList" parent="AdwBin">
<child> <child>
<object class="GtkBox"> <object class="GtkBox" id="container">
<property name="halign">end</property> <property name="halign">end</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child> <child>