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 218f9943a95e7fd742ecdb75eb8d8f4efb7eeea0
parent 8590e3b1fc3d0e9c6d62096126dad2083666b273
Author: Jonas Platte <jplatte+git@posteo.de>
Date:   Fri,  3 Jul 2020 20:45:49 +0200

Clone things less

Diffstat:
Msrc/app/components/event_list.rs | 11++++++-----
Msrc/app/components/events/image.rs | 37++++++++++---------------------------
Msrc/app/components/events/mod.rs | 6+++---
Msrc/app/components/events/notice.rs | 10+++++-----
Msrc/app/components/events/text.rs | 10+++++-----
Msrc/app/components/events/video.rs | 46+++++++++++++++-------------------------------
Msrc/app/components/room_list/mod.rs | 32++++++++++++++++++++++----------
Msrc/app/matrix/mod.rs | 12++++++------
Msrc/app/matrix/sync.rs | 23++++++++++++-----------
9 files changed, 84 insertions(+), 103 deletions(-)

diff --git a/src/app/components/event_list.rs b/src/app/components/event_list.rs @@ -52,7 +52,7 @@ impl Component for EventList { }; if props.current_room.is_some() { - let room_id = props.current_room.clone().unwrap().room_id; + let room_id = props.current_room.as_ref().unwrap().room_id.clone(); if !state.events.contains_key(&room_id) { matrix_agent.send(Request::GetOldMessages((room_id, None))); } @@ -79,14 +79,15 @@ impl Component for EventList { .any(|x| x.event_id == msg.event_id)) { self.state.events.get_mut(&room_id).unwrap().push(msg); - room_id == self.props.current_room.clone().unwrap().room_id + room_id + == self.props.current_room.as_ref().unwrap().room_id } else { false } } else { let msgs = vec![msg]; self.state.events.insert(room_id.clone(), msgs); - room_id == self.props.current_room.clone().unwrap().room_id + room_id == self.props.current_room.as_ref().unwrap().room_id } } else { false @@ -119,7 +120,7 @@ impl Component for EventList { Msg::SendMessage(message) => { info!("Sending Message"); self.matrix_agent.send(Request::SendMessage(( - self.props.current_room.clone().unwrap().room_id, + self.props.current_room.as_ref().unwrap().room_id.clone(), message, ))); false @@ -131,7 +132,7 @@ impl Component for EventList { fn change(&mut self, props: Self::Properties) -> bool { if self.props != props { if props.current_room.is_some() { - let room_id = props.clone().current_room.unwrap().room_id; + let room_id = props.current_room.as_ref().unwrap().room_id.clone(); if !self.state.events.contains_key(&room_id) { self.matrix_agent .send(Request::GetOldMessages((room_id, None))); diff --git a/src/app/components/events/image.rs b/src/app/components/events/image.rs @@ -48,48 +48,31 @@ impl Component for Image { //noinspection RsTypeCheck fn view(&self) -> Html { let new_user = is_new_user( - self.props.prev_event.clone(), - self.props.event.clone().unwrap(), + self.props.prev_event.as_ref(), + self.props.event.as_ref().unwrap(), ); let sender_displayname = if new_user { get_sender_displayname( - self.props.room.clone().unwrap(), - self.props.event.clone().unwrap(), + self.props.room.as_ref().unwrap(), + self.props.event.as_ref().unwrap(), ) } else { "".to_string() }; - if self - .props - .image_event - .as_ref() - .unwrap() - .url - .clone() - .is_some() - { - let image_url = self - .props - .image_event - .as_ref() - .unwrap() - .url - .clone() - .unwrap(); - let thumbnail = match self + if let Some(image_url) = &self.props.image_event.as_ref().unwrap().url { + let thumbnail = self .props .image_event .as_ref() .unwrap() .info - .clone() + .as_ref() .unwrap() .thumbnail_url - { - None => image_url.clone(), - Some(v) => v, - }; + .as_ref() + .unwrap_or(image_url); + let lightbox_id: u8 = random(); let lightbox_id_full = format!("image_{}", lightbox_id); let lightbox_href_full = format!("#image_{}", lightbox_id); diff --git a/src/app/components/events/mod.rs b/src/app/components/events/mod.rs @@ -8,7 +8,7 @@ pub mod notice; pub mod text; pub mod video; -pub fn is_new_user(prev_event: Option<MessageEvent>, event: MessageEvent) -> bool { +pub fn is_new_user(prev_event: Option<&MessageEvent>, event: &MessageEvent) -> bool { if let Some(prev_event) = prev_event { prev_event.sender != event.sender } else { @@ -16,7 +16,7 @@ pub fn is_new_user(prev_event: Option<MessageEvent>, event: MessageEvent) -> boo } } -pub fn get_sender_displayname(room: Room, event: MessageEvent) -> String { +pub fn get_sender_displayname(room: &Room, event: &MessageEvent) -> String { match room.members.get(&event.sender) { None => event.sender.to_string(), Some(member) => member @@ -27,7 +27,7 @@ pub fn get_sender_displayname(room: Room, event: MessageEvent) -> String { } } -pub fn get_sender_avatar(homeserver_url: Url, room: Room, event: MessageEvent) -> Option<String> { +pub fn get_sender_avatar(homeserver_url: Url, room: &Room, event: &MessageEvent) -> Option<String> { room.members.get(&event.sender).and_then(|member| { member .avatar_url diff --git a/src/app/components/events/notice.rs b/src/app/components/events/notice.rs @@ -51,19 +51,19 @@ impl Component for Notice { //noinspection RsTypeCheck fn view(&self) -> Html { let new_user = is_new_user( - self.props.prev_event.clone(), - self.props.event.clone().unwrap(), + self.props.prev_event.as_ref(), + self.props.event.as_ref().unwrap(), ); let sender_displayname = if new_user { get_sender_displayname( - self.props.room.clone().unwrap(), - self.props.event.clone().unwrap(), + self.props.room.as_ref().unwrap(), + self.props.event.as_ref().unwrap(), ) } else { "".to_string() }; - let mut pure_content = self.props.notice_event.clone().unwrap().body; + let mut pure_content = self.props.notice_event.as_ref().unwrap().body.clone(); let finder = LinkFinder::new(); let pure_content_clone = pure_content.clone(); let links: Vec<_> = finder.links(&pure_content_clone).collect(); diff --git a/src/app/components/events/text.rs b/src/app/components/events/text.rs @@ -50,19 +50,19 @@ impl Component for Text { //noinspection RsTypeCheck fn view(&self) -> Html { let new_user = is_new_user( - self.props.prev_event.clone(), - self.props.event.clone().unwrap(), + self.props.prev_event.as_ref(), + self.props.event.as_ref().unwrap(), ); let sender_displayname = if new_user { get_sender_displayname( - self.props.room.clone().unwrap(), - self.props.event.clone().unwrap(), + self.props.room.as_ref().unwrap(), + self.props.event.as_ref().unwrap(), ) } else { "".to_string() }; - let mut pure_content = self.props.text_event.clone().unwrap().body; + let mut pure_content = self.props.text_event.as_ref().unwrap().body.clone(); let finder = LinkFinder::new(); let pure_content_clone = pure_content.clone(); let links: Vec<_> = finder.links(&pure_content_clone).collect(); diff --git a/src/app/components/events/video.rs b/src/app/components/events/video.rs @@ -48,13 +48,13 @@ impl Component for Video { //noinspection RsTypeCheck fn view(&self) -> Html { let new_user = is_new_user( - self.props.prev_event.clone(), - self.props.event.clone().unwrap(), + self.props.prev_event.as_ref(), + self.props.event.as_ref().unwrap(), ); let sender_displayname = if new_user { get_sender_displayname( - self.props.room.clone().unwrap(), - self.props.event.clone().unwrap(), + self.props.room.as_ref().unwrap(), + self.props.event.as_ref().unwrap(), ) } else { "".to_string() @@ -65,36 +65,20 @@ impl Component for Video { sender_displayname, self.props.video_event.as_ref().unwrap().body ); - if self - .props - .video_event - .as_ref() - .unwrap() - .url - .clone() - .is_some() - { - let video_url = self - .props - .video_event - .as_ref() - .unwrap() - .url - .clone() - .unwrap(); - let thumbnail = match self + + if let Some(video_url) = self.props.video_event.as_ref().unwrap().url.as_ref() { + let thumbnail = self .props .video_event .as_ref() .unwrap() .info - .clone() + .as_ref() .unwrap() .thumbnail_url - { - None => video_url.clone(), - Some(v) => v, - }; + .as_ref() + .unwrap_or(video_url); + let lightbox_id: u8 = random(); let lightbox_id_full = format!("video_{}", lightbox_id); let lightbox_href_full = format!("#video_{}", lightbox_id); @@ -102,8 +86,8 @@ impl Component for Video { html! { <div> <p><displayname>{sender_displayname}{": "}</displayname></p> - <a href={lightbox_href_full.clone()}><img src=thumbnail/></a> - <div class="lightbox short-animate" id={lightbox_id_full.clone()}> + <a href={lightbox_href_full}><img src=thumbnail/></a> + <div class="lightbox short-animate" id={lightbox_id_full}> <video class="long-animate" controls=true> <source src=video_url type="video/mp4"/> {"Your browser does not support the video tag."} @@ -117,8 +101,8 @@ impl Component for Video { } else { html! { <div> - <a href={lightbox_href_full.clone()}><img src=thumbnail/></a> - <div class="lightbox short-animate" id={lightbox_id_full.clone()}> + <a href={lightbox_href_full}><img src=thumbnail/></a> + <div class="lightbox short-animate" id={lightbox_id_full}> <video class="long-animate" controls=true> <source src=video_url type="video/mp4"/> {"Your browser does not support the video tag."} diff --git a/src/app/components/room_list/mod.rs b/src/app/components/room_list/mod.rs @@ -144,6 +144,27 @@ impl Component for RoomList { </div> } } else { + let rooms = if self.state.search_query.is_none() + || (self.state.search_query.as_ref().unwrap_or(&"".to_string()) == &"".to_string()) + { + self.state + .rooms + .iter() + .map(|(_, room)| self.get_room(room)) + .collect::<Html>() + } else { + self.state + .rooms + .iter() + .filter(|(_, room)| { + room.display_name() + .to_lowercase() + .contains(&self.state.search_query.as_ref().unwrap().to_lowercase()) + }) + .map(|(_, room)| self.get_room(room)) + .collect::<Html>() + }; + html! { <div class="roomlist" style="height: 100%"> <div class="top-bar"> @@ -166,16 +187,7 @@ impl Component for RoomList { </div> </div> </div> - - <div class="scrollable list"> - { - if self.state.search_query.is_none() || (self.state.search_query.as_ref().unwrap_or(&"".to_string()) == &"".to_string()) { - self.state.rooms.iter().map(|(_, room)| self.get_room(room)).collect::<Html>() - } else { - self.state.rooms.iter().filter(|(_, room)| room.display_name().to_lowercase().contains(&self.state.search_query.as_ref().unwrap().to_lowercase())).map(|(_, room)| self.get_room(room)).collect::<Html>() - } - } - </div> + <div class="scrollable list">{rooms}</div> <div class="bottom-bar"> <div class="toggleWrapper"> <input type="checkbox" class="dn" id="dn" checked=self.state.dark_theme value=self.state.dark_theme onclick=self.link.callback(|e: MouseEvent| {Msg::ToggleTheme})/> diff --git a/src/app/matrix/mod.rs b/src/app/matrix/mod.rs @@ -308,7 +308,7 @@ impl Agent for MatrixAgent { { if image_event.url.is_some() { let new_url = Some(get_media_download_url( - agent.matrix_client.clone().unwrap().homeserver(), + agent.matrix_client.as_ref().unwrap().homeserver(), image_event.url.unwrap(), )); image_event.url = new_url; @@ -317,7 +317,7 @@ impl Agent for MatrixAgent { let mut info = image_event.info.unwrap(); if info.thumbnail_url.is_some() { let new_url = Some(get_media_download_url( - agent.matrix_client.clone().unwrap().homeserver(), + agent.matrix_client.as_ref().unwrap().homeserver(), info.thumbnail_url.unwrap(), )); info.thumbnail_url = new_url; @@ -329,7 +329,7 @@ impl Agent for MatrixAgent { if let MessageEventContent::Video(mut video_event) = event.content { if video_event.url.is_some() { let new_url = Some(get_video_media_download_url( - agent.matrix_client.clone().unwrap().homeserver(), + agent.matrix_client.as_ref().unwrap().homeserver(), video_event.url.unwrap(), )); video_event.url = new_url; @@ -338,7 +338,7 @@ impl Agent for MatrixAgent { let mut info = video_event.info.unwrap(); if info.thumbnail_url.is_some() { let new_url = Some(get_media_download_url( - agent.matrix_client.clone().unwrap().homeserver(), + agent.matrix_client.as_ref().unwrap().homeserver(), info.thumbnail_url.unwrap(), )); info.thumbnail_url = new_url; @@ -441,10 +441,10 @@ impl MatrixAgent { info!("preparing client"); if self.session.is_some() { info!("restoring login"); - let homeserver = self.session.clone().unwrap().homeserver_url; + let homeserver = &self.session.as_ref().unwrap().homeserver_url; let client_config = ClientConfig::new(); - let homeserver_url = Url::parse(&homeserver).unwrap(); + let homeserver_url = Url::parse(homeserver).unwrap(); let client = Client::new_with_config(homeserver_url, client_config).unwrap(); self.matrix_client = Some(client.clone()); diff --git a/src/app/matrix/sync.rs b/src/app/matrix/sync.rs @@ -89,7 +89,7 @@ impl Sync { } if let RoomEvent::RoomMessage(mut event) = event { - if let MessageEventContent::Text(text_event) = event.clone().content { + if let MessageEventContent::Text(text_event) = event.content.clone() { let homeserver_url = self.matrix_client.clone().homeserver().clone(); let cloned_event = event.clone(); @@ -100,18 +100,19 @@ impl Sync { spawn_local(async move { let room: Arc<RwLock<Room>> = client .clone() - .get_joined_room(&local_room_id.clone()) + .get_joined_room(&local_room_id) .await .unwrap(); - let read_clone = room.read().await; - let clean_room = (*read_clone).clone(); - let avatar_url = get_sender_avatar( - homeserver_url, - clean_room.clone(), - cloned_event.clone(), - ); - let room_name = clean_room.display_name(); - let displayname = get_sender_displayname(clean_room, cloned_event.clone()); + + let (avatar_url, room_name, displayname) = { + let room = room.read().await; + + ( + get_sender_avatar(homeserver_url, &room, &cloned_event), + room.display_name(), + get_sender_displayname(&room, &cloned_event), + ) + }; let title = if displayname == room_name { displayname