commit bb4a25c3e064e56b780785c7bdd9d8c7edd07955
parent 572516e40adb131513ed65ee7bd6be16968893cb
Author: Marcel <mtrnord1@gmail.com>
Date: Tue, 26 May 2020 13:39:24 +0200
Fix routing
Took 1 hour 31 minutes
Diffstat:
6 files changed, 140 insertions(+), 87 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -8,26 +8,29 @@ edition = "2018"
crate-type = ["cdylib", "rlib"]
[dependencies]
+cfg-if = "0.1"
+console_error_panic_hook = { version = "0.1", optional = true }
log = "0.4"
strum = "0.17"
strum_macros = "0.17"
serde = "1"
serde_derive = "1"
-wasm-bindgen = "0.2.58"
+wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4.12"
wasm-logger = "0.2"
-wee_alloc = { version = "0.4.4", optional = true }
+wee_alloc = "0.4"
yew = "0.16"
yew-router = "0.13"
futures = "0.3"
matrix-sdk = { version = "0.1.0", git = "https://github.com/matrix-org/matrix-rust-sdk.git", default-features = false}
url = "2.1.1"
+yew_styles = "0.3.1"
[dev-dependencies]
wasm-bindgen-test = "0.3"
[dependencies.web-sys]
-version = "0.3.4"
+version = "0.3"
features = [
'KeyboardEvent',
]
diff --git a/src/app.rs b/src/app.rs
@@ -1,66 +1,121 @@
use log::*;
-use serde_derive::{Deserialize, Serialize};
-use yew::prelude::*;
+use yew::{prelude::*, virtual_dom::VNode};
use yew_router::{prelude::*, Switch};
-use yew_router::switch::Permissive;
-use yew::virtual_dom::VNode;
use crate::app::views::{login::Login, main_view::MainView};
+use crate::app::matrix::{Response, MatrixAgent};
+use yew_router::agent::RouteRequest::ChangeRoute;
mod matrix;
mod views;
#[derive(Switch, Clone)]
pub enum AppRoute {
- #[to = "/"]
- Start,
- #[to = "/login"]
- Login,
#[to = "/app"]
MainView,
- #[to = "/page-not-found"]
- PageNotFound(Permissive<String>),
+ #[to = "/"]
+ Start,
+}
+pub enum Msg {
+ RouteChanged(Route<()>),
+ ChangeRoute(AppRoute),
+ NewMessage(Response),
+}
+pub struct App {
+ matrix_agent: Box<dyn Bridge<MatrixAgent>>,
+ link: ComponentLink<Self>,
+ route: Option<Route<()>>,
+ route_agent: Box<dyn Bridge<RouteAgent<()>>>,
}
-pub struct App {}
-
-#[derive(Serialize, Deserialize)]
-pub struct State {}
-
+impl App {
+ fn change_route(&self, app_route: AppRoute) -> Callback<MouseEvent> {
+ self.link.callback(move |_| {
+ let route = app_route.clone();
+ Msg::ChangeRoute(route)
+ })
+ }
+}
impl Component for App {
- type Message = ();
+ type Message = Msg;
type Properties = ();
- fn create(_: Self::Properties, _link: ComponentLink<Self>) -> Self {
- App {}
+ fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
+ let route_agent = RouteAgent::bridge(link.callback(Msg::RouteChanged));
+ let mut matrix_agent = MatrixAgent::bridge(link.callback(Msg::NewMessage));
+ matrix_agent.send(matrix::Request::GetLoggedIn);
+ App {
+ matrix_agent,
+ route_agent,
+ route: None,
+ link,
+ }
}
- fn update(&mut self, _: Self::Message) -> ShouldRender {
- false
+ fn update(&mut self, msg: Self::Message) -> ShouldRender {
+ match msg {
+ Msg::RouteChanged(route) => {
+ self.route = Some(route);
+ }
+ Msg::ChangeRoute(route) => {
+ let route: Route = route.into();
+ self.route = Some(route.clone());
+ self.route_agent.send(ChangeRoute(route));
+ }
+ Msg::NewMessage(response) => {
+ info!("NewMessage: {:#?}", response);
+ if response.message == "client_logged_in"{
+ info!("client_logged_in");
+ info!("{}", response.content);
+ let route: Route = if response.content == "true" {
+ //self.state.logged_in = true;
+
+ // replace with sync routeagent message once its possible
+ // https://github.com/yewstack/yew/issues/1127
+ //RouteService::new().get_route();
+ AppRoute::MainView.into()
+ } else {
+ AppRoute::Start.into()
+ };
+
+ info!("{:#?}", route.clone());
+ self.route = Some(route.clone());
+ self.route_agent.send(ChangeRoute(route));
+ }
+ }
+ }
+ true
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
- fn view(&self) -> VNode {
+ fn view(&self) -> Html {
info!("rendered App!");
+ info!("Route: {:#?}", &self.route);
html! {
<div>
- <Router<AppRoute, ()>
- render = Router::render(|switch: AppRoute| {
- match switch {
- AppRoute::Start => html!{<Login />},
- AppRoute::Login => html!{<Login />},
- AppRoute::MainView => html!{<MainView />},
- AppRoute::PageNotFound(Permissive(None)) => html!{"Page not found"},
- AppRoute::PageNotFound(Permissive(Some(missed_route))) => html!{format!("Page '{}' not found", missed_route)}
+ {
+ match &self.route {
+ None => {info!("NoneRoute"); html! {<Login />}},
+ Some(route) => match AppRoute::switch(route.clone()) {
+ Some(AppRoute::MainView) => {
+ info!("MainViewRoute");
+ html! {
+ <MainView />
+ }
+ },
+ Some(AppRoute::Start) => {
+ info!("StartRoute");
+ html! {
+ <Login />
+ }
+ },
+ None => VNode::from("404")
}
- })
- redirect = Router::redirect(|route: Route| {
- AppRoute::PageNotFound(Permissive(Some(route.route)))
- })
- />
+ }
+ }
</div>
}
}
diff --git a/src/app/matrix.rs b/src/app/matrix.rs
@@ -30,6 +30,7 @@ pub enum Request {
GetLoggedIn,
}
+// TODO make enum
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Response {
pub message: String,
@@ -95,8 +96,8 @@ impl Agent for MatrixAgent {
.await;
info!("did login");
let resp = Response {
- message: "login_logged_in".to_string(),
- content: "".to_string(),
+ message: "client_logged_in".to_string(),
+ content: "true".to_string(),
};
info!("prepared login response");
for sub in subscribers.iter() {
@@ -132,6 +133,9 @@ impl Agent for MatrixAgent {
impl MatrixAgent {
async fn get_logged_in(&self) -> String {
+ if self.matrix_client.is_none() {
+ return "false".to_string();
+ }
self.matrix_client
.clone()
.unwrap()
diff --git a/src/app/views/login.rs b/src/app/views/login.rs
@@ -1,23 +1,17 @@
use log::*;
-use serde_derive::{Deserialize, Serialize};
use yew::agent::{Dispatched, Dispatcher};
use yew::prelude::*;
use yew::services::storage::{Area, StorageService};
-use yew_router::{route::Route};
-use crate::app::matrix::{MatrixAgent, Request, Response};
-use yew_router::agent::RouteRequest;
-use yew_router::prelude::*;
+use crate::app::matrix::{MatrixAgent, Request};
pub struct Login {
link: ComponentLink<Self>,
- router: Box<dyn Bridge<RouteAgent>>,
homeserver: String,
username: String,
password: String,
storage: StorageService,
matrix_agent: Dispatcher<MatrixAgent>,
- _producer: Box<dyn Bridge<MatrixAgent>>,
}
pub enum Msg {
@@ -25,32 +19,25 @@ pub enum Msg {
SetUsername(String),
SetPassword(String),
Login,
- Navigate(String),
- NewMessage(Response),
Nope,
}
+
impl Component for Login {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
- let callback = link.callback(|_| Msg::Nope); // TODO use a dispatcher instead.
- let router = RouteAgent::bridge(callback);
-
let storage = StorageService::new(Area::Local).unwrap();
let matrix_agent = MatrixAgent::dispatcher();
- let matrix_callback = link.callback(Msg::NewMessage);
- let _producer = MatrixAgent::bridge(matrix_callback);
Login {
link,
- router,
+ //TODO use state
homeserver: "".to_string(),
username: "".to_string(),
password: "".to_string(),
storage,
matrix_agent,
- _producer,
}
}
@@ -77,24 +64,9 @@ impl Component for Login {
Msg::Login => {
info!("Start Login");
self.matrix_agent.send(Request::Login());
- true
- }
- Msg::Navigate(route_string) => {
- let route = Route::from(route_string);
-
- self.router.send(RouteRequest::ChangeRoute(route));
- true
+ false
}
Msg::Nope => false,
- Msg::NewMessage(response) => {
- info!("NewMessage: {:#?}", response);
- if response.message == "login_logged_in" {
- info!("Finished Login");
- self.link
- .callback(|_: InputData| Msg::Navigate("/app".to_owned()));
- }
- true
- }
}
}
@@ -103,7 +75,7 @@ impl Component for Login {
}
fn view(&self) -> Html {
- info!("rendered App!");
+ info!("rendered Login!");
html! {
<div>
<input class="server"
@@ -127,11 +99,11 @@ impl Component for Login {
type="password"
value=&self.password
oninput=self.link.callback(|e: InputData| Msg::SetPassword(e.value))
- //onkeypress=self.link.callback(|e: KeyboardEvent| {
- // if e.key() == "Enter" { Msg::Add } else { Msg::Nope }
- //})
/>
- <button onclick=self.link.callback(|_: MouseEvent| Msg::Login)>
+ <button onclick=self.link.callback(|_: MouseEvent| Msg::Login)
+ onkeypress=self.link.callback(|e: KeyboardEvent| {
+ if e.key() == "Enter" { Msg::Login } else { Msg::Nope }
+ })>
{ "Login" }
</button>
</div>
diff --git a/src/app/views/main_view.rs b/src/app/views/main_view.rs
@@ -1,6 +1,5 @@
use log::*;
use serde_derive::{Deserialize, Serialize};
-use yew::agent::{Dispatched, Dispatcher};
use yew::prelude::*;
use yew::services::storage::Area;
use yew::services::StorageService;
@@ -11,9 +10,8 @@ use crate::app::matrix::{MatrixAgent, Response};
pub struct MainView {
link: ComponentLink<Self>,
storage: StorageService,
- matrix_agent: Dispatcher<MatrixAgent>,
state: State,
- _producer: Box<dyn Bridge<MatrixAgent>>,
+ matrix_agent: Box<dyn Bridge<MatrixAgent>>,
}
pub enum Msg {
@@ -29,9 +27,8 @@ impl Component for MainView {
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
let storage = StorageService::new(Area::Local).unwrap();
- let matrix_agent = MatrixAgent::dispatcher();
let matrix_callback = link.callback(Msg::NewMessage);
- let _producer = MatrixAgent::bridge(matrix_callback);
+ let matrix_agent = MatrixAgent::bridge(matrix_callback);
let state = State {};
MainView {
@@ -39,7 +36,6 @@ impl Component for MainView {
storage,
matrix_agent,
state,
- _producer,
}
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,18 +1,41 @@
+
#![recursion_limit = "512"]
+#[macro_use]
+extern crate cfg_if;
mod app;
use wasm_bindgen::prelude::*;
-// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
-// allocator.
-#[cfg(feature = "wee_alloc")]
-#[global_allocator]
-static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
+cfg_if! {
+ // When the `console_error_panic_hook` feature is enabled, we can call the
+ // `set_panic_hook` function to get better error messages if we ever panic.
+ if #[cfg(feature = "console_error_panic_hook")] {
+ extern crate console_error_panic_hook;
+ use console_error_panic_hook::set_once as set_panic_hook;
+ } else {
+ #[inline]
+ fn set_panic_hook() {}
+ }
+}
+
+cfg_if! {
+ // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
+ // allocator.
+ if #[cfg(feature = "wee_alloc")] {
+ extern crate wee_alloc;
+ #[global_allocator]
+ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
+ }
+}
+
// This is the entry point for the web app
#[wasm_bindgen]
pub fn run_app() -> Result<(), JsValue> {
+ // If the `console_error_panic_hook` feature is enabled this will set a panic hook, otherwise
+ // it will do nothing.
+ set_panic_hook();
wasm_logger::init(wasm_logger::Config::default());
yew::start_app::<app::App>();
Ok(())