timeline: use a string instead of a u64 to identify timeline items

This will allow to define a prefix later, to distinguish detached
timelines from live timelines.
This commit is contained in:
Benjamin Bouvier
2024-04-22 17:57:52 +02:00
parent 9547e3cee6
commit e4331ac9b8
10 changed files with 32 additions and 28 deletions

View File

@@ -746,8 +746,8 @@ impl TimelineItem {
}
}
pub fn unique_id(&self) -> u64 {
self.0.unique_id()
pub fn unique_id(&self) -> String {
self.0.unique_id().to_owned()
}
pub fn fmt_debug(&self) -> String {

View File

@@ -291,7 +291,10 @@ impl DayDividerAdjuster {
}
let unique_id = replaced.unique_id();
let item = TimelineItem::new(VirtualTimelineItem::DayDivider(ts), unique_id);
let item = TimelineItem::new(
VirtualTimelineItem::DayDivider(ts),
unique_id.to_owned(),
);
items.set(at, item);
max_i = i;

View File

@@ -934,13 +934,13 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
// If the old item is the last one and no day divider
// changes need to happen, replace and return early.
trace!(idx, "Replacing existing event");
self.items.set(idx, TimelineItem::new(item, old_item_id));
self.items.set(idx, TimelineItem::new(item, old_item_id.to_owned()));
return;
}
// In more complex cases, remove the item before re-adding the item.
trace!("Removing local echo or duplicate timeline item");
removed_event_item_id = Some(self.items.remove(idx).internal_id);
removed_event_item_id = Some(self.items.remove(idx).internal_id.clone());
// no return here, below code for adding a new event
// will run to re-add the removed item
@@ -988,7 +988,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
#[cfg(feature = "e2e-encryption")]
Flow::Remote { position: TimelineItemPosition::Update(idx), .. } => {
trace!("Updating timeline item at position {idx}");
let id = self.items[*idx].internal_id;
let id = self.items[*idx].internal_id.clone();
self.items.set(*idx, TimelineItem::new(item, id));
}
}
@@ -1040,7 +1040,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
trace!("Found timeline item to update");
if let Some(new_item) = update(self, item.inner) {
trace!("Updating item");
self.items.set(idx, TimelineItem::new(new_item, item.internal_id));
self.items.set(idx, TimelineItem::new(new_item, item.internal_id.to_owned()));
self.result.items_updated += 1;
}
true

View File

