♻️ Add Account, Room and Space UI store structs
This commit is contained in:
@@ -12,6 +12,8 @@ web = ["dioxus/web"]
|
|||||||
dioxus = "0.5.*"
|
dioxus = "0.5.*"
|
||||||
dioxus-sdk = { version = "0.5.*", features = ["utils"] }
|
dioxus-sdk = { version = "0.5.*", features = ["utils"] }
|
||||||
dioxus-free-icons = { version = "0.8.*", features = ["ionicons", "font-awesome-solid", "material-design-icons-navigation"] }
|
dioxus-free-icons = { version = "0.8.*", features = ["ionicons", "font-awesome-solid", "material-design-icons-navigation"] }
|
||||||
|
# modx = "0.1"
|
||||||
|
modx = { git = "https://github.com/ASR-ASU/modx.git", branch = "asr/fix-props-visibility" }
|
||||||
|
|
||||||
# matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk.git", branch = "main", default-features = false, features = ["js", "rustls-tls"] }
|
# matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk.git", branch = "main", default-features = false, features = ["js", "rustls-tls"] }
|
||||||
matrix-sdk = { version = "0.7.*", default-features = false, features = ["js", "rustls-tls"] }
|
matrix-sdk = { version = "0.7.*", default-features = false, features = ["js", "rustls-tls"] }
|
||||||
|
183
src/base.rs
183
src/base.rs
@@ -1,185 +1,60 @@
|
|||||||
// Cf. https://dioxuslabs.com/learn/0.4/reference/use_coroutine
|
use std::rc::Rc;
|
||||||
// In order to use/run the rx.next().await statement you will need to extend the [Stream] trait
|
|
||||||
// (used by [UnboundedReceiver]) by adding 'futures_util' as a dependency to your project
|
|
||||||
// and adding the use futures_util::stream::StreamExt;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use futures_util::stream::StreamExt;
|
use futures_util::stream::StreamExt;
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use matrix_sdk::ruma::OwnedRoomId;
|
|
||||||
use tokio::select;
|
|
||||||
|
|
||||||
use crate::domain::model::room::{ByIdRooms, Room};
|
use crate::domain::model::account::Account;
|
||||||
|
use crate::domain::model::messaging_interface::AccountMessagingProviderInterface;
|
||||||
use crate::domain::model::session::Session;
|
use crate::domain::model::session::Session;
|
||||||
use crate::infrastructure::messaging::matrix::client::{Client, RoomEvent};
|
use crate::infrastructure::messaging::matrix::client::Client;
|
||||||
use crate::infrastructure::messaging::matrix::requester::{Receivers, Requester};
|
|
||||||
use crate::infrastructure::messaging::matrix::worker_tasks::LoginStyle;
|
use crate::infrastructure::messaging::matrix::worker_tasks::LoginStyle;
|
||||||
use crate::ui::components::chats_window::interface::Interface as ChatsWinInterface;
|
use crate::ui::store::Store;
|
||||||
|
|
||||||
// #[derive(Clone, Debug)]
|
pub async fn login(mut rx: UnboundedReceiver<bool>, session: &GlobalSignal<Session>) {
|
||||||
// pub struct UserInfo {
|
|
||||||
// pub avatar_url: Option<OwnedMxcUri>,
|
|
||||||
// pub display_name: Option<String>,
|
|
||||||
// pub blurhash: Option<String>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl UserInfo {
|
|
||||||
// pub fn new(
|
|
||||||
// avatar_url: Option<OwnedMxcUri>,
|
|
||||||
// display_name: Option<String>,
|
|
||||||
// blurhash: Option<String>,
|
|
||||||
// ) -> Self {
|
|
||||||
// Self {
|
|
||||||
// avatar_url,
|
|
||||||
// display_name,
|
|
||||||
// blurhash,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub type ByIdUserInfos = HashMap<OwnedUserId, UserInfo>;
|
|
||||||
|
|
||||||
// #[derive(Clone)]
|
|
||||||
// pub struct Store {
|
|
||||||
// pub is_logged: bool,
|
|
||||||
// pub rooms: ByIdRooms,
|
|
||||||
// pub user_infos: ByIdUserInfos,
|
|
||||||
// pub user_id: Option<OwnedUserId>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Store {
|
|
||||||
// pub fn new() -> Self {
|
|
||||||
// Self {
|
|
||||||
// is_logged: false,
|
|
||||||
// rooms: HashMap::new(),
|
|
||||||
// user_infos: HashMap::new(),
|
|
||||||
// user_id: None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl PartialEq for Store {
|
|
||||||
// fn eq(&self, other: &Self) -> bool {
|
|
||||||
// self.is_logged == other.is_logged
|
|
||||||
// && self.user_id == other.user_id
|
|
||||||
// && self.user_infos.len() == other.user_infos.len()
|
|
||||||
// && self
|
|
||||||
// .user_infos
|
|
||||||
// .keys()
|
|
||||||
// .all(|k| other.user_infos.contains_key(k))
|
|
||||||
// && self.rooms.len() == other.rooms.len()
|
|
||||||
// && self.rooms.keys().all(|k| other.rooms.contains_key(k))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Eq for Store {}
|
|
||||||
|
|
||||||
pub struct AppSettings {
|
|
||||||
pub requester: Option<RefCell<Requester>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AppSettings {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self { requester: None }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_requester(&mut self, requester: RefCell<Requester>) {
|
|
||||||
self.requester = Some(requester);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn on_room(room_id: OwnedRoomId, room: Room, by_id_rooms: &GlobalSignal<ByIdRooms>) {
|
|
||||||
// TODO: Update rooms
|
|
||||||
by_id_rooms
|
|
||||||
.write()
|
|
||||||
.insert(room_id, RefCell::<Room>::new(room));
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn on_joining_invitation(
|
|
||||||
room_id: OwnedRoomId,
|
|
||||||
room: Room,
|
|
||||||
by_id_rooms: &GlobalSignal<ByIdRooms>,
|
|
||||||
) {
|
|
||||||
debug!("You're invited to join the \"{}\" room", room.id());
|
|
||||||
// TODO: Update rooms
|
|
||||||
by_id_rooms
|
|
||||||
.write()
|
|
||||||
.insert(room_id, RefCell::<Room>::new(room));
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn on_room_topic(room_id: OwnedRoomId, topic: String, by_id_rooms: &GlobalSignal<ByIdRooms>) {
|
|
||||||
if let Some(room) = by_id_rooms.read().get(&room_id) {
|
|
||||||
let mut room = room.borrow_mut();
|
|
||||||
room.set_topic(Some(topic));
|
|
||||||
} else {
|
|
||||||
warn!("No room found with the \"{}\" id", room_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn sync_messages(by_id_rooms: &GlobalSignal<ByIdRooms>, room_id: OwnedRoomId) {
|
|
||||||
error!("== sync_messages ==");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn sync_rooms(
|
|
||||||
mut rx: UnboundedReceiver<bool>,
|
|
||||||
receivers: Receivers,
|
|
||||||
by_id_rooms: &GlobalSignal<ByIdRooms>,
|
|
||||||
) {
|
|
||||||
if let Some(_is_logged) = rx.next().await {
|
|
||||||
let mut rooms_receiver = receivers.room_receiver.borrow_mut();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
// TODO: Remove select if no more receivers will be used.
|
|
||||||
select! {
|
|
||||||
res = rooms_receiver.recv() => {
|
|
||||||
if let Ok(room_event) = res {
|
|
||||||
match room_event {
|
|
||||||
RoomEvent::MemberEvent(room_id, room) => on_room(room_id, room, &by_id_rooms).await,
|
|
||||||
RoomEvent::InviteEvent(room_id, room) => on_joining_invitation(room_id, room, &by_id_rooms).await,
|
|
||||||
RoomEvent::TopicEvent(room_id, topic) => on_room_topic(room_id, topic, &by_id_rooms).await,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn login(
|
|
||||||
mut rx: UnboundedReceiver<bool>,
|
|
||||||
app_settings: &GlobalSignal<AppSettings>,
|
|
||||||
session: &GlobalSignal<Session>,
|
|
||||||
) {
|
|
||||||
while let Some(is_logged) = rx.next().await {
|
while let Some(is_logged) = rx.next().await {
|
||||||
|
error!("is_logged={is_logged}");
|
||||||
if !is_logged {
|
if !is_logged {
|
||||||
let homeserver_url = session.read().homeserver_url.clone();
|
let homeserver_url = session.read().homeserver_url.clone();
|
||||||
let username = session.read().username.clone();
|
let username = session.read().username.clone();
|
||||||
let password = session.read().password.clone();
|
let password = session.read().password.clone();
|
||||||
|
|
||||||
if homeserver_url.is_some() && username.is_some() && password.is_some() {
|
if homeserver_url.is_some() && username.is_some() && password.is_some() {
|
||||||
let client = Client::spawn(homeserver_url.unwrap()).await;
|
let (requester, account_events_receiver) =
|
||||||
|
Client::spawn(homeserver_url.unwrap()).await;
|
||||||
|
|
||||||
if let Err(err) = client.init().await {
|
if let Err(err) = requester.init().await {
|
||||||
error!("Following error occureds during client init: {}", err);
|
error!("Following error occureds during client init: {}", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
match client
|
error!("Before login");
|
||||||
|
|
||||||
|
match requester
|
||||||
.login(LoginStyle::Password(username.unwrap(), password.unwrap()))
|
.login(LoginStyle::Password(username.unwrap(), password.unwrap()))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
debug!("successfully logged");
|
debug!("successfully logged");
|
||||||
session.write().is_logged = true;
|
session.write().is_logged = true;
|
||||||
|
|
||||||
|
let requester = Rc::new(requester);
|
||||||
|
|
||||||
|
dioxus::prelude::spawn(async move {
|
||||||
|
// ACCOUNT.write().set_messaging_provider(requester.clone());
|
||||||
|
ACCOUNT.write().set_messaging_provider(requester.clone());
|
||||||
|
|
||||||
|
let _ = requester
|
||||||
|
.run_forever(&*ACCOUNT.read(), account_events_receiver)
|
||||||
|
.await;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Error during login: {err}");
|
error!("Error during login: {err}");
|
||||||
// TODO: Handle invalid login
|
// TODO: Handle invalid login
|
||||||
// invalid_login.modify(|_| true);
|
// invalid_login.modify(|_| true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app_settings.write().set_requester(RefCell::new(client));
|
|
||||||
} else {
|
} else {
|
||||||
warn!("At least one of the following values is/are invalid: homeserver, username or password");
|
warn!("At least one of the following values is/are invalid: homeserver, username or password");
|
||||||
}
|
}
|
||||||
@@ -190,8 +65,8 @@ pub async fn login(
|
|||||||
error!("=== LOGIN END ===");
|
error!("=== LOGIN END ===");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static APP_SETTINGS: GlobalSignal<AppSettings> = Signal::global(AppSettings::new);
|
pub static STORE: GlobalSignal<Store> = Signal::global(Store::new);
|
||||||
pub static ROOMS: GlobalSignal<ByIdRooms> = Signal::global(ByIdRooms::new);
|
|
||||||
|
// TODO: Merge ACCOUNT and SESSION
|
||||||
|
pub static ACCOUNT: GlobalSignal<Account> = Signal::global(|| Account::new(&STORE));
|
||||||
pub static SESSION: GlobalSignal<Session> = Signal::global(Session::new);
|
pub static SESSION: GlobalSignal<Session> = Signal::global(Session::new);
|
||||||
pub static CHATS_WIN_INTERFACE: GlobalSignal<ChatsWinInterface> =
|
|
||||||
Signal::global(ChatsWinInterface::new);
|
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@@ -95,32 +93,30 @@ impl Account {
|
|||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
impl AccountMessagingConsumerInterface for Account {
|
impl AccountMessagingConsumerInterface for Account {
|
||||||
async fn on_new_room(&self, room: Room) -> Rc<dyn RoomMessagingConsumerInterface> {
|
async fn on_new_room(&self, room: Rc<Room>) -> Rc<dyn RoomMessagingConsumerInterface> {
|
||||||
let room_id = room.id().clone();
|
let room_id = room.id().clone();
|
||||||
let room = Rc::new(room);
|
|
||||||
|
|
||||||
self.by_id_rooms
|
self.by_id_rooms
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(room_id, Rc::clone(&room));
|
.insert(room_id, Rc::clone(&room));
|
||||||
|
|
||||||
let room_store = Box::new(self.store.on_new_room(Rc::clone(&room)));
|
let room_store = self.store.on_new_room(Rc::clone(&room));
|
||||||
|
|
||||||
room.set_store(Some(room_store));
|
room.set_store(room_store);
|
||||||
|
|
||||||
room
|
room
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_new_space(&self, space: Space) -> Rc<dyn SpaceMessagingConsumerInterface> {
|
async fn on_new_space(&self, space: Rc<Space>) -> Rc<dyn SpaceMessagingConsumerInterface> {
|
||||||
let space_id = space.id().clone();
|
let space_id = space.id().clone();
|
||||||
let space = Rc::new(space);
|
|
||||||
|
|
||||||
self.by_id_spaces
|
self.by_id_spaces
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(space_id, Rc::clone(&space));
|
.insert(space_id, Rc::clone(&space));
|
||||||
|
|
||||||
let space_store = Box::new(self.store.on_new_space(Rc::clone(&space)));
|
let space_store = self.store.on_new_space(Rc::clone(&space));
|
||||||
|
|
||||||
space.set_store(Some(space_store));
|
space.set_store(space_store);
|
||||||
|
|
||||||
space
|
space
|
||||||
}
|
}
|
||||||
|
@@ -13,8 +13,8 @@ use crate::infrastructure::messaging::matrix::account_event::AccountEvent;
|
|||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
pub trait AccountMessagingConsumerInterface {
|
pub trait AccountMessagingConsumerInterface {
|
||||||
async fn on_new_room(&self, room: Room) -> Rc<dyn RoomMessagingConsumerInterface>;
|
async fn on_new_room(&self, room: Rc<Room>) -> Rc<dyn RoomMessagingConsumerInterface>;
|
||||||
async fn on_new_space(&self, space: Space) -> Rc<dyn SpaceMessagingConsumerInterface>;
|
async fn on_new_space(&self, space: Rc<Space>) -> Rc<dyn SpaceMessagingConsumerInterface>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use futures::future::{join, join_all};
|
use futures::future::{join, join_all};
|
||||||
@@ -34,7 +32,7 @@ pub struct Room {
|
|||||||
members: RefCell<HashMap<UserId, RoomMember>>,
|
members: RefCell<HashMap<UserId, RoomMember>>,
|
||||||
|
|
||||||
messaging_provider: Option<Rc<dyn RoomMessagingProviderInterface>>,
|
messaging_provider: Option<Rc<dyn RoomMessagingProviderInterface>>,
|
||||||
store: RefCell<Option<Box<dyn RoomStoreProviderInterface>>>,
|
store: RefCell<Option<Rc<dyn RoomStoreProviderInterface>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Room {
|
impl PartialEq for Room {
|
||||||
@@ -75,8 +73,8 @@ impl Room {
|
|||||||
self.messaging_provider = Some(messaging_provider);
|
self.messaging_provider = Some(messaging_provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_store(&self, store: Option<Box<dyn RoomStoreProviderInterface>>) {
|
pub fn set_store(&self, store: Rc<dyn RoomStoreProviderInterface>) {
|
||||||
*self.store.borrow_mut() = store;
|
*self.store.borrow_mut() = Some(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> &RoomId {
|
pub fn id(&self) -> &RoomId {
|
||||||
|
@@ -26,7 +26,7 @@ pub struct Space {
|
|||||||
children: RefCell<HashSet<RoomId>>, // We don´t expect to manage nested spaces
|
children: RefCell<HashSet<RoomId>>, // We don´t expect to manage nested spaces
|
||||||
|
|
||||||
messaging_provider: Option<Rc<dyn SpaceMessagingProviderInterface>>,
|
messaging_provider: Option<Rc<dyn SpaceMessagingProviderInterface>>,
|
||||||
store: RefCell<Option<Box<dyn SpaceStoreProviderInterface>>>,
|
store: RefCell<Option<Rc<dyn SpaceStoreProviderInterface>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Space {
|
impl PartialEq for Space {
|
||||||
@@ -57,8 +57,8 @@ impl Space {
|
|||||||
self.messaging_provider = Some(provider);
|
self.messaging_provider = Some(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_store(&self, store: Option<Box<dyn SpaceStoreProviderInterface>>) {
|
pub fn set_store(&self, store: Rc<dyn SpaceStoreProviderInterface>) {
|
||||||
*self.store.borrow_mut() = store;
|
*self.store.borrow_mut() = Some(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> &SpaceId {
|
pub fn id(&self) -> &SpaceId {
|
||||||
@@ -84,7 +84,7 @@ impl SpaceMessagingConsumerInterface for Space {
|
|||||||
error!("Space::on_new_name({:?})", name);
|
error!("Space::on_new_name({:?})", name);
|
||||||
self.name.borrow_mut().clone_from(&name);
|
self.name.borrow_mut().clone_from(&name);
|
||||||
|
|
||||||
if let Some(store) = self.store.borrow_mut().as_mut() {
|
if let Some(store) = self.store.borrow().as_ref() {
|
||||||
store.set_name(name);
|
store.set_name(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::room::Room;
|
use super::{room::Room, space::Space};
|
||||||
use super::space::Space;
|
|
||||||
use crate::base::{StoreRoom, StoreSpace};
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub trait AccountStoreConsumerInterface {}
|
pub trait AccountStoreConsumerInterface {}
|
||||||
|
|
||||||
pub trait AccountStoreProviderInterface {
|
pub trait AccountStoreProviderInterface {
|
||||||
fn on_new_room(&self, room: Rc<Room>) -> StoreRoom;
|
fn on_new_room(&self, room: Rc<Room>) -> Rc<dyn RoomStoreProviderInterface>;
|
||||||
fn on_new_space(&self, space: Rc<Space>) -> StoreSpace;
|
fn on_new_space(&self, space: Rc<Space>) -> Rc<dyn SpaceStoreProviderInterface>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -19,5 +17,5 @@ pub trait RoomStoreProviderInterface {}
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub trait SpaceStoreConsumerInterface {}
|
pub trait SpaceStoreConsumerInterface {}
|
||||||
pub trait SpaceStoreProviderInterface {
|
pub trait SpaceStoreProviderInterface {
|
||||||
fn set_name(&mut self, _name: Option<String>) {}
|
fn set_name(&self, _name: Option<String>) {}
|
||||||
}
|
}
|
||||||
|
@@ -147,6 +147,8 @@ impl AccountMessagingProviderInterface for Requester {
|
|||||||
|
|
||||||
room.set_messaging_provider(client.clone());
|
room.set_messaging_provider(client.clone());
|
||||||
|
|
||||||
|
let room = Rc::new(room);
|
||||||
|
|
||||||
let stream = BroadcastStream::new(receiver.into());
|
let stream = BroadcastStream::new(receiver.into());
|
||||||
rooms_events_streams.insert(room_id.clone(), stream);
|
rooms_events_streams.insert(room_id.clone(), stream);
|
||||||
|
|
||||||
@@ -162,6 +164,8 @@ impl AccountMessagingProviderInterface for Requester {
|
|||||||
|
|
||||||
space.set_messaging_provider(client.clone());
|
space.set_messaging_provider(client.clone());
|
||||||
|
|
||||||
|
let space = Rc::new(space);
|
||||||
|
|
||||||
let stream = BroadcastStream::new(receiver.into());
|
let stream = BroadcastStream::new(receiver.into());
|
||||||
spaces_events_streams.insert(space_id.clone(), stream);
|
spaces_events_streams.insert(space_id.clone(), stream);
|
||||||
|
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
pub(crate) mod components;
|
pub(crate) mod components;
|
||||||
|
pub(crate) mod store;
|
||||||
pub(crate) mod views;
|
pub(crate) mod views;
|
||||||
|
50
src/ui/store/mod.rs
Normal file
50
src/ui/store/mod.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
pub(crate) mod room;
|
||||||
|
pub(crate) mod space;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::domain::model::room::{Room as DomainRoom, RoomId};
|
||||||
|
use crate::domain::model::space::{Space as DomainSpace, SpaceId};
|
||||||
|
use crate::domain::model::store_interface::{
|
||||||
|
AccountStoreProviderInterface, RoomStoreProviderInterface, SpaceStoreProviderInterface,
|
||||||
|
};
|
||||||
|
|
||||||
|
use room::{Room, RoomProps};
|
||||||
|
use space::{Space, SpaceProps};
|
||||||
|
|
||||||
|
#[modx::store]
|
||||||
|
pub struct Store {
|
||||||
|
rooms: HashMap<RoomId, Room>,
|
||||||
|
spaces: HashMap<SpaceId, Space>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl AccountStoreProviderInterface for GlobalSignal<Store> {
|
||||||
|
fn on_new_room(&self, domain_room: Rc<DomainRoom>) -> Rc<dyn RoomStoreProviderInterface> {
|
||||||
|
let room_id = domain_room.id();
|
||||||
|
|
||||||
|
let props = RoomProps::new(room_id.clone(), domain_room.name());
|
||||||
|
let room = Room::new(props);
|
||||||
|
|
||||||
|
let mut rooms = self.read().rooms;
|
||||||
|
rooms.write().insert(room_id.clone(), room);
|
||||||
|
|
||||||
|
Rc::new(room.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_new_space(&self, domain_space: Rc<DomainSpace>) -> Rc<dyn SpaceStoreProviderInterface> {
|
||||||
|
let space_id = domain_space.id();
|
||||||
|
|
||||||
|
let props = SpaceProps::new(space_id.clone(), domain_space.name());
|
||||||
|
let space = Space::new(props);
|
||||||
|
|
||||||
|
let mut spaces = self.read().spaces;
|
||||||
|
spaces.write().insert(space_id.clone(), space);
|
||||||
|
|
||||||
|
Rc::new(RefCell::new(space.clone()))
|
||||||
|
}
|
||||||
|
}
|
21
src/ui/store/room.rs
Normal file
21
src/ui/store/room.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::domain::model::{
|
||||||
|
room::RoomId, room_member::RoomMember, store_interface::RoomStoreProviderInterface,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[modx::props(id, name)]
|
||||||
|
#[modx::store]
|
||||||
|
pub struct Room {
|
||||||
|
id: RoomId,
|
||||||
|
name: Option<String>,
|
||||||
|
members: Vec<RoomMember>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Room {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RoomStoreProviderInterface for Room {}
|
24
src/ui/store/space.rs
Normal file
24
src/ui/store/space.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::domain::model::{space::SpaceId, store_interface::SpaceStoreProviderInterface};
|
||||||
|
|
||||||
|
#[modx::props(id, name)]
|
||||||
|
#[modx::store]
|
||||||
|
pub struct Space {
|
||||||
|
id: SpaceId,
|
||||||
|
name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Space {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpaceStoreProviderInterface for RefCell<Space> {
|
||||||
|
fn set_name(&self, name: Option<String>) {
|
||||||
|
self.borrow_mut().name.set(name);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user