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 043d37301b88affded2871c8f4564ef5351e791b
parent 457f22b7104e41ce40d6c2ef78da3a8c8e55414b
Author: Marcel <mtrnord1@gmail.com>
Date:   Mon,  1 Jun 2020 16:16:59 +0200

Add formatted body, fix minor issues with encrypted rooms and images, fix scrollbar in chrome

Took 29 minutes

Diffstat:
Msrc/app/components/event_list.rs | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/app/matrix.rs | 4++--
Msrc/app/matrix/sync.rs | 4+++-
Mstatic/custom-css.scss | 21++++++++++++++++++++-
4 files changed, 95 insertions(+), 34 deletions(-)

diff --git a/src/app/components/event_list.rs b/src/app/components/event_list.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::convert::TryFrom; use log::*; use matrix_sdk::{ @@ -6,7 +7,9 @@ use matrix_sdk::{ identifiers::{EventId, RoomId}, Room, }; +use web_sys::Node; use yew::prelude::*; +use yew::virtual_dom::VNode; use crate::app::matrix::{MatrixAgent, Request, Response}; @@ -71,7 +74,7 @@ impl Component for EventList { match response { Response::Sync((room_id, msg)) => { // TODO handle all events - if self.state.events.contains_key(&room_id) { + return if self.state.events.contains_key(&room_id) { if !(self.state.events[&room_id] .iter() .map(|x| x.event_id.clone()) @@ -79,17 +82,26 @@ impl Component for EventList { .contains(&msg.event_id)) { self.state.events.get_mut(&room_id).unwrap().push(msg); - return true; + return if room_id + == self.props.current_room.clone().unwrap().room_id + { + true + } else { + false + }; } else { - return false; + false } } else { let mut msgs = Vec::new(); msgs.push(msg); - self.state.events.insert(room_id, msgs); - return true; - } - return false; + self.state.events.insert(room_id.clone(), msgs); + return if room_id == self.props.current_room.clone().unwrap().room_id { + true + } else { + false + }; + }; } Response::OldMessages((room_id, mut messages)) => { if self.state.events.contains_key(&room_id) { @@ -182,44 +194,72 @@ impl EventList { // Typeinspection of IDEA breaks with this :D //noinspection RsTypeCheck fn get_event(&self, event: &MessageEvent) -> Html { + // TODO make encryption supported + let sender_displayname = { let room = self.props.current_room.as_ref().unwrap(); match room.members.get(&event.sender) { - None => { event.sender.to_string() } - Some(member) => { - member - .display_name - .as_ref() - .map(ToString::to_string) - .unwrap_or(event.sender.to_string()) - } + None => event.sender.to_string(), + Some(member) => member + .display_name + .as_ref() + .map(ToString::to_string) + .unwrap_or(event.sender.to_string()), } }; match &event.content { MessageEventContent::Text(text_event) => { - html! { - <p>{sender_displayname}{": "}{text_event.body.clone()}</p> + if text_event.formatted_body.is_some() { + let js_text_event = { + let div = web_sys::window() + .unwrap() + .document() + .unwrap() + .create_element("p") + .unwrap(); + div.set_inner_html( + format!( + "<displayname>{}:</displayname> {}", + sender_displayname, + text_event.formatted_body.as_ref().unwrap() + ) + .as_str(), + ); + div + }; + info!("js_text_event: {:?}", js_text_event); + let node = Node::from(js_text_event); + let vnode = VNode::VRef(node); + info!("js_text_event: {:?}", vnode); + vnode + } else { + html! { + <p><displayname>{sender_displayname}{": "}</displayname>{text_event.body.clone()}</p> + } } } MessageEventContent::Notice(notice_event) => { html! { - <p style="opacity: .6;">{sender_displayname}{": "}{notice_event.body.clone()}</p> + <p style="opacity: .6;"><displayname>{sender_displayname}{": "}</displayname>{notice_event.body.clone()}</p> } } MessageEventContent::Image(image_event) => { let caption = format!("{}: {}", sender_displayname, image_event.body); - - let image_url = image_event.url.clone().unwrap(); - let thumbnail = match image_event.info.clone().unwrap().thumbnail_url { - None => image_url.clone(), - Some(v) => v, - }; - html! { - <div uk-lightbox=""> - <a class="uk-inline" href=image_url data-caption=caption > - <img src=thumbnail alt=caption /> - </a> - </div> + if image_event.url.clone().is_some() { + let image_url = image_event.url.clone().unwrap(); + let thumbnail = match image_event.info.clone().unwrap().thumbnail_url { + None => image_url.clone(), + Some(v) => v, + }; + html! { + <div uk-lightbox=""> + <a class="uk-inline" href=image_url data-caption=caption > + <img src=thumbnail alt=caption /> + </a> + </div> + } + } else { + html! {} } } _ => { diff --git a/src/app/matrix.rs b/src/app/matrix.rs @@ -343,12 +343,12 @@ impl Agent for MatrixAgent { Request::SendMessage((room_id, message)) => { let client = self.matrix_client.clone().unwrap(); spawn_local(async move { - let mut options = Options::empty(); options.insert(Options::ENABLE_STRIKETHROUGH); let parser = Parser::new_ext(message.as_str(), options); - let mut formatted_message: String = String::with_capacity(message.len() * 3 / 2); + let mut formatted_message: String = + String::with_capacity(message.len() * 3 / 2); html::push_html(&mut formatted_message, parser); formatted_message = formatted_message.replace("<p>", "").replace("</p>", ""); formatted_message.pop(); diff --git a/src/app/matrix/sync.rs b/src/app/matrix/sync.rs @@ -17,7 +17,9 @@ pub struct Sync { impl Sync { pub async fn start_sync(&self) { let client = self.matrix_client.clone(); - let settings = SyncSettings::default().timeout(Duration::from_secs(30)).full_state(true); + let settings = SyncSettings::default() + .timeout(Duration::from_secs(30)) + .full_state(true); client .sync_forever(settings, |response| self.on_sync_response(response)) diff --git a/static/custom-css.scss b/static/custom-css.scss @@ -20,7 +20,12 @@ } .scrollable::-webkit-scrollbar { - width: 11px; + width: 5px; + background: $scrollbar-bg-color; +} + +.scrollable::-webkit-scrollbar-thumb { + background: $scrollbar-color; } .non-scrollable-container { @@ -54,3 +59,17 @@ body { width: 20rem; padding: 1.5rem; } + +blockquote { + margin: 0 0 10px 0 !important; + font-size: 16px !important; + line-height: 1.5 !important; + border-left: 4px solid #ddd !important; + padding-left: 2px !important; + font-style: italic !important; + color: var(--global-emphasis-color) !important; +} + +displayname { + font-weight: bold !important; +}