@@ -1019,7 +1019,7 @@ impl TimelineInner {
};
trace!("Updating in-reply-to details");
let internal_id = item.internal_id;
let internal_id = item.internal_id.to_owned();
let mut item = item.clone();
item.set_content(TimelineItemContent::Message(
message.with_in_reply_to(InReplyToDetails {

View File

@@ -332,7 +332,7 @@ impl TimelineInnerState {
}
}
let item = TimelineItem::new(new_related, related.internal_id);
let item = TimelineItem::new(new_related, related.internal_id.to_owned());
self.items.set(idx, item);
Ok(())
@@ -757,10 +757,10 @@ impl TimelineInnerMetadata {
/// Returns the next internal id for a timeline item (and increment our
/// internal counter).
pub fn next_internal_id(&mut self) -> u64 {
pub fn next_internal_id(&mut self) -> String {
let val = self.next_internal_id;
self.next_internal_id += 1;
val
format!("{val}")
}
/// Returns a new timeline item with a fresh internal id.

View File

@@ -32,17 +32,18 @@ pub enum TimelineItemKind {
#[derive(Clone, Debug)]
pub struct TimelineItem {
pub(crate) kind: TimelineItemKind,
pub(crate) internal_id: u64,
pub(crate) internal_id: String,
}
impl TimelineItem {
/// Create a new `TimelineItem` with the given kind and internal id.
pub(crate) fn new(kind: impl Into<TimelineItemKind>, internal_id: u64) -> Arc<Self> {
pub(crate) fn new(kind: impl Into<TimelineItemKind>, internal_id: String) -> Arc<Self> {
Arc::new(TimelineItem { kind: kind.into(), internal_id })
}
/// Create a clone of the current `TimelineItem` with the given kind.
pub(crate) fn with_kind(&self, kind: impl Into<TimelineItemKind>) -> Arc<Self> {
Arc::new(Self { kind: kind.into(), internal_id: self.internal_id })
Arc::new(Self { kind: kind.into(), internal_id: self.internal_id.clone() })
}
/// Get the [`TimelineItemKind`] of this item.
@@ -70,14 +71,14 @@ impl TimelineItem {
/// dividers, identity isn't easy to define though and you might
/// see a new ID getting generated for a day divider that you
/// perceive to be "the same" as a previous one.
pub fn unique_id(&self) -> u64 {
self.internal_id
pub fn unique_id(&self) -> &str {
&self.internal_id
}
pub(crate) fn read_marker() -> Arc<TimelineItem> {
Arc::new(Self {
kind: TimelineItemKind::Virtual(VirtualTimelineItem::ReadMarker),
internal_id: u64::MAX,
internal_id: "__read_marker".to_owned(),
})
}

View File

@@ -286,7 +286,7 @@ impl ReadReceiptTimelineUpdate {
return;
};
let event_item_id = event_item.internal_id;
let event_item_id = event_item.internal_id.to_owned();
let mut event_item = event_item.clone();
if let Some(remote_event_item) = event_item.as_remote_mut() {
@@ -321,7 +321,7 @@ impl ReadReceiptTimelineUpdate {
return;
};
let event_item_id = event_item.internal_id;
let event_item_id = event_item.internal_id.to_owned();
let mut event_item = event_item.clone();
if let Some(remote_event_item) = event_item.as_remote_mut() {
@@ -468,7 +468,7 @@ impl TimelineInnerStateTransaction<'_> {
return;
};
let prev_event_item_id = prev_event_item.internal_id;
let prev_event_item_id = prev_event_item.internal_id.to_owned();
let mut prev_event_item = prev_event_item.clone();
let Some(remote_prev_event_item) = prev_event_item.as_remote_mut() else {

View File

@@ -316,10 +316,10 @@ async fn test_dedup_initial() {
assert_eq!(event3.as_event().unwrap().sender(), *CAROL);
// Make sure we reused IDs when deduplicating events
assert_eq!(event1.unique_id(), 0);
assert_eq!(event2.unique_id(), 1);
assert_eq!(event3.unique_id(), 2);
assert_eq!(timeline_items[0].unique_id(), 3);
assert_eq!(event1.unique_id(), "0");
assert_eq!(event2.unique_id(), "1");
assert_eq!(event3.unique_id(), "2");
assert_eq!(timeline_items[0].unique_id(), "3");
}
#[async_test]

View File

@@ -46,7 +46,7 @@ async fn test_remote_echo_full_trip() {
assert!(event_item.is_local_echo());
assert_matches!(event_item.send_state(), Some(EventSendState::NotSentYet));
assert!(!event_item.can_be_replied_to());
item.unique_id()
item.unique_id().to_owned()
};
{

View File

@@ -25,14 +25,14 @@ use super::{event_item::EventTimelineItemKind, EventTimelineItem, TimelineItem};
pub(super) struct EventTimelineItemWithId<'a> {
pub inner: &'a EventTimelineItem,
/// Internal identifier generated by [`TimelineInnerMetadata`].
pub internal_id: u64,
pub internal_id: &'a str,
}
impl<'a> EventTimelineItemWithId<'a> {
pub fn with_inner_kind(&self, kind: impl Into<EventTimelineItemKind>) -> Arc<TimelineItem> {
Arc::new(TimelineItem {
kind: self.inner.with_kind(kind).into(),
internal_id: self.internal_id,
internal_id: self.internal_id.to_owned(),
})
}
}
@@ -59,7 +59,7 @@ pub(super) fn rfind_event_item(
.filter_map(|(idx, item)| {
Some((
idx,
EventTimelineItemWithId { inner: item.as_event()?, internal_id: item.internal_id },
EventTimelineItemWithId { inner: item.as_event()?, internal_id: &item.internal_id },
))
})
.rfind(|(_, it)| f(it.inner))