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

View File

@ -1,50 +1,17 @@
use crate::api;
use crate::error::UiError;
use crate::state::{Action, Room, WebUiDispatcher};
use std::sync::Arc;
use wasm_bindgen_futures::spawn_local;
use web_sys::console;
use yew::prelude::*;
use yewdux::dispatch::Dispatcher;
use yewdux::prelude::*;
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)]
pub(crate) struct YewduxRoomList {
dispatch: RoomListDispatch,
dispatch: WebUiDispatcher,
link: ComponentLink<YewduxRoomList>,
}
@ -52,14 +19,13 @@ pub(crate) type RoomList = WithDispatch<YewduxRoomList>;
fn view_room(room: &Room) -> Html {
html! {
<div>
<div>{room.room_id.clone()}</div>
<div>{room.display_name.clone()}</div>
</div>
<li>
{&room.display_name} {" ("}{&room.room_id}{")"}
</li>
}
}
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?;
for room in rooms {
@ -74,7 +40,7 @@ async fn load_rooms(dispatch: &RoomListDispatch) -> Result<(), UiError> {
impl Component for YewduxRoomList {
type Message = ();
type Properties = RoomListDispatch;
type Properties = WebUiDispatcher;
fn create(dispatch: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { dispatch, link }
@ -88,11 +54,9 @@ impl Component for YewduxRoomList {
self.dispatch.neq_assign(dispatch)
}
fn view(&self) -> Html {
let dispatch = Arc::new(self.dispatch.clone());
let the_future = self.link.callback(move |_| {
let dispatch = dispatch.clone();
fn rendered(&mut self, first_render: bool) {
if first_render {
let dispatch = Arc::new(self.dispatch.clone());
spawn_local(async move {
//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! {
<div>
<button onclick=the_future>{ "Add Room" }</button>
<ul>
{
for self.dispatch.state().rooms.iter().map(|oath| {
view_room(oath)
for self.dispatch.state().rooms.iter().map(|room| {
view_room(room)
})
}
</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
//directory. Webpack then replaces this import with what is actually
//needed.
import("./pkg").then(runic => {
console.log('module is: ', runic);
runic.run_app();
});
import("./pkg");