Skip to content

Commit

Permalink
feat: Provide method to set last read message
Browse files Browse the repository at this point in the history
  • Loading branch information
nesium committed Jun 11, 2024
1 parent 68534d3 commit 69e367c
Show file tree
Hide file tree
Showing 3 changed files with 358 additions and 31 deletions.
10 changes: 10 additions & 0 deletions bindings/prose-sdk-js/src/types/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface RoomBase {
loadDraft(): Promise<string>;
markAsRead(): Promise<void>;
setLastReadMessage(messageID: string): Promise<void>;
}
export interface RoomMUC {
Expand Down Expand Up @@ -394,6 +395,15 @@ macro_rules! base_room_impl {
pub async fn mark_as_read(&self) -> Result<()> {
Ok(self.room.mark_as_read().await.map_err(WasmError::from)?)
}

#[wasm_bindgen(js_name = "setLastReadMessage")]
pub async fn set_last_read_message(&self, message_id: &str) -> Result<()> {
self.room
.set_last_read_message(&message_id.into())
.await
.map_err(WasmError::from)?;
Ok(())
}
}
};
}
Expand Down
131 changes: 105 additions & 26 deletions crates/prose-core-client/src/app/services/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use crate::app::deps::{
DynSyncedRoomSettingsService, DynTimeProvider, DynUserProfileRepository,
};
use crate::domain::messaging::models::{
send_message_request, Emoji, Message, MessageId, MessageLike, MessageLikeError, MessageParser,
MessageTargetId,
send_message_request, ArchivedMessageRef, Emoji, Message, MessageId, MessageLike,
MessageLikeError, MessageParser, MessageTargetId,
};
use crate::domain::messaging::models::{MessageLikeId, MessageLikePayload, SendMessageRequest};
use crate::domain::rooms::models::{Room as DomainRoom, RoomAffiliation, RoomSpec};
Expand Down Expand Up @@ -418,38 +418,58 @@ impl<Kind> Room<Kind> {
})
}

pub async fn set_last_read_message(&self, id: &MessageId) -> Result<()> {
let account = self.ctx.connected_account()?;

let mut messages = self
.message_repo
.get(&account, &self.data.room_id, id)
.await?;

if messages.is_empty() {
return Err(anyhow!("No message exists with id {id}."));
}

let message = messages.swap_remove(0);

if let Some(stanza_id) = message.stanza_id {
return self
.set_last_read_message_ref(
&account,
Some(ArchivedMessageRef {
stanza_id,
timestamp: message.timestamp,
}),
true,
)
.await;
}

self.set_last_read_message_ref(
&account,
self.message_repo
.get_last_received_message(&account, &self.data.room_id, Some(message.timestamp))
.await?,
true,
)
.await?;

Ok(())
}

pub async fn mark_as_read(&self) -> Result<()> {
let account = self.ctx.connected_account()?;

let Some(message_ref) = self
.message_repo
.get_last_received_message(&self.ctx.connected_account()?, &self.data.room_id, None)
.get_last_received_message(&account, &self.data.room_id, None)
.await?
else {
return Ok(());
};

let mut updated_message_ids = vec![];

self.update_synced_settings(|settings| {
if settings.last_read_message.as_ref() == Some(&message_ref) {
return;
}

if let Some(former_message_ref) = settings.last_read_message.take() {
updated_message_ids.push(former_message_ref.stanza_id);
}
updated_message_ids.push(message_ref.stanza_id.clone());
settings.last_read_message = Some(message_ref);
})
.await;

if updated_message_ids.is_empty() {
return Ok(());
}

self.inner.data.set_needs_update_statistics();
self.client_event_dispatcher
.dispatch_event(ClientEvent::SidebarChanged);

self.set_last_read_message_ref(&account, Some(message_ref), false)
.await?;
Ok(())
}

Expand Down Expand Up @@ -832,6 +852,65 @@ impl<Kind> Room<Kind> {
}
}
}

async fn set_last_read_message_ref(
&self,
account: &AccountId,
message_ref: Option<ArchivedMessageRef>,
send_message_changed_events: bool,
) -> Result<()> {
let mut updated_stanza_ids = vec![];

self.update_synced_settings(|settings| {
if settings.last_read_message == message_ref {
return;
}

if let Some(former_message_ref) = settings.last_read_message.take() {
updated_stanza_ids.push(former_message_ref.stanza_id);
}

if let Some(stanza_id) = message_ref.as_ref().map(|r| r.stanza_id.clone()) {
updated_stanza_ids.push(stanza_id);
}

settings.last_read_message = message_ref;
})
.await;

if updated_stanza_ids.is_empty() {
return Ok(());
}

if send_message_changed_events {
let mut updated_message_ids = vec![];

for id in updated_stanza_ids {
if let Some(message_id) = self
.message_repo
.resolve_message_id(&account, &self.data.room_id, &id)
.await?
{
updated_message_ids.push(message_id);
}
}

if !updated_message_ids.is_empty() {
self.client_event_dispatcher.dispatch_room_event(
self.data.clone(),
ClientRoomEventType::MessagesUpdated {
message_ids: updated_message_ids,
},
)
}
}

self.inner.data.set_needs_update_statistics();
self.client_event_dispatcher
.dispatch_event(ClientEvent::SidebarChanged);

Ok(())
}
}

impl Room<Group> {
Expand Down
Loading

0 comments on commit 69e367c

Please sign in to comment.