client: Started working on ability to sync messages after last known message
This commit is contained in:
@@ -10,7 +10,7 @@ use async_trait::async_trait;
|
|||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
model::{Conversation, ConversationID, JwtToken, Message},
|
model::{Conversation, ConversationID, JwtToken, Message, MessageID},
|
||||||
APIInterface
|
APIInterface
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,8 +118,27 @@ impl<K: TokenStore + Send + Sync> APIInterface for HTTPAPIClient<K> {
|
|||||||
Ok(token)
|
Ok(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_messages(&mut self, conversation_id: &ConversationID) -> Result<Vec<Message>, Self::Error> {
|
async fn get_messages(
|
||||||
let endpoint = format!("messages?guid={}", conversation_id);
|
&mut self,
|
||||||
|
conversation_id: &ConversationID,
|
||||||
|
limit: Option<u32>,
|
||||||
|
before: Option<MessageID>,
|
||||||
|
after: Option<MessageID>,
|
||||||
|
) -> Result<Vec<Message>, Self::Error> {
|
||||||
|
let mut endpoint = format!("messages?guid={}", conversation_id);
|
||||||
|
|
||||||
|
if let Some(limit_val) = limit {
|
||||||
|
endpoint.push_str(&format!("&limit={}", limit_val));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(before_id) = before {
|
||||||
|
endpoint.push_str(&format!("&beforeMessageGUID={}", before_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(after_id) = after {
|
||||||
|
endpoint.push_str(&format!("&afterMessageGUID={}", after_id));
|
||||||
|
}
|
||||||
|
|
||||||
let messages: Vec<Message> = self.request(&endpoint, Method::GET).await?;
|
let messages: Vec<Message> = self.request(&endpoint, Method::GET).await?;
|
||||||
Ok(messages)
|
Ok(messages)
|
||||||
}
|
}
|
||||||
@@ -288,7 +307,7 @@ mod test {
|
|||||||
let mut client = local_mock_client();
|
let mut client = local_mock_client();
|
||||||
let conversations = client.get_conversations().await.unwrap();
|
let conversations = client.get_conversations().await.unwrap();
|
||||||
let conversation = conversations.first().unwrap();
|
let conversation = conversations.first().unwrap();
|
||||||
let messages = client.get_messages(&conversation.guid).await.unwrap();
|
let messages = client.get_messages(&conversation.guid, None, None, None).await.unwrap();
|
||||||
assert!(!messages.is_empty());
|
assert!(!messages.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
pub use crate::model::{
|
pub use crate::model::{
|
||||||
Conversation, Message, ConversationID
|
Conversation, Message, ConversationID, MessageID,
|
||||||
};
|
};
|
||||||
use crate::model::JwtToken;
|
use crate::model::JwtToken;
|
||||||
|
|
||||||
@@ -20,7 +20,13 @@ pub trait APIInterface {
|
|||||||
async fn get_conversations(&mut self) -> Result<Vec<Conversation>, Self::Error>;
|
async fn get_conversations(&mut self) -> Result<Vec<Conversation>, Self::Error>;
|
||||||
|
|
||||||
// (GET) /messages
|
// (GET) /messages
|
||||||
async fn get_messages(&mut self, conversation_id: &ConversationID) -> Result<Vec<Message>, Self::Error>;
|
async fn get_messages(
|
||||||
|
&mut self,
|
||||||
|
conversation_id: &ConversationID,
|
||||||
|
limit: Option<u32>,
|
||||||
|
before: Option<MessageID>,
|
||||||
|
after: Option<MessageID>,
|
||||||
|
) -> Result<Vec<Message>, Self::Error>;
|
||||||
|
|
||||||
// (POST) /authenticate
|
// (POST) /authenticate
|
||||||
async fn authenticate(&mut self, credentials: Credentials) -> Result<JwtToken, Self::Error>;
|
async fn authenticate(&mut self, credentials: Credentials) -> Result<JwtToken, Self::Error>;
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ use serde::Deserialize;
|
|||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::Identifiable;
|
||||||
|
|
||||||
|
pub type MessageID = <Message as Identifiable>::ID;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
pub guid: String,
|
pub guid: String,
|
||||||
@@ -22,6 +26,14 @@ impl Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Identifiable for Message {
|
||||||
|
type ID = String;
|
||||||
|
|
||||||
|
fn id(&self) -> &Self::ID {
|
||||||
|
&self.guid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct MessageBuilder {
|
pub struct MessageBuilder {
|
||||||
guid: Option<String>,
|
guid: Option<String>,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ pub use conversation::Conversation;
|
|||||||
pub use conversation::ConversationID;
|
pub use conversation::ConversationID;
|
||||||
|
|
||||||
pub use message::Message;
|
pub use message::Message;
|
||||||
|
pub use message::MessageID;
|
||||||
|
|
||||||
pub mod jwt;
|
pub mod jwt;
|
||||||
pub use jwt::JwtToken;
|
pub use jwt::JwtToken;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
|||||||
pub use crate::APIInterface;
|
pub use crate::APIInterface;
|
||||||
use crate::{
|
use crate::{
|
||||||
api::http_client::Credentials,
|
api::http_client::Credentials,
|
||||||
model::{Conversation, ConversationID, JwtToken, Message}
|
model::{Conversation, ConversationID, JwtToken, Message, MessageID}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TestClient {
|
pub struct TestClient {
|
||||||
@@ -44,7 +44,13 @@ impl APIInterface for TestClient {
|
|||||||
Ok(self.conversations.clone())
|
Ok(self.conversations.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_messages(&mut self, conversation_id: &ConversationID) -> Result<Vec<Message>, Self::Error> {
|
async fn get_messages(
|
||||||
|
&mut self,
|
||||||
|
conversation_id: &ConversationID,
|
||||||
|
limit: Option<u32>,
|
||||||
|
before: Option<MessageID>,
|
||||||
|
after: Option<MessageID>
|
||||||
|
) -> Result<Vec<Message>, Self::Error> {
|
||||||
if let Some(messages) = self.messages.get(conversation_id) {
|
if let Some(messages) = self.messages.get(conversation_id) {
|
||||||
return Ok(messages.clone())
|
return Ok(messages.clone())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ impl Daemon {
|
|||||||
|
|
||||||
// Fetch and sync messages for this conversation
|
// Fetch and sync messages for this conversation
|
||||||
log::debug!(target: target::SYNC, "Fetching messages for conversation {}", conversation_id);
|
log::debug!(target: target::SYNC, "Fetching messages for conversation {}", conversation_id);
|
||||||
let messages = client.get_messages(&conversation_id).await?;
|
let messages = client.get_messages(&conversation_id, None, None, None).await?;
|
||||||
let db_messages: Vec<kordophone_db::models::Message> = messages.into_iter()
|
let db_messages: Vec<kordophone_db::models::Message> = messages.into_iter()
|
||||||
.map(|m| kordophone_db::models::Message::from(m))
|
.map(|m| kordophone_db::models::Message::from(m))
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ impl ClientCli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn print_messages(&mut self, conversation_id: String) -> Result<()> {
|
pub async fn print_messages(&mut self, conversation_id: String) -> Result<()> {
|
||||||
let messages = self.api.get_messages(&conversation_id).await?;
|
let messages = self.api.get_messages(&conversation_id, None, None, None).await?;
|
||||||
for message in messages {
|
for message in messages {
|
||||||
println!("{}", MessagePrinter::new(&message.into()));
|
println!("{}", MessagePrinter::new(&message.into()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ impl DbClient {
|
|||||||
}).await?;
|
}).await?;
|
||||||
|
|
||||||
// Fetch and sync messages for this conversation
|
// Fetch and sync messages for this conversation
|
||||||
let messages = client.get_messages(&conversation_id).await?;
|
let messages = client.get_messages(&conversation_id, None, None, None).await?;
|
||||||
let db_messages: Vec<kordophone_db::models::Message> = messages.into_iter()
|
let db_messages: Vec<kordophone_db::models::Message> = messages.into_iter()
|
||||||
.map(|m| kordophone_db::models::Message::from(m))
|
.map(|m| kordophone_db::models::Message::from(m))
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
Reference in New Issue
Block a user