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

commit 2fe0c07abd7925383fd00be5a2dc67a2fb558eb6
parent c9159791a7d70099c41455a00177d99115771165
Author: Marcel <mtrnord1@gmail.com>
Date:   Tue, 16 Jun 2020 22:06:00 +0200

Fix input field performance

Took 30 minutes

Diffstat:
Msrc/app/components/event_list.rs | 50++++++++++++++++----------------------------------
Asrc/app/components/input.rs | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/app/components/mod.rs | 1+
3 files changed, 91 insertions(+), 34 deletions(-)

diff --git a/src/app/components/event_list.rs b/src/app/components/event_list.rs @@ -7,11 +7,15 @@ use matrix_sdk::{ use std::collections::HashMap; use yew::prelude::*; -use crate::app::components::events::{image::Image, notice::Notice, text::Text, video::Video}; +use crate::app::components::{ + events::{image::Image, notice::Notice, text::Text, video::Video}, + input::Input, +}; use crate::app::matrix::{MatrixAgent, Request, Response}; pub struct EventList { link: ComponentLink<Self>, + on_submit: Callback<String>, state: State, matrix_agent: Box<dyn Bridge<MatrixAgent>>, props: Props, @@ -21,14 +25,12 @@ pub struct EventList { pub struct State { // TODO handle all events pub events: HashMap<RoomId, Vec<MessageEvent>>, - pub message: Option<String>, } #[allow(clippy::large_enum_variant)] pub enum Msg { NewMessage(Response), - SetMessage(String), - SendMessage, + SendMessage(String), Nope, } @@ -48,7 +50,6 @@ impl Component for EventList { let state = State { events: Default::default(), - message: None, }; if props.current_room.is_some() { @@ -59,6 +60,7 @@ impl Component for EventList { } EventList { + on_submit: link.callback(Msg::SendMessage), props, link, matrix_agent, @@ -109,21 +111,13 @@ impl Component for EventList { _ => false, } } - Msg::SetMessage(message) => { - self.state.message = Some(message); - true - } - Msg::SendMessage => { + Msg::SendMessage(message) => { info!("Sending Message"); - if self.state.message.is_some() { - self.matrix_agent.send(Request::SendMessage(( - self.props.current_room.clone().unwrap().room_id, - self.state.message.clone().unwrap(), - ))); - self.state.message = None; - } - - true + self.matrix_agent.send(Request::SendMessage(( + self.props.current_room.clone().unwrap().room_id, + message, + ))); + false } Msg::Nope => false, } @@ -168,21 +162,9 @@ impl Component for EventList { } <div id="anchor"></div> </div> - <form class="uk-margin" - onsubmit=self.link.callback(|e: FocusEvent| {e.prevent_default(); Msg::Nope}) - onkeypress=self.link.callback(|e: KeyboardEvent| { - if e.key() == "Enter" { Msg::SendMessage } else { Msg::Nope } - })> - <div> - <div class="uk-inline" style="display: block !important;"> - <span class="material-icons" id="ma-icon">{"create"}</span> - <input class="uk-input" type="text" - value=&self.state.message.as_ref().unwrap_or(&"".to_string()) - oninput=self.link.callback(|e: InputData| Msg::SetMessage(e.value)) - /> - </div> - </div> - </form> + <div class="uk-margin"> + <Input on_submit=&self.on_submit/> + </div> </div> }; } diff --git a/src/app/components/input.rs b/src/app/components/input.rs @@ -0,0 +1,74 @@ +use yew::prelude::*; + +#[derive(Debug, PartialEq, Clone, Properties)] +pub struct InputProps { + pub on_submit: Callback<String>, +} + +pub struct InputState { + value: Option<String>, +} + +pub struct Input { + on_input: Callback<InputData>, + on_submit: Callback<KeyboardEvent>, + state: InputState, + props: InputProps, +} + +#[allow(clippy::large_enum_variant)] +pub enum Msg { + ValueChange(InputData), + ValueSubmit(KeyboardEvent), +} + +impl Component for Input { + type Message = Msg; + type Properties = InputProps; + + fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self { + let state = InputState { value: None }; + Self { + props, + on_input: link.callback(Msg::ValueChange), + on_submit: link.callback(Msg::ValueSubmit), + state, + } + } + + fn update(&mut self, msg: Self::Message) -> bool { + match msg { + Msg::ValueChange(data) => { + self.state.value = Some(data.value); + true + } + Msg::ValueSubmit(data) => { + if data.key() == "Enter" { + self.props + .on_submit + .emit(self.state.value.as_ref().unwrap_or(&"".to_string()).clone()); + self.state.value = None; + return true; + } + false + } + } + } + + fn change(&mut self, _props: Self::Properties) -> bool { + false + } + + fn view(&self) -> Html { + html! { + <div class="uk-inline" style="display: block !important;"> + <span class="material-icons" id="ma-icon">{"create"}</span> + <input class="uk-input" type="text" + value=&self.state.value.as_ref().unwrap_or(&"".to_string()) + oninput=&self.on_input + onkeypress=&self.on_submit + /> + </div> + } + } +} diff --git a/src/app/components/mod.rs b/src/app/components/mod.rs @@ -1,4 +1,5 @@ pub mod event_list; pub mod events; +pub mod input; pub mod raw_html; pub mod room_list;