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:
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;