Working login flow.

This commit is contained in:
projectmoon 2021-06-17 14:31:18 +00:00
parent 76fbe9a74b
commit 9e0fd44448
5 changed files with 140 additions and 150 deletions

127
Cargo.lock generated
View File

@ -390,6 +390,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg-match"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8100e46ff92eb85bf6dc2930c73f2a4f7176393c84a9446b3d501e1b354e7b34"
[[package]]
name = "chacha20"
version = "0.6.0"
@ -2728,12 +2734,6 @@ dependencies = [
"uncased",
]
[[package]]
name = "route-recognizer"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824172f0afccf3773c3905f5550ac94572144efe0deaf49a1f22bbca188d193e"
[[package]]
name = "ruma"
version = "0.1.2"
@ -3014,12 +3014,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "scoped-tls-hkt"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e9d7eaddb227e8fbaaa71136ae0e1e913ca159b86c7da82f3e8f0044ad3a63"
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -3592,9 +3586,7 @@ dependencies = [
"wasm-bindgen-futures",
"web-sys",
"yew",
"yew-functional",
"yew-router",
"yew-services",
"yewdux",
"yewtil",
]
@ -4221,28 +4213,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "weblog"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6eec0958e0181982bc8b4577b1363f21300a670603615c58643f172c92c47357"
dependencies = [
"wasm-bindgen",
"web-sys",
"weblog-proc-macro",
]
[[package]]
name = "weblog-proc-macro"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d9abb8ee84ede5408a346721d72fb216a27f53a539ff3c83ed1bf7625af7104"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "which"
version = "4.1.0"
@ -4335,18 +4305,22 @@ checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"
[[package]]
name = "yew"
version = "0.17.4"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4d5154faef86dddd2eb333d4755ea5643787d20aca683e58759b0e53351409f"
dependencies = [
"anyhow",
"anymap",
"bincode",
"cfg-if 1.0.0",
"cfg-match",
"console_error_panic_hook",
"gloo",
"http",
"indexmap",
"js-sys",
"log",
"ryu",
"serde",
"serde_json",
"slab",
@ -4357,31 +4331,11 @@ dependencies = [
"yew-macro",
]
[[package]]
name = "yew-functional"
version = "0.13.0"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
dependencies = [
"scoped-tls-hkt",
"wasm-bindgen",
"yew",
"yew-functional-macro",
]
[[package]]
name = "yew-functional-macro"
version = "0.1.0"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "yew-macro"
version = "0.17.0"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6e23bfe3dc3933fbe9592d149c9985f3047d08c637a884b9344c21e56e092ef"
dependencies = [
"boolinator",
"lazy_static",
@ -4392,68 +4346,65 @@ dependencies = [
[[package]]
name = "yew-router"
version = "0.14.0"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27666236d9597eac9be560e841e415e20ba67020bc8cd081076be178e159c8bc"
dependencies = [
"cfg-if 1.0.0",
"cfg-match",
"gloo",
"js-sys",
"route-recognizer",
"log",
"nom 5.1.2",
"serde",
"serde_urlencoded",
"serde_json",
"wasm-bindgen",
"web-sys",
"weblog",
"yew",
"yew-router-macro",
"yew-router-route-parser",
]
[[package]]
name = "yew-router-macro"
version = "0.14.0"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0ace2924b7a175e2d1c0e62ee7022a5ad840040dcd52414ce5f410ab322dba"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"yew-router-route-parser",
]
[[package]]
name = "yew-services"
version = "0.1.0"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
name = "yew-router-route-parser"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de4a67208fb46b900af18a7397938b01f379dfc18da34799cfa8347eec715697"
dependencies = [
"anyhow",
"gloo",
"http",
"js-sys",
"serde",
"serde_json",
"thiserror",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"yew",
"nom 5.1.2",
]
[[package]]
name = "yewdux"
version = "0.6.1"
source = "git+https://github.com/deftsp/yewdux?rev=dbda686#dbda686dea05c0efaef0cd3af46012033071f40e"
version = "0.6.2"
source = "git+https://github.com/intendednull/yewdux?rev=v0.6.2#a6d8dbf69d472a2d0e82ab70237b16e86865c994"
dependencies = [
"serde",
"yew",
"yew-services",
]
[[package]]
name = "yewtil"
version = "0.3.2"
source = "git+https://github.com/yewstack/yew?rev=246bc59#246bc5960b504258b0603bc76760777e6650c91d"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8543663ac49cd613df079282a1d8bdbdebdad6e02bac229f870fd4237b5d9aaa"
dependencies = [
"log",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"yew",
]

View File

@ -13,20 +13,13 @@ crate-type = ["cdylib", "rlib"]
tenebrous-api = { path = "../../api" }
[dependencies]
# yew = { version = "0.18" }
# yewtil = {version = "0.4" }
# yew-router = {version = "0.15" }
# yewdux = {version = "^0.6" }
yew = { git = "https://github.com/yewstack/yew", rev = "246bc59" }
yew-functional = { git = "https://github.com/yewstack/yew", rev = "246bc59" }
yew-router = { git = "https://github.com/yewstack/yew", rev = "246bc59" }
yew-services = { git = "https://github.com/yewstack/yew", rev = "246bc59" }
yewtil = { git = "https://github.com/yewstack/yew", rev = "246bc59"}
yewdux = { git = "https://github.com/deftsp/yewdux", rev = "dbda686"}
yew = { version = "0.18" }
yewtil = {version = "0.4" }
yew-router = {version = "0.15" }
yewdux = { git = "https://github.com/intendednull/yewdux", rev = "v0.6.2"}
wasm-bindgen = { version = "0.2" }
wasm-bindgen-futures = "0.4"
js-sys = "0.3"
#grpc-web-client = "0.1"
graphql_client = { git = "https://github.com/graphql-rust/graphql-client", branch = "master" }
graphql_client_web = { git = "https://github.com/graphql-rust/graphql-client", branch = "master" }
serde = { version = "1.0.67", features = ["derive"] }

View File

@ -25,20 +25,14 @@ pub enum LoginAction {
}
pub(crate) type Login = WithDispatch<YewduxLogin>;
async fn do_login(
dispatch: &WebUiDispatcher,
username: &str,
password: &str,
) -> Result<(), UiError> {
let jwt = api::auth::login(username, password).await?;
//state.jwt_token = Some(jwt);
dispatch.send(Action::UpdateJwt(jwt));
Ok(())
}
async fn do_refresh_jwt(dispatch: &WebUiDispatcher) -> Result<(), UiError> {
let jwt = api::auth::refresh_jwt().await?;
dispatch.send(Action::UpdateJwt(jwt));
dispatch.send(Action::Login(jwt));
Ok(())
}
@ -78,31 +72,12 @@ impl Component for YewduxLogin {
self.dispatch.neq_assign(Rc::new(dispatch))
}
fn rendered(&mut self, first_render: bool) {
if first_render {
//
}
}
fn view(&self) -> Html {
// let do_the_login = self.dispatch.reduce_callback(|state| {
// spawn_local(async move {
// do_login(state, "user", "pw").await;
// });
// });
let do_the_login = self.link.callback(move |e: FocusEvent| {
e.prevent_default();
LoginAction::Login
});
// let refresh_jwt = self.link.callback(move |_| {
// let dispatch = dispatch2.clone();
// spawn_local(async move {
// do_refresh_jwt(&*dispatch).await;
// });
// });
let update_username = self
.link
.callback(|e: InputData| LoginAction::UpdateUsername(e.value));

View File

@ -1,11 +1,16 @@
use crate::components::error_message::ErrorMessage;
use crate::components::login::Login;
use error::UiError;
use rooms::RoomList;
use rooms::YewduxRoomList;
use state::{Action, AuthState, WebUiDispatcher};
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::spawn_local;
use yew::prelude::*;
use yew_router::prelude::*;
use yew_router::{components::RouterAnchor, prelude::*, switch::Permissive};
use yewdux::prelude::*;
use yewtil::NeqAssign;
pub mod api;
pub mod components;
@ -14,20 +19,20 @@ pub mod grpc;
pub mod rooms;
pub mod state;
#[derive(Routable, PartialEq, Clone, Debug)]
#[derive(Clone, Debug, Switch)]
pub enum AppRoute {
#[at("/rooms")]
#[to = "/rooms"]
Rooms,
#[at("/rooms/{room_id}")]
#[to = "/rooms/{room_id}"]
Room { room_id: String },
#[at("/")]
#[to = "/"]
Index,
}
type AppRouter = Router<AppRoute>;
type AppAnchor = Link<AppRoute>; //For rendering clickable links.
type AppAnchor = RouterAnchor<AppRoute>; //For rendering clickable links.
fn render_route(routes: &AppRoute) -> Html {
fn render_route(routes: AppRoute) -> Html {
match routes {
AppRoute::Rooms => {
html! {
@ -36,13 +41,12 @@ fn render_route(routes: &AppRoute) -> Html {
}
AppRoute::Room { room_id } => {
html! {
<div>{"This is the specifi roompage."}</div>
<div>{"This is the specific room page."}</div>
}
}
AppRoute::Index => {
html! {
<div>
<Login />
<ErrorMessage />
<RoomList />
</div>
@ -51,25 +55,69 @@ fn render_route(routes: &AppRoute) -> Html {
}
}
struct App;
struct YewduxApp {
link: ComponentLink<YewduxApp>,
dispatch: WebUiDispatcher,
}
impl Component for App {
type App = WithDispatch<YewduxApp>;
async fn refresh_jwt(dispatch: &WebUiDispatcher) {
match api::auth::refresh_jwt().await {
Ok(jwt) => {
dispatch.send(Action::Login(jwt));
}
Err(e) => {
web_sys::console::log_1(&e.to_string().into());
dispatch.send(Action::ChangeAuthState(AuthState::NotLoggedIn));
}
}
}
impl Component for YewduxApp {
type Message = ();
type Properties = ();
type Properties = WebUiDispatcher;
fn create(_: Self::Properties, _link: ComponentLink<Self>) -> Self {
Self
fn create(dispatch: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { dispatch, link }
}
fn update(&mut self, _: Self::Message) -> ShouldRender {
false
}
fn change(&mut self, _: Self::Properties) -> ShouldRender {
false
fn change(&mut self, dispatch: Self::Properties) -> ShouldRender {
self.dispatch.neq_assign(dispatch)
}
fn rendered(&mut self, first_render: bool) {
if first_render {
let auth_state = self.dispatch.state().auth_state;
if auth_state == AuthState::RefreshNeeded {
let dispatch = self.dispatch.clone();
spawn_local(async move {
refresh_jwt(&dispatch).await;
});
}
}
}
fn view(&self) -> Html {
let auth_state = self.dispatch.state().auth_state;
match auth_state {
AuthState::RefreshNeeded => {
html! {
<div>{"Loading..."}</div>
}
}
AuthState::NotLoggedIn => {
html! {
<Login />
}
}
AuthState::LoggedIn => {
html! {
<div>
<div class="alert alert-primary" role="alert">
@ -82,6 +130,8 @@ impl Component for App {
}
}
}
}
}
#[wasm_bindgen(start)]
pub fn run_app() {

View File

@ -8,8 +8,22 @@ pub(crate) struct Room {
pub display_name: String,
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub(crate) enum AuthState {
NotLoggedIn,
LoggedIn,
RefreshNeeded,
}
impl Default for AuthState {
fn default() -> Self {
AuthState::RefreshNeeded
}
}
#[derive(Default, Clone)]
pub(crate) struct WebUiState {
pub auth_state: AuthState,
pub jwt_token: Option<String>,
pub rooms: Vec<Room>,
pub error_messages: Vec<String>,
@ -20,6 +34,8 @@ pub(crate) enum Action {
AddRoom(Room),
ErrorMessage(UiError),
ClearErrorMessage,
ChangeAuthState(AuthState),
Login(String),
}
impl Reducer for WebUiState {
@ -32,7 +48,12 @@ impl Reducer for WebUiState {
fn reduce(&mut self, action: Self::Action) -> bool {
match action {
Action::UpdateJwt(jwt_token) => self.jwt_token = Some(jwt_token),
Action::Login(jwt_token) => {
self.jwt_token = Some(jwt_token);
self.auth_state = AuthState::LoggedIn;
}
Action::AddRoom(room) => self.rooms.push(room.clone()),
Action::ChangeAuthState(auth_state) => self.auth_state = auth_state,
Action::ErrorMessage(error) => self.error_messages.push(error.to_string()),
Action::ClearErrorMessage => {
if self.error_messages.len() > 0 {