Move state to separate file. Fix double rendering problem.

This commit is contained in:
projectmoon 2021-06-07 22:34:05 +00:00
parent aeef9533ea
commit ddb8eae185
4 changed files with 57 additions and 55 deletions

View File

@ -1,12 +1,15 @@
use rooms::RoomList; use rooms::RoomList;
use rooms::YewduxRoomList;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use yew::prelude::*; use yew::prelude::*;
use yew_router::prelude::*; use yew_router::prelude::*;
use yewdux::prelude::*;
pub mod api; pub mod api;
pub mod error; pub mod error;
pub mod grpc; pub mod grpc;
pub mod rooms; pub mod rooms;
pub mod state;
#[derive(Routable, PartialEq, Clone, Debug)] #[derive(Routable, PartialEq, Clone, Debug)]
pub enum AppRoute { pub enum AppRoute {
@ -112,6 +115,5 @@ impl Component for App {
#[wasm_bindgen(start)] #[wasm_bindgen(start)]
pub fn run_app() { pub fn run_app() {
//App::<EncryptedImage>::new().mount_with_props(body, props);
yew::start_app::<App>(); yew::start_app::<App>();
} }

View File

@ -1,50 +1,17 @@
use crate::api; use crate::api;
use crate::error::UiError; use crate::error::UiError;
use crate::state::{Action, Room, WebUiDispatcher};
use std::sync::Arc; use std::sync::Arc;
use wasm_bindgen_futures::spawn_local; use wasm_bindgen_futures::spawn_local;
use web_sys::console; use web_sys::console;
use yew::prelude::*; use yew::prelude::*;
use yewdux::dispatch::Dispatcher;
use yewdux::prelude::*; use yewdux::prelude::*;
use yewtil::NeqAssign; use yewtil::NeqAssign;
#[derive(Clone)]
pub(crate) struct Room {
room_id: String,
display_name: String,
}
#[derive(Default, Clone)]
pub(crate) struct RoomListState {
rooms: Vec<Room>,
}
pub(crate) enum Action {
AddRoom(Room),
}
impl Reducer for RoomListState {
type Action = Action;
fn new() -> Self {
Self { rooms: vec![] }
}
fn reduce(&mut self, action: Self::Action) -> bool {
match action {
Action::AddRoom(room) => {
self.rooms.push(room.clone());
true
}
}
}
}
type RoomListDispatch = DispatchProps<ReducerStore<RoomListState>>;
//Oaths list
#[doc(hidden)] #[doc(hidden)]
pub(crate) struct YewduxRoomList { pub(crate) struct YewduxRoomList {
dispatch: RoomListDispatch, dispatch: WebUiDispatcher,
link: ComponentLink<YewduxRoomList>, link: ComponentLink<YewduxRoomList>,
} }
@ -52,14 +19,13 @@ pub(crate) type RoomList = WithDispatch<YewduxRoomList>;
fn view_room(room: &Room) -> Html { fn view_room(room: &Room) -> Html {
html! { html! {
<div> <li>
<div>{room.room_id.clone()}</div> {&room.display_name} {" ("}{&room.room_id}{")"}
<div>{room.display_name.clone()}</div> </li>
</div>
} }
} }
async fn load_rooms(dispatch: &RoomListDispatch) -> Result<(), UiError> { async fn load_rooms(dispatch: &WebUiDispatcher) -> Result<(), UiError> {
let rooms = api::dicebot::rooms_for_user("@projectmoon:agnos.is").await?; let rooms = api::dicebot::rooms_for_user("@projectmoon:agnos.is").await?;
for room in rooms { for room in rooms {
@ -74,7 +40,7 @@ async fn load_rooms(dispatch: &RoomListDispatch) -> Result<(), UiError> {
impl Component for YewduxRoomList { impl Component for YewduxRoomList {
type Message = (); type Message = ();
type Properties = RoomListDispatch; type Properties = WebUiDispatcher;
fn create(dispatch: Self::Properties, link: ComponentLink<Self>) -> Self { fn create(dispatch: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { dispatch, link } Self { dispatch, link }
@ -88,11 +54,9 @@ impl Component for YewduxRoomList {
self.dispatch.neq_assign(dispatch) self.dispatch.neq_assign(dispatch)
} }
fn view(&self) -> Html { fn rendered(&mut self, first_render: bool) {
let dispatch = Arc::new(self.dispatch.clone()); if first_render {
let dispatch = Arc::new(self.dispatch.clone());
let the_future = self.link.callback(move |_| {
let dispatch = dispatch.clone();
spawn_local(async move { spawn_local(async move {
//TODO make macro to report errors in some common way: //TODO make macro to report errors in some common way:
@ -102,15 +66,19 @@ impl Component for YewduxRoomList {
_ => (), _ => (),
} }
}); });
}); }
}
fn view(&self) -> Html {
let the_future = self.link.callback(move |_| {});
html! { html! {
<div> <div>
<button onclick=the_future>{ "Add Room" }</button> <button onclick=the_future>{ "Add Room" }</button>
<ul> <ul>
{ {
for self.dispatch.state().rooms.iter().map(|oath| { for self.dispatch.state().rooms.iter().map(|room| {
view_room(oath) view_room(room)
}) })
} }
</ul> </ul>

35
web-ui/crate/src/state.rs Normal file
View File

@ -0,0 +1,35 @@
use yewdux::prelude::*;
#[derive(Clone)]
pub(crate) struct Room {
pub room_id: String,
pub display_name: String,
}
#[derive(Default, Clone)]
pub(crate) struct WebUiState {
pub rooms: Vec<Room>,
}
pub(crate) enum Action {
AddRoom(Room),
}
impl Reducer for WebUiState {
type Action = Action;
fn new() -> Self {
Self { rooms: vec![] }
}
fn reduce(&mut self, action: Self::Action) -> bool {
match action {
Action::AddRoom(room) => {
self.rooms.push(room.clone());
true
}
}
}
}
pub(crate) type WebUiDispatcher = DispatchProps<ReducerStore<WebUiState>>;

View File

@ -1,7 +1,4 @@
//The wasm application is compiled as javascript into the /pkg //The wasm application is compiled as javascript into the /pkg
//directory. Webpack then replaces this import with what is actually //directory. Webpack then replaces this import with what is actually
//needed. //needed.
import("./pkg").then(runic => { import("./pkg");
console.log('module is: ', runic);
runic.run_app();
});