daydream

A small matrix web client written in rust
git clone git://archive.git.mtrnord.blog/daydream-mx/daydream.git
Log | Files | Refs | README | LICENSE

mod.rs (4063B)


      1 use yew::{prelude::*, virtual_dom::VNode};
      2 use yew_router::agent::RouteRequest::ChangeRoute;
      3 use yew_router::{prelude::*, Switch};
      4 
      5 use crate::app::matrix::{login::SessionStore, MatrixAgent, Response};
      6 use crate::app::views::{login::Login, main_view::MainView};
      7 use crate::constants::AUTH_KEY;
      8 use log::*;
      9 use std::sync::{Arc, Mutex};
     10 use yew::format::Json;
     11 use yew::services::storage::Area;
     12 use yew::services::StorageService;
     13 
     14 pub mod components;
     15 pub mod matrix;
     16 mod views;
     17 
     18 #[derive(Switch, Clone)]
     19 pub enum AppRoute {
     20     #[to = "/login"]
     21     Login,
     22     #[to = "/"]
     23     MainView,
     24 }
     25 
     26 #[allow(clippy::large_enum_variant)]
     27 pub enum Msg {
     28     RouteChanged(Route<()>),
     29     ChangeRoute(AppRoute),
     30     NewMessage(Response),
     31 }
     32 
     33 pub struct App {
     34     // While unused this needs to stay :(
     35     _matrix_agent: Box<dyn Bridge<MatrixAgent>>,
     36     route: Option<Route<()>>,
     37     route_agent: Box<dyn Bridge<RouteAgent<()>>>,
     38     storage: Arc<Mutex<StorageService>>,
     39 }
     40 
     41 impl Component for App {
     42     type Message = Msg;
     43     type Properties = ();
     44 
     45     fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
     46         let storage = Arc::new(Mutex::new(
     47             StorageService::new(Area::Local).expect("storage was disabled by the user"),
     48         ));
     49 
     50         let session: Option<SessionStore> = {
     51             if let Json(Ok(restored_model)) = storage.lock().unwrap().restore(AUTH_KEY) {
     52                 Some(restored_model)
     53             } else {
     54                 None
     55             }
     56         };
     57         let route_agent = RouteAgent::bridge(link.callback(Msg::RouteChanged));
     58         let mut matrix_agent = MatrixAgent::bridge(link.callback(Msg::NewMessage));
     59         if let Some(session) = session {
     60             matrix_agent.send(matrix::Request::SetSession(session));
     61         }
     62         matrix_agent.send(matrix::Request::GetLoggedIn);
     63         App {
     64             _matrix_agent: matrix_agent,
     65             route_agent,
     66             route: None,
     67             storage,
     68         }
     69     }
     70 
     71     fn update(&mut self, msg: Self::Message) -> ShouldRender {
     72         match msg {
     73             Msg::RouteChanged(route) => {
     74                 self.route = Some(route);
     75             }
     76             Msg::ChangeRoute(route) => {
     77                 let route: Route = route.into();
     78                 self.route = Some(route.clone());
     79                 info!("{:?}", self.route);
     80                 self.route_agent.send(ChangeRoute(route));
     81             }
     82             Msg::NewMessage(response) => {
     83                 //info!("NewMessage: {:#?}", response);
     84                 match response {
     85                     Response::SaveSession(session) => {
     86                         let mut storage = self.storage.lock().unwrap();
     87                         storage.store(AUTH_KEY, Json(&session));
     88                     }
     89                     Response::Error(_) => {}
     90                     Response::LoggedIn(logged_in) => {
     91                         let route: Route = if logged_in {
     92                             //self.state.logged_in = true;
     93 
     94                             // replace with sync routeagent message once its possible
     95                             // https://github.com/yewstack/yew/issues/1127
     96                             //RouteService::new().get_route();
     97                             AppRoute::MainView.into()
     98                         } else {
     99                             AppRoute::Login.into()
    100                         };
    101 
    102                         self.route = Some(route.clone());
    103                         self.route_agent.send(ChangeRoute(route));
    104                     }
    105                     _ => {}
    106                 }
    107             }
    108         }
    109         true
    110     }
    111 
    112     fn change(&mut self, _props: Self::Properties) -> ShouldRender {
    113         false
    114     }
    115 
    116     fn view(&self) -> Html {
    117         match &self.route {
    118             None => html! { <Login /> },
    119             Some(route) => match AppRoute::switch(route.clone()) {
    120                 Some(AppRoute::MainView) => html! { <MainView /> },
    121                 Some(AppRoute::Login) => html! { <Login /> },
    122                 None => VNode::from("404"),
    123             },
    124         }
    125     }
    126 }