Set messages' seen status when adding to vault
This commit is contained in:
parent
fdb8fc7bd0
commit
20ec6ef3b3
2 changed files with 81 additions and 37 deletions
|
|
@ -19,8 +19,9 @@ use crate::macros::ok_or_return;
|
||||||
use crate::ui::UiEvent;
|
use crate::ui::UiEvent;
|
||||||
use crate::vault::{EuphVault, Vault};
|
use crate::vault::{EuphVault, Vault};
|
||||||
|
|
||||||
use super::api::{Data, Log, Nick, Send, Snowflake};
|
use super::api::{Data, Log, Nick, Send, Snowflake, UserId};
|
||||||
use super::conn::{self, ConnRx, ConnTx, Status};
|
use super::conn::{self, ConnRx, ConnTx, Status};
|
||||||
|
use super::Joining;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
@ -170,6 +171,13 @@ impl State {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn own_user_id(&self) -> Option<UserId> {
|
||||||
|
Some(match self.conn_tx.as_ref()?.status().await.ok()? {
|
||||||
|
Status::Joining(Joining { hello, .. }) => hello?.session.id,
|
||||||
|
Status::Joined(joined) => joined.session.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async fn on_data(&mut self, data: Data) -> anyhow::Result<()> {
|
async fn on_data(&mut self, data: Data) -> anyhow::Result<()> {
|
||||||
match data {
|
match data {
|
||||||
Data::BounceEvent(_) => {}
|
Data::BounceEvent(_) => {}
|
||||||
|
|
@ -202,9 +210,10 @@ impl State {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Data::SendEvent(d) => {
|
Data::SendEvent(d) => {
|
||||||
|
let own_user_id = self.own_user_id().await;
|
||||||
if let Some(last_msg_id) = &mut self.last_msg_id {
|
if let Some(last_msg_id) = &mut self.last_msg_id {
|
||||||
let id = d.0.id;
|
let id = d.0.id;
|
||||||
self.vault.add_message(d.0, *last_msg_id);
|
self.vault.add_message(d.0, *last_msg_id, own_user_id);
|
||||||
*last_msg_id = Some(id);
|
*last_msg_id = Some(id);
|
||||||
} else {
|
} else {
|
||||||
bail!("send event before snapshot event");
|
bail!("send event before snapshot event");
|
||||||
|
|
@ -214,15 +223,18 @@ impl State {
|
||||||
info!("e&{}: successfully joined", self.name);
|
info!("e&{}: successfully joined", self.name);
|
||||||
self.vault.join(Time::now());
|
self.vault.join(Time::now());
|
||||||
self.last_msg_id = Some(d.log.last().map(|m| m.id));
|
self.last_msg_id = Some(d.log.last().map(|m| m.id));
|
||||||
self.vault.add_messages(d.log, None);
|
let own_user_id = self.own_user_id().await;
|
||||||
|
self.vault.add_messages(d.log, None, own_user_id);
|
||||||
}
|
}
|
||||||
Data::LogReply(d) => {
|
Data::LogReply(d) => {
|
||||||
self.vault.add_messages(d.log, d.before);
|
let own_user_id = self.own_user_id().await;
|
||||||
|
self.vault.add_messages(d.log, d.before, own_user_id);
|
||||||
}
|
}
|
||||||
Data::SendReply(d) => {
|
Data::SendReply(d) => {
|
||||||
|
let own_user_id = self.own_user_id().await;
|
||||||
if let Some(last_msg_id) = &mut self.last_msg_id {
|
if let Some(last_msg_id) = &mut self.last_msg_id {
|
||||||
let id = d.0.id;
|
let id = d.0.id;
|
||||||
self.vault.add_message(d.0, *last_msg_id);
|
self.vault.add_message(d.0, *last_msg_id, own_user_id);
|
||||||
*last_msg_id = Some(id);
|
*last_msg_id = Some(id);
|
||||||
} else {
|
} else {
|
||||||
bail!("send reply before snapshot event");
|
bail!("send reply before snapshot event");
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Trans
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
use crate::euph::api::{Message, Snowflake, Time};
|
use crate::euph::api::{Message, Snowflake, Time, UserId};
|
||||||
use crate::euph::SmallMessage;
|
use crate::euph::SmallMessage;
|
||||||
use crate::store::{MsgStore, Path, Tree};
|
use crate::store::{MsgStore, Path, Tree};
|
||||||
|
|
||||||
|
|
@ -99,20 +99,32 @@ impl EuphVault {
|
||||||
let _ = self.vault.tx.send(request.into());
|
let _ = self.vault.tx.send(request.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_message(&self, msg: Message, prev_msg: Option<Snowflake>) {
|
pub fn add_message(
|
||||||
|
&self,
|
||||||
|
msg: Message,
|
||||||
|
prev_msg: Option<Snowflake>,
|
||||||
|
own_user_id: Option<UserId>,
|
||||||
|
) {
|
||||||
let request = EuphRequest::AddMsg {
|
let request = EuphRequest::AddMsg {
|
||||||
room: self.room.clone(),
|
room: self.room.clone(),
|
||||||
msg: Box::new(msg),
|
msg: Box::new(msg),
|
||||||
prev_msg,
|
prev_msg,
|
||||||
|
own_user_id,
|
||||||
};
|
};
|
||||||
let _ = self.vault.tx.send(request.into());
|
let _ = self.vault.tx.send(request.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_messages(&self, msgs: Vec<Message>, next_msg: Option<Snowflake>) {
|
pub fn add_messages(
|
||||||
|
&self,
|
||||||
|
msgs: Vec<Message>,
|
||||||
|
next_msg: Option<Snowflake>,
|
||||||
|
own_user_id: Option<UserId>,
|
||||||
|
) {
|
||||||
let request = EuphRequest::AddMsgs {
|
let request = EuphRequest::AddMsgs {
|
||||||
room: self.room.clone(),
|
room: self.room.clone(),
|
||||||
msgs,
|
msgs,
|
||||||
next_msg,
|
next_msg,
|
||||||
|
own_user_id,
|
||||||
};
|
};
|
||||||
let _ = self.vault.tx.send(request.into());
|
let _ = self.vault.tx.send(request.into());
|
||||||
}
|
}
|
||||||
|
|
@ -280,11 +292,13 @@ pub(super) enum EuphRequest {
|
||||||
room: String,
|
room: String,
|
||||||
msg: Box<Message>,
|
msg: Box<Message>,
|
||||||
prev_msg: Option<Snowflake>,
|
prev_msg: Option<Snowflake>,
|
||||||
|
own_user_id: Option<UserId>,
|
||||||
},
|
},
|
||||||
AddMsgs {
|
AddMsgs {
|
||||||
room: String,
|
room: String,
|
||||||
msgs: Vec<Message>,
|
msgs: Vec<Message>,
|
||||||
next_msg: Option<Snowflake>,
|
next_msg: Option<Snowflake>,
|
||||||
|
own_user_id: Option<UserId>,
|
||||||
},
|
},
|
||||||
GetLastSpan {
|
GetLastSpan {
|
||||||
room: String,
|
room: String,
|
||||||
|
|
@ -350,12 +364,14 @@ impl EuphRequest {
|
||||||
room,
|
room,
|
||||||
msg,
|
msg,
|
||||||
prev_msg,
|
prev_msg,
|
||||||
} => Self::add_msg(conn, room, *msg, prev_msg),
|
own_user_id,
|
||||||
|
} => Self::add_msg(conn, room, *msg, prev_msg, own_user_id),
|
||||||
EuphRequest::AddMsgs {
|
EuphRequest::AddMsgs {
|
||||||
room,
|
room,
|
||||||
msgs,
|
msgs,
|
||||||
next_msg,
|
next_msg,
|
||||||
} => Self::add_msgs(conn, room, msgs, next_msg),
|
own_user_id,
|
||||||
|
} => Self::add_msgs(conn, room, msgs, next_msg, own_user_id),
|
||||||
EuphRequest::GetLastSpan { room, result } => Self::get_last_span(conn, room, result),
|
EuphRequest::GetLastSpan { room, result } => Self::get_last_span(conn, room, result),
|
||||||
EuphRequest::GetPath { room, id, result } => Self::get_path(conn, room, id, result),
|
EuphRequest::GetPath { room, id, result } => Self::get_path(conn, room, id, result),
|
||||||
EuphRequest::GetTree { room, root, result } => Self::get_tree(conn, room, root, result),
|
EuphRequest::GetTree { room, root, result } => Self::get_tree(conn, room, root, result),
|
||||||
|
|
@ -494,16 +510,28 @@ impl EuphRequest {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_msgs(tx: &Transaction<'_>, room: &str, msgs: Vec<Message>) -> rusqlite::Result<()> {
|
fn insert_msgs(
|
||||||
|
tx: &Transaction<'_>,
|
||||||
|
room: &str,
|
||||||
|
own_user_id: &Option<UserId>,
|
||||||
|
msgs: Vec<Message>,
|
||||||
|
) -> rusqlite::Result<()> {
|
||||||
let mut insert_msg = tx.prepare(
|
let mut insert_msg = tx.prepare(
|
||||||
"
|
"
|
||||||
INSERT OR REPLACE INTO euph_msgs (
|
INSERT OR REPLACE INTO euph_msgs (
|
||||||
room, id, parent, previous_edit_id, time, content, encryption_key_id, edited, deleted, truncated,
|
room, id, parent, previous_edit_id, time, content, encryption_key_id, edited, deleted, truncated,
|
||||||
user_id, name, server_id, server_era, session_id, is_staff, is_manager, client_address, real_client_address
|
user_id, name, server_id, server_era, session_id, is_staff, is_manager, client_address, real_client_address,
|
||||||
|
seen
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
:room, :id, :parent, :previous_edit_id, :time, :content, :encryption_key_id, :edited, :deleted, :truncated,
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?
|
:user_id, :name, :server_id, :server_era, :session_id, :is_staff, :is_manager, :client_address, :real_client_address,
|
||||||
|
(:user_id == :own_user_id OR EXISTS(
|
||||||
|
SELECT 1
|
||||||
|
FROM euph_rooms
|
||||||
|
WHERE room = :room
|
||||||
|
AND :time < first_joined
|
||||||
|
))
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -528,28 +556,30 @@ impl EuphRequest {
|
||||||
",
|
",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let own_user_id = own_user_id.as_ref().map(|u| &u.0);
|
||||||
for msg in msgs {
|
for msg in msgs {
|
||||||
insert_msg.execute(params![
|
insert_msg.execute(named_params! {
|
||||||
room,
|
":room": room,
|
||||||
msg.id,
|
":id": msg.id,
|
||||||
msg.parent,
|
":parent": msg.parent,
|
||||||
msg.previous_edit_id,
|
":previous_edit_id": msg.previous_edit_id,
|
||||||
msg.time,
|
":time": msg.time,
|
||||||
msg.content,
|
":content": msg.content,
|
||||||
msg.encryption_key_id,
|
":encryption_key_id": msg.encryption_key_id,
|
||||||
msg.edited,
|
":edited": msg.edited,
|
||||||
msg.deleted,
|
":deleted": msg.deleted,
|
||||||
msg.truncated,
|
":truncated": msg.truncated,
|
||||||
msg.sender.id.0,
|
":user_id": msg.sender.id.0,
|
||||||
msg.sender.name,
|
":name": msg.sender.name,
|
||||||
msg.sender.server_id,
|
":server_id": msg.sender.server_id,
|
||||||
msg.sender.server_era,
|
":server_era": msg.sender.server_era,
|
||||||
msg.sender.session_id,
|
":session_id": msg.sender.session_id,
|
||||||
msg.sender.is_staff,
|
":is_staff": msg.sender.is_staff,
|
||||||
msg.sender.is_manager,
|
":is_manager": msg.sender.is_manager,
|
||||||
msg.sender.client_address,
|
":client_address": msg.sender.client_address,
|
||||||
msg.sender.real_client_address,
|
":real_client_address": msg.sender.real_client_address,
|
||||||
])?;
|
":own_user_id": own_user_id, // May be NULL
|
||||||
|
})?;
|
||||||
|
|
||||||
if let Some(parent) = msg.parent {
|
if let Some(parent) = msg.parent {
|
||||||
delete_trees.execute(params![room, msg.id])?;
|
delete_trees.execute(params![room, msg.id])?;
|
||||||
|
|
@ -641,11 +671,12 @@ impl EuphRequest {
|
||||||
room: String,
|
room: String,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
prev_msg: Option<Snowflake>,
|
prev_msg: Option<Snowflake>,
|
||||||
|
own_user_id: Option<UserId>,
|
||||||
) -> rusqlite::Result<()> {
|
) -> rusqlite::Result<()> {
|
||||||
let tx = conn.transaction()?;
|
let tx = conn.transaction()?;
|
||||||
|
|
||||||
let end = msg.id;
|
let end = msg.id;
|
||||||
Self::insert_msgs(&tx, &room, vec![msg])?;
|
Self::insert_msgs(&tx, &room, &own_user_id, vec![msg])?;
|
||||||
Self::add_span(&tx, &room, prev_msg, Some(end))?;
|
Self::add_span(&tx, &room, prev_msg, Some(end))?;
|
||||||
|
|
||||||
tx.commit()?;
|
tx.commit()?;
|
||||||
|
|
@ -657,6 +688,7 @@ impl EuphRequest {
|
||||||
room: String,
|
room: String,
|
||||||
msgs: Vec<Message>,
|
msgs: Vec<Message>,
|
||||||
next_msg_id: Option<Snowflake>,
|
next_msg_id: Option<Snowflake>,
|
||||||
|
own_user_id: Option<UserId>,
|
||||||
) -> rusqlite::Result<()> {
|
) -> rusqlite::Result<()> {
|
||||||
let tx = conn.transaction()?;
|
let tx = conn.transaction()?;
|
||||||
|
|
||||||
|
|
@ -666,7 +698,7 @@ impl EuphRequest {
|
||||||
let first_msg_id = msgs.first().unwrap().id;
|
let first_msg_id = msgs.first().unwrap().id;
|
||||||
let last_msg_id = msgs.last().unwrap().id;
|
let last_msg_id = msgs.last().unwrap().id;
|
||||||
|
|
||||||
Self::insert_msgs(&tx, &room, msgs)?;
|
Self::insert_msgs(&tx, &room, &own_user_id, msgs)?;
|
||||||
|
|
||||||
let end = next_msg_id.unwrap_or(last_msg_id);
|
let end = next_msg_id.unwrap_or(last_msg_id);
|
||||||
Self::add_span(&tx, &room, Some(first_msg_id), Some(end))?;
|
Self::add_span(&tx, &room, Some(first_msg_id), Some(end))?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue