Commit 913832a327a8
tarball6 files changed+48-14
@@ -1,8 +1,10 @@
11
use std::{collections::HashMap, sync::Arc};22
33
use futures_util::future::{join_all, try_join};4
-use matrix_sdk::{Room, room::MessagesOptions};5
-use ruma::{OwnedEventId, OwnedUserId, UInt};4
+use matrix_sdk::{5
+ Room, deserialized_responses::TimelineEvent as SdkTimelineEvent, room::MessagesOptions,6
+};7
+use ruma::{OwnedEventId, OwnedUserId, UInt, push::Action};68
use serde_json::Value;79
810
use crate::{@@ -51,7 +53,14 @@ pub(crate) async fn execute(
5153
));5254
}5355
let side = fetch_side(&room, Some(&token), limit, backwards).await?;54
- let mut page = Assembly::new(&room, current_user_id.as_deref(), &side.values, None).await;56
+ let mut page = Assembly::new(57
+ &room,58
+ current_user_id.as_deref(),59
+ &side.values,60
+ &side.highlights,61
+ None,62
+ )63
+ .await;5564
let events = page.take(0..side.values.len());5665
media.register(page.media).await;5766
Ok(crate::CommandOutput::EventContextPage(EventContextPage {@@ -84,10 +93,10 @@ pub(crate) async fn capture(
8493
error8594
}8695
})?;87
- let target = raw96
+ let (target, target_highlight) = raw8897
.event8998
.as_ref()90
- .and_then(|event| serde_json::from_str::<Value>(event.raw().json().get()).ok())99
+ .and_then(raw_event)91100
.ok_or_else(|| Error::new(ErrorKind::EventNotFound, "event was not found"))?;92101
let (before, after) = try_join(93102
fetch_side(&room, raw.prev_batch_token.as_deref(), before_limit, true),@@ -98,10 +107,14 @@ pub(crate) async fn capture(
98107
let mut values = before.values;99108
values.push(target);100109
values.extend(after.values);110
+ let mut highlights = before.highlights;111
+ highlights.push(target_highlight);112
+ highlights.extend(after.highlights);101113
let mut page = Assembly::new(102114
&room,103115
current_user_id.as_deref(),104116
&values,117
+ &highlights,105118
Some(target_index),106119
)107120
.await;@@ -127,9 +140,19 @@ pub(crate) async fn capture(
127140
struct Side {128141
/// in timeline order129142
values: Vec<Value>,143
+ /// beside `values`, from the push actions the sdk worked out as it fetched144
+ highlights: Vec<bool>,130145
token: Option<String>,131146
}132147
148
+fn raw_event(event: &SdkTimelineEvent) -> Option<(Value, bool)> {149
+ let value = serde_json::from_str(event.raw().json().get()).ok()?;150
+ let highlight = event151
+ .push_actions()152
+ .is_some_and(|actions| actions.iter().any(Action::is_highlight));153
+ Some((value, highlight))154
+}155
+133156
async fn fetch_side(134157
room: &Room,135158
token: Option<&str>,@@ -139,12 +162,14 @@ async fn fetch_side(
139162
let Some(token) = token else {140163
return Ok(Side {141164
values: Vec::new(),165
+ highlights: Vec::new(),142166
token: None,143167
});144168
};145169
if limit == 0 {146170
return Ok(Side {147171
values: Vec::new(),172
+ highlights: Vec::new(),148173
token: Some(token.to_owned()),149174
});150175
}@@ -159,16 +184,14 @@ async fn fetch_side(
159184
.messages(options)160185
.await161186
.map_err(|source| Error::from_sdk("fetching event context events failed", source))?;162
- let mut values: Vec<Value> = messages163
- .chunk164
- .iter()165
- .filter_map(|event| serde_json::from_str(event.raw().json().get()).ok())166
- .collect();187
+ let mut events: Vec<_> = messages.chunk.iter().filter_map(raw_event).collect();167188
if backwards {168
- values.reverse();189
+ events.reverse();169190
}191
+ let (values, highlights) = events.into_iter().unzip();170192
Ok(Side {171193
values,194
+ highlights,172195
token: messages.end,173196
})174197
}@@ -184,10 +207,16 @@ impl Assembly {
184207
room: &Room,185208
current_user_id: Option<&ruma::UserId>,186209
values: &[Value],210
+ highlights: &[bool],187211
keep: Option<usize>,188212
) -> Self {189213
let page = normalise_context(values, keep, current_user_id, room.room_id());190214
let mut items = page.items;215
+ for (index, item) in &mut items {216
+ if let TimelineItem::Event(event) = item {217
+ event.highlight = highlights[*index];218
+ }219
+ }191220
let mut media = page.media;192221
let mut targets: HashMap<OwnedEventId, TimelineEvent> = HashMap::new();193222
let mut missing = Vec::new();@@ -172,9 +172,9 @@ impl EngineError {
172172
kind: match self {173173
Self::EventReceiverClosed => EngineErrorKind::EventReceiverClosed,174174
Self::TaskPanicked { .. } => EngineErrorKind::Watcher,175
- Self::Unauthenticated176
- | Self::ZeroCapacity177
- | Self::SyncService(_) => EngineErrorKind::Other,175
+ Self::Unauthenticated | Self::ZeroCapacity | Self::SyncService(_) => {176
+ EngineErrorKind::Other177
+ }178178
},179179
message: self.to_string(),180180
}@@ -60,6 +60,7 @@ fn message_event(event_id: &str, timestamp_ms: u64, body: &str) -> TimelineItem
6060
reactions: Vec::new(),6161
read_by: Vec::new(),6262
editable: false,63
+ highlight: false,6364
}))6465
}6566
@@ -1629,6 +1629,8 @@ pub struct TimelineEvent {
16291629
pub reactions: Vec<Reaction>,16301630
pub read_by: Vec<OwnedUserId>,16311631
pub editable: bool,1632
+ /// the push rules ask for this one to stand out, always false for a local echo1633
+ pub highlight: bool,16321634
}16331635
16341636
impl TimelineEvent {@@ -182,6 +182,7 @@ pub(crate) fn normalise_observed(
182182
reactions: Vec::new(),183183
read_by: Vec::new(),184184
editable: false,185
+ highlight: false,185186
};186187
Some((TimelineItem::Event(Box::new(event)), media))187188
}@@ -145,6 +145,7 @@ impl Normaliser<'_> {
145145
reactions: reactions(event, self.current_user_id),146146
read_by,147147
editable: event.is_editable(),148
+ highlight: event.is_highlighted(),148149
}149150
}150151
}