Browse Source

room-history: Display the sender of membership change events

fractal-12
Kévin Commaille 9 months ago
parent
commit
0eec6d8189
No known key found for this signature in database
GPG Key ID: F26F4BE20A08255B
  1. 165
      src/session/view/content/room_history/state/content.rs

165
src/session/view/content/room_history/state/content.rs

@ -1,6 +1,6 @@
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
use gtk::{glib, pango};
use gtk::{glib, glib::clone, pango};
use matrix_sdk_ui::timeline::{
AnyOtherFullStateEventContent, MemberProfileChange, MembershipChange, OtherState,
RoomMembershipChange, TimelineItemContent,
@ -12,7 +12,12 @@ use ruma::{
use tracing::warn;
use super::StateCreation;
use crate::{gettext_f, prelude::*, session::model::Event};
use crate::{
gettext_f,
prelude::*,
session::model::{Event, Member},
utils::BoundObjectWeakRef,
};
mod imp {
use super::*;
@ -23,6 +28,8 @@ mod imp {
/// The state event displayed by this widget.
#[property(get, set = Self::set_event, nullable)]
event: glib::WeakRef<Event>,
/// The sender of the event.
sender: BoundObjectWeakRef<Member>,
}
#[glib::object_subclass]
@ -46,26 +53,45 @@ mod imp {
return;
};
let sender = event.sender();
let disambiguated_name_handler = sender.connect_disambiguated_name_notify(clone!(
#[weak(rename_to = imp)]
self,
move |_| {
imp.update_content();
}
));
self.sender.set(&sender, vec![disambiguated_name_handler]);
self.event.set(Some(event));
self.update_content();
}
/// Update the content for the current state.
fn update_content(&self) {
let Some(event) = self.event.upgrade() else {
return;
};
let Some(sender) = self.sender.obj() else {
return;
};
match event.content() {
TimelineItemContent::MembershipChange(membership_change) => {
self.update_with_membership_change(&membership_change, &event.sender_id());
self.update_with_membership_change(&membership_change, &sender);
}
TimelineItemContent::ProfileChange(profile_change) => {
self.update_with_profile_change(&profile_change, &sender);
}
TimelineItemContent::ProfileChange(profile_change) => self
.update_with_profile_change(
&profile_change,
&event.sender().disambiguated_name(),
),
TimelineItemContent::OtherState(other_state) => {
self.update_with_other_state(&other_state);
self.update_with_other_state(&other_state, &sender);
}
_ => unreachable!(),
}
self.event.set(Some(event));
}
/// Update this row with the given [`OtherState`].
fn update_with_other_state(&self, other_state: &OtherState) {
fn update_with_other_state(&self, other_state: &OtherState, sender: &Member) {
let widget = match other_state.content() {
AnyOtherFullStateEventContent::RoomCreate(content) => {
WidgetType::Creation(StateCreation::new(content))
@ -86,8 +112,11 @@ mod imp {
WidgetType::Text(gettext_f(
// Translators: Do NOT translate the content between '{' and '}', this is a
// variable name.
"{user} was invited to this room.",
&[("user", display_name)],
"{sender} invited {user}.",
&[
("sender", &sender.disambiguated_name()),
("user", display_name),
],
))
}
_ => {
@ -113,9 +142,10 @@ mod imp {
fn update_with_membership_change(
&self,
membership_change: &RoomMembershipChange,
sender: &UserId,
sender: &Member,
) {
let display_name = match membership_change.content() {
let sender_display_name = sender.disambiguated_name();
let target_display_name = match membership_change.content() {
FullStateEventContent::Original { content, .. } => content
.displayname
.clone()
@ -124,66 +154,81 @@ mod imp {
};
let supported_membership_change =
Self::to_supported_membership_change(membership_change, sender);
Self::to_supported_membership_change(membership_change, sender.user_id());
let message = match supported_membership_change {
MembershipChange::Joined => {
// Translators: Do NOT translate the content between '{' and '}', this
// is a variable name.
gettext_f("{user} joined this room.", &[("user", &display_name)])
gettext_f(
"{user} joined this room.",
&[("user", &target_display_name)],
)
}
MembershipChange::Left => {
// Translators: Do NOT translate the content between '{' and '}',
// this is a variable name.
gettext_f("{user} left the room.", &[("user", &display_name)])
gettext_f("{user} left the room.", &[("user", &target_display_name)])
}
MembershipChange::Banned => gettext_f(
MembershipChange::Banned | MembershipChange::KickedAndBanned => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} was banned.",
&[("user", &display_name)],
// '{' and '}', these are variable names.
"{sender} banned {user}.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
MembershipChange::Unbanned => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} was unbanned.",
&[("user", &display_name)],
// '{' and '}', these are variable names.
"{sender} unbanned {user}.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
MembershipChange::Kicked => gettext_f(
// Translators: Do NOT translate the content between '{' and
// '}', this is a variable name.
"{user} was kicked out of the room.",
&[("user", &display_name)],
// '}', these are variable names.
"{sender} kicked {user} out.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
MembershipChange::Invited | MembershipChange::KnockAccepted => gettext_f(
// Translators: Do NOT translate the content between '{' and '}', this is
// a variable name.
"{user} was invited to this room.",
&[("user", &display_name)],
),
MembershipChange::KickedAndBanned => gettext_f(
// Translators: Do NOT translate the content between '{' and '}', this is
// a variable name.
"{user} was kicked out of the room and banned.",
&[("user", &display_name)],
// Translators: Do NOT translate the content between '{' and '}', these are
// variable names.
"{sender} invited {user}.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
MembershipChange::InvitationAccepted => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} accepted the invite.",
&[("user", &display_name)],
&[("user", &target_display_name)],
),
MembershipChange::InvitationRejected => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} rejected the invite.",
&[("user", &display_name)],
// '{' and '}', these are variable names.
"{user} declined the invite.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
MembershipChange::InvitationRevoked => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"The invitation for {user} has been revoked.",
&[("user", &display_name)],
// '{' and '}', these are variable names.
"{sender} revoked the invitation for {user}.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
MembershipChange::Knocked =>
// TODO: Add button to invite the user.
@ -192,20 +237,23 @@ mod imp {
// Translators: Do NOT translate the content between '{' and '}', this
// is a variable name.
"{user} requested to be invited to this room.",
&[("user", &display_name)],
&[("user", &target_display_name)],
)
}
MembershipChange::KnockRetracted => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} retracted their request to be invited to this room.",
&[("user", &display_name)],
&[("user", &target_display_name)],
),
MembershipChange::KnockDenied => gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user}’s request to be invited to this room was denied.",
&[("user", &display_name)],
// '{' and '}', these are variable names.
"{sender} denied {user}’s request to be invited to this room.",
&[
("sender", &sender_display_name),
("user", &target_display_name),
],
),
_ => {
warn!(
@ -271,7 +319,7 @@ mod imp {
fn update_with_profile_change(
&self,
profile_change: &MemberProfileChange,
display_name: &str,
sender: &Member,
) {
let message = if let Some(displayname) = profile_change.displayname_change() {
if let Some(prev_name) = &displayname.old {
@ -309,33 +357,38 @@ mod imp {
)
}
} else if let Some(avatar_url) = profile_change.avatar_url_change() {
let display_name = sender.disambiguated_name();
if avatar_url.old.is_none() {
gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} set their avatar.",
&[("user", display_name)],
&[("user", &display_name)],
)
} else if avatar_url.new.is_none() {
gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} removed their avatar.",
&[("user", display_name)],
&[("user", &display_name)],
)
} else {
gettext_f(
// Translators: Do NOT translate the content between
// '{' and '}', this is a variable name.
"{user} changed their avatar.",
&[("user", display_name)],
&[("user", &display_name)],
)
}
} else {
// We don't know what changed so fall back to the membership.
// Translators: Do NOT translate the content between '{' and '}', this
// is a variable name.
gettext_f("{user} joined this room.", &[("user", display_name)])
gettext_f(
"{user} joined this room.",
&[("user", &sender.disambiguated_name())],
)
};
let child = self.obj().child_or_else::<gtk::Label>(text);

Loading…
Cancel
Save