aboutsummaryrefslogtreecommitdiffstats
path: root/filamento
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--filamento/src/db.rs144
-rw-r--r--filamento/src/lib.rs21
-rw-r--r--filamento/src/logic/local_only.rs7
-rw-r--r--filamento/src/logic/offline.rs12
-rw-r--r--filamento/src/logic/online.rs7
5 files changed, 138 insertions, 53 deletions
diff --git a/filamento/src/db.rs b/filamento/src/db.rs
index 9d4b4e9..1b5afe6 100644
--- a/filamento/src/db.rs
+++ b/filamento/src/db.rs
@@ -344,6 +344,14 @@ impl Db {
result
}
+ pub(crate) async fn read_chat_and_user(&self, chat: JID) -> Result<(Chat, User), Error> {
+ let (result, recv) = oneshot::channel();
+ let command = DbCommand::ReadChatAndUser { chat, result };
+ self.sender.send(command);
+ let result = recv.await?;
+ result
+ }
+
pub(crate) async fn mark_chat_as_chatted(&self, chat: JID) -> Result<(), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::MarkChatAsChatted { chat, result };
@@ -605,6 +613,10 @@ pub enum DbCommand {
chat: JID,
result: oneshot::Sender<Result<Chat, Error>>,
},
+ ReadChatAndUser {
+ chat: JID,
+ result: oneshot::Sender<Result<(Chat, User), Error>>,
+ },
MarkChatAsChatted {
chat: JID,
result: oneshot::Sender<Result<(), Error>>,
@@ -700,45 +712,46 @@ impl Display for DbCommand {
#[rustfmt::skip]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
- DbCommand::CreateUser { user, result } => "CreateUser",
- DbCommand::ReadUser { user, result } => "ReadUser",
- DbCommand::DeleteUserNick { jid, result } => "DeleteUserNick",
- DbCommand::UpsertUserNick { jid, nick, result } => "UpsertUserNick",
- DbCommand::DeleteUserAvatar { jid, result } => "DeleteUserAvatar",
- DbCommand::UpsertUserAvatar { jid, avatar, result } => "UpsertUserAvatar",
- DbCommand::UpdateUser { user, result } => "UpdateUser",
- DbCommand::CreateContact { contact, result } => "CreateContact",
- DbCommand::ReadContact { contact, result } => "ReadContact",
- DbCommand::ReadContactOpt { contact, result } => "ReadContactOpt",
- DbCommand::UpdateContact { contact, result } => "UpdateContact",
- DbCommand::UpsertContact { contact, result } => "UpsertContact",
- DbCommand::DeleteContact { contact, result } => "DeleteContact",
- DbCommand::ReplaceCachedRoster { roster, result } => "ReplaceCachedRoster",
- DbCommand::ReadCachedRoster { result } => "ReadCachedRoster",
- DbCommand::ReadCachedRosterWithUsers { result } => "ReadCachedRosterWithUsers",
- DbCommand::CreateChat { chat, result } => "CreateChat",
- DbCommand::ReadChat { chat, result } => "ReadChat",
- DbCommand::MarkChatAsChatted { chat, result } => "MarkChatAsChatted",
- DbCommand::UpdateChatCorrespondent { old_chat, new_correspondent, result } => "UpdateChatCorrespondent",
- DbCommand::DeleteChat { chat, result } => "DeleteChat",
- DbCommand::ReadChats { result } => "ReadChats",
- DbCommand::ReadChatsOrdered { result } => "ReadChatsOrdered",
- DbCommand::ReadChatsOrderedWithLatestMessages { result } => "ReadChatsOrderedWithLatestMessages",
- DbCommand::ReadChatsOrderedWithLatestMessagesAndUsers { result } => "ReadChatsOrderedWithLatestMessagesAndUsers",
- DbCommand::CreateMessage { message, chat, from, result } => "CreateMessage",
- DbCommand::UpsertChatAndUser { chat, result } => "UpsertChatAndUser",
- DbCommand::CreateMessageWithUserResource { message, chat, from, result } => "CreateMessageWithUserResource",
- DbCommand::UpdateMessageDelivery { message, delivery, result } => "UpdateMessageDelivery",
- DbCommand::DeleteMessage { message, result } => "DeleteMessage",
- DbCommand::ReadMessage { message, result } => "ReadMessage",
- DbCommand::ReadMessageHistory { chat, result } => "ReadMessageHistory",
- DbCommand::ReadMessageHistoryWithUsers { chat, result } => "ReadMessageHistoryWithUsers",
- DbCommand::ReadCachedStatus { result } => "ReadCachedStatus",
- DbCommand::UpsertCachedStatus { status, result } => "UpsertCachedStatus",
- DbCommand::DeleteCachedStatus { result } => "DeleteCachedStatus",
- DbCommand::ReadCapabilities { node, result } => "ReadCapabilities",
- DbCommand::UpsertCapabilities { node, capabilities, result } => "UpsertCapabilities",
- })
+ DbCommand::CreateUser { user, result } => "CreateUser",
+ DbCommand::ReadUser { user, result } => "ReadUser",
+ DbCommand::DeleteUserNick { jid, result } => "DeleteUserNick",
+ DbCommand::UpsertUserNick { jid, nick, result } => "UpsertUserNick",
+ DbCommand::DeleteUserAvatar { jid, result } => "DeleteUserAvatar",
+ DbCommand::UpsertUserAvatar { jid, avatar, result } => "UpsertUserAvatar",
+ DbCommand::UpdateUser { user, result } => "UpdateUser",
+ DbCommand::CreateContact { contact, result } => "CreateContact",
+ DbCommand::ReadContact { contact, result } => "ReadContact",
+ DbCommand::ReadContactOpt { contact, result } => "ReadContactOpt",
+ DbCommand::UpdateContact { contact, result } => "UpdateContact",
+ DbCommand::UpsertContact { contact, result } => "UpsertContact",
+ DbCommand::DeleteContact { contact, result } => "DeleteContact",
+ DbCommand::ReplaceCachedRoster { roster, result } => "ReplaceCachedRoster",
+ DbCommand::ReadCachedRoster { result } => "ReadCachedRoster",
+ DbCommand::ReadCachedRosterWithUsers { result } => "ReadCachedRosterWithUsers",
+ DbCommand::CreateChat { chat, result } => "CreateChat",
+ DbCommand::ReadChat { chat, result } => "ReadChat",
+ DbCommand::MarkChatAsChatted { chat, result } => "MarkChatAsChatted",
+ DbCommand::UpdateChatCorrespondent { old_chat, new_correspondent, result } => "UpdateChatCorrespondent",
+ DbCommand::DeleteChat { chat, result } => "DeleteChat",
+ DbCommand::ReadChats { result } => "ReadChats",
+ DbCommand::ReadChatsOrdered { result } => "ReadChatsOrdered",
+ DbCommand::ReadChatsOrderedWithLatestMessages { result } => "ReadChatsOrderedWithLatestMessages",
+ DbCommand::ReadChatsOrderedWithLatestMessagesAndUsers { result } => "ReadChatsOrderedWithLatestMessagesAndUsers",
+ DbCommand::CreateMessage { message, chat, from, result } => "CreateMessage",
+ DbCommand::UpsertChatAndUser { chat, result } => "UpsertChatAndUser",
+ DbCommand::CreateMessageWithUserResource { message, chat, from, result } => "CreateMessageWithUserResource",
+ DbCommand::UpdateMessageDelivery { message, delivery, result } => "UpdateMessageDelivery",
+ DbCommand::DeleteMessage { message, result } => "DeleteMessage",
+ DbCommand::ReadMessage { message, result } => "ReadMessage",
+ DbCommand::ReadMessageHistory { chat, result } => "ReadMessageHistory",
+ DbCommand::ReadMessageHistoryWithUsers { chat, result } => "ReadMessageHistoryWithUsers",
+ DbCommand::ReadCachedStatus { result } => "ReadCachedStatus",
+ DbCommand::UpsertCachedStatus { status, result } => "UpsertCachedStatus",
+ DbCommand::DeleteCachedStatus { result } => "DeleteCachedStatus",
+ DbCommand::ReadCapabilities { node, result } => "ReadCapabilities",
+ DbCommand::UpsertCapabilities { node, capabilities, result } => "UpsertCapabilities",
+ DbCommand::ReadChatAndUser { chat, result } => "ReadChatAndUser",
+ })
}
}
@@ -863,6 +876,9 @@ impl DbActor {
DbCommand::ReadChat { chat, result } => {
result.send(self.read_chat(chat));
}
+ DbCommand::ReadChatAndUser { chat, result } => {
+ result.send(self.read_chat_and_user(chat));
+ }
DbCommand::MarkChatAsChatted { chat, result } => {
result.send(self.mark_chat_as_chatted(chat));
}
@@ -1272,8 +1288,10 @@ impl DbActor {
// TODO: what happens if a correspondent changes from a user to a contact? maybe just have correspondent be a user, then have the client make the user show up as a contact in ui if they are in the loaded roster.
+ /// should be a bare jid
+ /// TODO: this is NOT a read
pub(crate) fn read_chat(&self, chat: JID) -> Result<Chat, Error> {
- let chat = self.db.query_row(
+ let chat_opt = self.db.query_row(
"select correspondent, have_chatted from chats where correspondent = ?1",
[&chat],
|row| {
@@ -1282,8 +1300,50 @@ impl DbActor {
have_chatted: row.get(1)?,
})
},
- )?;
- Ok(chat)
+ ).optional()?;
+ match chat_opt {
+ Some(chat) => return Ok(chat),
+ None => {
+ let chat = Chat {
+ correspondent: chat,
+ have_chatted: false,
+ };
+ self.create_chat(chat.clone())?;
+ Ok(chat)
+ }
+ }
+ }
+
+ pub(crate) fn read_chat_and_user(&self, chat: JID) -> Result<(Chat, User), Error> {
+ let user = self.read_user(chat.clone())?;
+ let chat_opt = self.db.query_row(
+ "select correspondent, have_chatted, jid, nick, avatar from chats join users on correspondent = jid where correspondent = ?1",
+ [&chat],
+ |row| {
+ Ok((
+ Chat {
+ correspondent: row.get(0)?,
+ have_chatted: row.get(1)?,
+ },
+ User {
+ jid: row.get(2)?,
+ nick: row.get(3)?,
+ avatar: row.get(4)?,
+ }
+ ))
+ },
+ ).optional()?;
+ match chat_opt {
+ Some(chat) => return Ok(chat),
+ None => {
+ let chat = Chat {
+ correspondent: chat,
+ have_chatted: false,
+ };
+ self.create_chat(chat.clone())?;
+ Ok((chat, user))
+ }
+ }
}
pub(crate) fn mark_chat_as_chatted(&self, chat: JID) -> Result<(), Error> {
diff --git a/filamento/src/lib.rs b/filamento/src/lib.rs
index 8b27441..068bfe8 100644
--- a/filamento/src/lib.rs
+++ b/filamento/src/lib.rs
@@ -69,6 +69,8 @@ pub enum Command<Fs: FileStore> {
),
/// get a specific chat by jid
GetChat(JID, oneshot::Sender<Result<Chat, DatabaseError>>),
+ /// get a specific chat and user by jid
+ GetChatAndUser(JID, oneshot::Sender<Result<(Chat, User), DatabaseError>>),
/// get message history for chat (does appropriate mam things)
GetMessage(Uuid, oneshot::Sender<Result<Message, DatabaseError>>),
// TODO: paging and filtering
@@ -269,8 +271,9 @@ impl<Fs: FileStore + Clone + Send + Sync + 'static> Client<Fs> {
}
impl<Fs: FileStore> Client<Fs> {
- pub async fn connect(&self) -> Result<(), CommandError<ConnectionError>> {
- let (send, recv) = oneshot::channel::<Result<(), ConnectionError>>();
+ /// returns the resource
+ pub async fn connect(&self) -> Result<String, CommandError<ConnectionError>> {
+ let (send, recv) = oneshot::channel::<Result<String, ConnectionError>>();
self.send(CoreClientCommand::Connect(send))
.await
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
@@ -278,7 +281,7 @@ impl<Fs: FileStore> Client<Fs> {
.await
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
- Ok(())
+ Ok(result)
}
pub async fn disconnect(&self, offline: Offline) -> Result<(), ActorError> {
@@ -382,6 +385,18 @@ impl<Fs: FileStore> Client<Fs> {
Ok(chat)
}
+ pub async fn get_chat_and_user(&self, jid: JID) -> Result<(Chat, User), CommandError<DatabaseError>> {
+ let (send, recv) = oneshot::channel();
+ self.send(CoreClientCommand::Command(Command::GetChatAndUser(jid, send)))
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
+ let result= timeout(self.timeout, recv)
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
+ Ok(result)
+ }
+
pub async fn get_message(&self, id: Uuid) -> Result<Message, CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::GetMessage(id, send)))
diff --git a/filamento/src/logic/local_only.rs b/filamento/src/logic/local_only.rs
index a22efbd..f5705f4 100644
--- a/filamento/src/logic/local_only.rs
+++ b/filamento/src/logic/local_only.rs
@@ -44,6 +44,13 @@ pub async fn handle_get_chat<Fs: FileStore + Clone>(
Ok(logic.db().read_chat(jid).await?)
}
+pub async fn handle_get_chat_and_user<Fs: FileStore + Clone>(
+ logic: &ClientLogic<Fs>,
+ jid: JID,
+) -> Result<(Chat, User), DatabaseError> {
+ Ok(logic.db().read_chat_and_user(jid).await?)
+}
+
pub async fn handle_get_message<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
id: Uuid,
diff --git a/filamento/src/logic/offline.rs b/filamento/src/logic/offline.rs
index 42a38ca..606b04f 100644
--- a/filamento/src/logic/offline.rs
+++ b/filamento/src/logic/offline.rs
@@ -19,13 +19,9 @@ use crate::{
};
use super::{
- ClientLogic,
local_only::{
- handle_delete_chat, handle_delete_messaage, handle_get_chat, handle_get_chats,
- handle_get_chats_ordered, handle_get_chats_ordered_with_latest_messages,
- handle_get_chats_ordered_with_latest_messages_and_users, handle_get_message,
- handle_get_messages, handle_get_messages_with_users, handle_get_user,
- },
+ handle_delete_chat, handle_delete_messaage, handle_get_chat, handle_get_chat_and_user, handle_get_chats, handle_get_chats_ordered, handle_get_chats_ordered_with_latest_messages, handle_get_chats_ordered_with_latest_messages_and_users, handle_get_message, handle_get_messages, handle_get_messages_with_users, handle_get_user
+ }, ClientLogic
};
pub async fn handle_offline<Fs: FileStore + Clone>(logic: ClientLogic<Fs>, command: Command<Fs>) {
@@ -89,6 +85,10 @@ pub async fn handle_offline_result<Fs: FileStore + Clone>(
let chats = handle_get_chat(logic, jid).await;
sender.send(chats);
}
+ Command::GetChatAndUser(jid, sender) => {
+ let chat = handle_get_chat_and_user(logic, jid).await;
+ let _ = sender.send(chat);
+ }
Command::GetMessage(id, sender) => {
let message = handle_get_message(logic, id).await;
let _ = sender.send(message);
diff --git a/filamento/src/logic/online.rs b/filamento/src/logic/online.rs
index 969e08a..9814ff2 100644
--- a/filamento/src/logic/online.rs
+++ b/filamento/src/logic/online.rs
@@ -23,8 +23,7 @@ use crate::{
use super::{
local_only::{
- handle_get_message,
- handle_delete_chat, handle_delete_messaage, handle_get_chat, handle_get_chats, handle_get_chats_ordered, handle_get_chats_ordered_with_latest_messages, handle_get_chats_ordered_with_latest_messages_and_users, handle_get_messages, handle_get_messages_with_users, handle_get_user
+ handle_delete_chat, handle_delete_messaage, handle_get_chat, handle_get_chat_and_user, handle_get_chats, handle_get_chats_ordered, handle_get_chats_ordered_with_latest_messages, handle_get_chats_ordered_with_latest_messages_and_users, handle_get_message, handle_get_messages, handle_get_messages_with_users, handle_get_user
}, ClientLogic
};
@@ -1111,6 +1110,10 @@ pub async fn handle_online_result<Fs: FileStore + Clone>(
let chat = handle_get_chat(logic, jid).await;
let _ = sender.send(chat);
}
+ Command::GetChatAndUser(jid, sender) => {
+ let chat = handle_get_chat_and_user(logic, jid).await;
+ let _ = sender.send(chat);
+ }
Command::GetMessage(id, sender) => {
let message = handle_get_message(logic, id).await;
let _ = sender.send(message);