137 lines
4.1 KiB
Rust
137 lines
4.1 KiB
Rust
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|
|
|
use async_trait::async_trait;
|
|
use tracing::{error, instrument, trace};
|
|
|
|
use super::{
|
|
common::PresenceState,
|
|
messaging_interface::{
|
|
AccountMessagingConsumerInterface, AccountMessagingProviderInterface,
|
|
RoomMessagingConsumerInterface, SpaceMessagingConsumerInterface,
|
|
},
|
|
room::{Room, RoomId},
|
|
space::{Space, SpaceId},
|
|
store_interface::{
|
|
AccountStoreProviderInterface, RoomStoreConsumerInterface, SpaceStoreConsumerInterface,
|
|
},
|
|
};
|
|
|
|
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());
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
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 {
|
|
#[instrument(name = "Account", skip_all)]
|
|
async fn on_new_room(&self, room: Rc<Room>) -> Rc<dyn RoomMessagingConsumerInterface> {
|
|
trace!("on_new_room");
|
|
|
|
let room_id = room.id().clone();
|
|
|
|
self.by_id_rooms
|
|
.borrow_mut()
|
|
.insert(room_id, Rc::clone(&room));
|
|
|
|
let room_store = self
|
|
.store
|
|
.on_new_room(Rc::clone(&room) as Rc<dyn RoomStoreConsumerInterface>);
|
|
|
|
room.set_store(room_store);
|
|
|
|
room
|
|
}
|
|
|
|
#[instrument(name = "Account", skip_all)]
|
|
async fn on_new_space(&self, space: Rc<Space>) -> Rc<dyn SpaceMessagingConsumerInterface> {
|
|
trace!("on_new_space");
|
|
|
|
let space_id = space.id().clone();
|
|
|
|
self.by_id_spaces
|
|
.borrow_mut()
|
|
.insert(space_id, Rc::clone(&space));
|
|
|
|
let space_store = self
|
|
.store
|
|
.on_new_space(Rc::clone(&space) as Rc<dyn SpaceStoreConsumerInterface>);
|
|
|
|
space.set_store(space_store);
|
|
|
|
space
|
|
}
|
|
}
|