Format timeline events in a human-readable way

This commit is contained in:
2023-11-04 13:46:41 +01:00
parent b4eeb8a6b8
commit 58ab62d7d3

View File

@ -26,7 +26,8 @@ use matrix_sdk::ruma::OwnedRoomId;
use matrix_sdk::Client;
use matrix_sdk::Room;
use matrix_sdk_ui::timeline::{
BackPaginationStatus, PaginationOptions, RoomExt, Timeline, TimelineItem,
BackPaginationStatus, PaginationOptions, RoomExt, Timeline, TimelineItem, TimelineItemKind,
VirtualTimelineItem,
};
use ratatui::text::Text;
use smallvec::SmallVec;
@ -52,11 +53,153 @@ impl SingleClientRoomBuffer {
}
if let Some(changes) = self.stream.next().await {
for change in changes {
change.map(|timeline_item| format!("{:#?}", timeline_item)).apply(&mut self.items);
change
.map(|item| self.format_timeline_item(item))
.apply(&mut self.items);
}
}
}
fn format_timeline_item(&self, tl_item: impl AsRef<TimelineItem>) -> String {
match tl_item.as_ref().kind() {
TimelineItemKind::Event(event) => {
use matrix_sdk_ui::timeline::TimelineItemContent::*;
let sender = event
.sender()
.as_str()
.strip_prefix("@")
.expect("missing @ prefix");
match event.content() {
Message(message) => format!(" <{}> {}", sender, message.body().replace("\n", "\n ")),
RedactedMessage => format!("xx <{}> [redacted]", sender),
Sticker(sticker) => format!("st <{}> {}", sender, sticker.content().body),
UnableToDecrypt(_) => format!("xx <{}> [unable to decrypt]", sender),
MembershipChange(change) => {
use matrix_sdk_ui::timeline::MembershipChange::*;
if change.user_id() == event.sender() {
let Some(change_kind) = change.change() else {
return format!("--- {} made incomprehensible changes to themselves", sender);
};
match change_kind {
None => format!("--- {} made no discernable changes to themselves", sender),
Error => format!(
"xxx {} made a change to themselves that made matrix-sdk-ui error",
sender
),
Joined => format!("--> {} joined", sender),
Left => format!("<-- {} left", sender),
Banned => format!("-x- {} banned themselves", sender),
Unbanned => format!("-x- {} unbanned themselves", sender),
Kicked => format!("<!- {} kicked themselves", sender),
Invited => format!("-o- {} invited themselves", sender),
KickedAndBanned => format!("<!x {} kicked and banned themselves", sender),
InvitationAccepted => format!("-o> {} accepted an invite", sender),
InvitationRejected => format!("-ox {} rejected an invite", sender),
InvitationRevoked => format!("--x {} revoked an invite", sender),
Knocked => format!("-?> {} knocked", sender),
KnockAccepted => format!("-?o {} accepted a knock", sender),
KnockRetracted => format!("-?x {} retracted a knock", sender),
KnockDenied => format!("-?x {} denied a knock", sender),
NotImplemented => format!(
"xxx {} made a change matrix-sdk-ui does not support yet",
sender
),
}
} else if change.user_id() == "" {
let Some(change_kind) = change.change() else {
return format!("--- {} made incomprehensible changes", sender);
};
match change_kind {
None => format!("--- {} made no discernable changes", sender),
Error => format!("xxx {} made a change that made matrix-sdk-ui error", sender),
Joined | Left | Banned | Unbanned | Kicked | Invited | KickedAndBanned
| InvitationAccepted | InvitationRejected | InvitationRevoked | Knocked
| KnockAccepted | KnockRetracted | KnockDenied => {
format!("--> {} made a non-sensical change: {:?}", sender, change)
},
NotImplemented => format!(
"xxx {} made a change matrix-sdk-ui does not support yet",
sender
),
}
} else {
let target = change
.user_id()
.as_str()
.strip_prefix("@")
.expect("missing @ prefix");
let Some(change_kind) = change.change() else {
return format!("--- {} made incomprehensible changes to {}", sender, target);
};
match change_kind {
None => format!("--- {} made no discernable changes to {}", sender, target),
Error => format!(
"xxx {} made a change to {} that made matrix-sdk-ui error",
sender, target
),
Joined | Left => format!(
"--> {} made a non-sensical change to {}: {:?}",
sender, target, change
),
Banned => format!("-x- {} banned {}", sender, target),
Unbanned => format!("-x- {} unbanned {}", sender, target),
Kicked => format!("<!- {} kicked {}", sender, target),
Invited => format!("-o- {} invited {}", sender, target),
KickedAndBanned => format!("<!x {} kicked and banned {}", sender, target),
InvitationAccepted => format!("-o> {} accepted an invite to {}", sender, target),
InvitationRejected => format!("-ox {} rejected an invite to {}", sender, target),
InvitationRevoked => format!("--x {} revoked an invite to {}", sender, target),
Knocked => format!("-?> {} made {} knock", sender, target),
KnockAccepted => format!("-?o {} accepted {}'s knock", sender, target),
KnockRetracted => format!("-?x {} retracted {}'s knock", sender, target),
KnockDenied => format!("-?x {} denied {}'s knock", sender, target),
NotImplemented => format!(
"xxx {} made a change to {} that matrix-sdk-ui does not support yet",
sender, target
),
}
}
},
ProfileChange(_) => format!("--- {} updated their profile", sender),
OtherState(state) => {
if state.state_key() == "" {
format!("--- {} changed the room: {:?}", sender, state.content())
} else {
format!(
"--- {} changed {}: {:?}",
sender,
state.state_key(),
state.content()
)
}
},
FailedToParseMessageLike { event_type, error } => format!(
"xxx {} sent a {} message that made matrix-sdk-ui error: {:?}",
sender, event_type, error
),
FailedToParseState {
event_type,
state_key,
error,
} => {
format!(
"xxx {} made a {} change to {} that made matrix-sdk-ui error: {:?}",
sender, event_type, state_key, error
)
},
Poll(_) => format!("-?- {} acted on a poll", sender),
}
},
TimelineItemKind::Virtual(VirtualTimelineItem::ReadMarker) => {
format!("---- read marker ----")
},
TimelineItemKind::Virtual(VirtualTimelineItem::DayDivider(day_divider)) => {
format!("---- day divider: {:?} ----", day_divider)
},
}
}
async fn spawn_back_pagination(&self, num: u16) {
let room_id = self.room_id.clone();
let timeline = self.timeline.clone();