🚧 Add Account identity and messaging and store interfaces

This commit is contained in:
2024-05-10 18:05:25 +02:00
parent 0a0d6e745b
commit 79e8dea622
6 changed files with 230 additions and 0 deletions

127
src/domain/model/account.rs Normal file
View File

@@ -0,0 +1,127 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use async_trait::async_trait;
use tracing::error;
use super::{
common::PresenceState,
messaging_interface::{
AccountMessagingConsumerInterface, AccountMessagingProviderInterface,
RoomMessagingConsumerInterface, SpaceMessagingConsumerInterface,
},
room::{Room, RoomId},
space::{Space, SpaceId},
store_interface::AccountStoreProviderInterface,
};
type Rooms = HashMap<RoomId, Rc<Room>>;
type Spaces = HashMap<SpaceId, Rc<Space>>;
pub struct Account {
display_name: RefCell<Option<String>>,
avatar: RefCell<Option<Vec<u8>>>,
#[allow(dead_code)]
presence_state: RefCell<Option<PresenceState>>,
by_id_rooms: RefCell<Rooms>,
by_id_spaces: RefCell<Spaces>,
messaging_provider: Option<Rc<dyn AccountMessagingProviderInterface>>,
store: &'static dyn AccountStoreProviderInterface,
}
impl Account {
pub fn new(store: &'static dyn AccountStoreProviderInterface) -> Self {
Self {
display_name: RefCell::new(None),
avatar: RefCell::new(None),
presence_state: RefCell::new(None),
by_id_rooms: RefCell::new(Rooms::new()),
by_id_spaces: RefCell::new(Spaces::new()),
messaging_provider: None,
store,
}
}
pub fn set_messaging_provider(&mut self, provider: Rc<dyn AccountMessagingProviderInterface>) {
self.messaging_provider = Some(provider.clone());
}
pub fn get_room(&self, room_id: &RoomId) -> Option<Rc<Room>> {
self.by_id_rooms.borrow().get(room_id).cloned()
}
pub async fn get_display_name(&self) -> &RefCell<Option<String>> {
if self.display_name.borrow().is_none() {
if let Some(requester) = &self.messaging_provider {
let resp = requester.get_display_name().await;
if let Ok(display_name) = resp {
if let Some(display_name) = display_name {
self.display_name.borrow_mut().replace(display_name);
} else {
self.display_name.borrow_mut().take();
}
} else {
error!("err={:?}", resp);
}
}
}
&self.display_name
}
pub async fn get_avatar(&self) -> &RefCell<Option<Vec<u8>>> {
if self.avatar.borrow().is_none() {
if let Some(requester) = &self.messaging_provider {
let resp = requester.get_avatar().await;
if let Ok(avatar) = resp {
if let Some(avatar) = avatar {
self.avatar.borrow_mut().replace(avatar);
} else {
self.avatar.borrow_mut().take();
}
} else {
error!("err={:?}", resp);
}
}
}
&self.avatar
}
}
#[async_trait(?Send)]
impl AccountMessagingConsumerInterface for Account {
async fn on_new_room(&self, room: Room) -> Rc<dyn RoomMessagingConsumerInterface> {
let room_id = room.id().clone();
let room = Rc::new(room);
self.by_id_rooms
.borrow_mut()
.insert(room_id, Rc::clone(&room));
let room_store = Box::new(self.store.on_new_room(Rc::clone(&room)));
room.set_store(Some(room_store));
room
}
async fn on_new_space(&self, space: Space) -> Rc<dyn SpaceMessagingConsumerInterface> {
let space_id = space.id().clone();
let space = Rc::new(space);
self.by_id_spaces
.borrow_mut()
.insert(space_id, Rc::clone(&space));
let space_store = Box::new(self.store.on_new_space(Rc::clone(&space)));
space.set_store(Some(space_store));
space
}
}

View File

@@ -0,0 +1,7 @@
use matrix_sdk::ruma::{presence::PresenceState as MatrixPresenceState, OwnedUserId};
pub type Avatar = Vec<u8>;
pub type PresenceState = MatrixPresenceState;
pub type UserId = OwnedUserId;

View File

@@ -0,0 +1,68 @@
use std::rc::Rc;
use async_trait::async_trait;
use tokio::sync::broadcast::Receiver;
use crate::infrastructure::messaging::matrix::worker_tasks::AccountEvent;
use super::{
common::{Avatar, UserId},
room::{Room, RoomId},
room_member::RoomMember,
space::Space,
};
#[async_trait(?Send)]
pub trait AccountMessagingConsumerInterface {
async fn on_new_room(&self, room: Room) -> Rc<dyn RoomMessagingConsumerInterface>;
async fn on_new_space(&self, space: Space) -> Rc<dyn SpaceMessagingConsumerInterface>;
}
#[async_trait(?Send)]
pub trait AccountMessagingProviderInterface {
async fn get_display_name(&self) -> anyhow::Result<Option<String>>;
async fn get_avatar(&self) -> anyhow::Result<Option<Vec<u8>>>;
async fn run_forever(
&self,
account_events_consumer: &dyn AccountMessagingConsumerInterface,
account_events_receiver: Receiver<AccountEvent>,
) -> anyhow::Result<()>;
}
#[async_trait(?Send)]
pub trait RoomMessagingConsumerInterface {
async fn on_invitation(&self) {}
async fn on_new_topic(&self, _topic: Option<String>) {}
async fn on_new_name(&self, _name: Option<String>) {}
#[allow(dead_code)]
async fn on_membership(&self, _member: RoomMember) {}
}
#[async_trait(?Send)]
pub trait RoomMessagingProviderInterface {
async fn get_avatar(&self, id: &RoomId) -> anyhow::Result<Option<Avatar>>;
async fn get_members(&self, id: &RoomId) -> anyhow::Result<Vec<RoomMember>>;
}
#[async_trait(?Send)]
pub trait SpaceMessagingConsumerInterface {
async fn on_child(&self, _room_id: RoomId) {}
async fn on_new_topic(&self, _topic: Option<String>) {}
async fn on_new_name(&self, _name: Option<String>) {}
}
#[async_trait(?Send)]
pub trait SpaceMessagingProviderInterface {}
// TODO: Rework
#[async_trait(?Send)]
pub trait MemberMessagingProviderInterface {
async fn get_avatar(
&self,
room_id: &RoomId,
user_id: &UserId,
) -> anyhow::Result<Option<Avatar>>;
}

View File

@@ -1,2 +1,6 @@
pub(crate) mod account;
pub(crate) mod common;
pub(crate) mod messaging_interface;
pub(crate) mod room;
pub(crate) mod session;
pub(crate) mod store_interface;

View File

@@ -0,0 +1,23 @@
use std::rc::Rc;
use super::room::Room;
use super::space::Space;
use crate::base::{StoreRoom, StoreSpace};
#[allow(dead_code)]
pub trait AccountStoreConsumerInterface {}
pub trait AccountStoreProviderInterface {
fn on_new_room(&self, room: Rc<Room>) -> StoreRoom;
fn on_new_space(&self, space: Rc<Space>) -> StoreSpace;
}
#[allow(dead_code)]
pub trait RoomStoreConsumerInterface {}
pub trait RoomStoreProviderInterface {}
#[allow(dead_code)]
pub trait SpaceStoreConsumerInterface {}
pub trait SpaceStoreProviderInterface {
fn set_name(&mut self, _name: Option<String>) {}
}