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 66c03fca65655190e98a6b3d52da3d304c922a00
parent 4f7710cf33f11c8b032fbdc6ab9f6c0e46dfc56e
Author: Marcel <mtrnord1@gmail.com>
Date:   Mon,  1 Jun 2020 21:39:08 +0200

Install emscripten, only display name on events in the list if required, fix images from sync and display name above images

Took 1 hour 21 minutes

Diffstat:
M.github/workflows/deploy.yml | 9++++++++-
MCargo.toml | 6+++++-
Msrc/app/components/event_list.rs | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/app/matrix/sync.rs | 33+++++++++++++++++++++++++--------
Mstatic/custom-css.scss | 2+-
5 files changed, 110 insertions(+), 30 deletions(-)

diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml @@ -24,8 +24,15 @@ jobs: - name: Install run: yarn + - name: Get emscripten SDK + run: + - wget https://github.com/emscripten-core/emsdk/archive/master.zip + - unzip master.zip + - ./emsdk-master/emsdk install latest + - ./emsdk-master/emsdk activate latest + - name: Build - run: yarn run build + run: source emsdk-master/emsdk_env.sh && yarn run build #- name: Publish # uses: netlify/actions/cli@master diff --git a/Cargo.toml b/Cargo.toml @@ -22,7 +22,7 @@ wee_alloc = "0.4" yew = { git = "https://github.com/yewstack/yew" } yew-router = { git = "https://github.com/yewstack/yew" } yewtil = { git = "https://github.com/yewstack/yew" } -matrix-sdk = { version = "0.1.0", git = "https://github.com/MTRNord/matrix-rust-sdk", branch = "expose-send-rebased", default-features = false} +matrix-sdk = { version = "0.1.0", git = "https://github.com/MTRNord/matrix-rust-sdk", branch = "expose-send-rebased", default-features = false}# features = ["encryption"]} url = "2.1.1" thiserror = "1.0" futures-locks = { git = "https://github.com/asomers/futures-locks", default-features = false } @@ -40,6 +40,10 @@ features = [ 'DomStringMap' ] +[patch.crates-io] +olm-sys = { git = "https://gitlab.gnome.org/stoically/olm-sys", branch = "wasm-target" } +cjson = { git = "https://github.com/engineerd/cjson" } + [profile.release] # less code to include into binary panic = 'abort' diff --git a/src/app/components/event_list.rs b/src/app/components/event_list.rs @@ -163,9 +163,18 @@ impl Component for EventList { <div class="scrollable" style="height: 100%"> { if self.state.events.contains_key(&self.props.current_room.as_ref().unwrap().room_id) { - self.state.events[&self.props.current_room.as_ref().unwrap().room_id].iter().map(|event| self.get_event(event)).collect::<Html>() + let events = self.state.events[&self.props.current_room.as_ref().unwrap().room_id].clone(); + let mut elements: Vec<Html> = Vec::new(); + for (pos, event) in self.state.events[&self.props.current_room.as_ref().unwrap().room_id].iter().enumerate() { + if pos == 0 { + elements.push(self.get_event(None, event)); + } else { + elements.push(self.get_event(Some(&events[pos - 1]), event)); + }; + } + elements.into_iter().collect::<Html>() } else { - html!{} + html! {} } } <div id="anchor"></div> @@ -193,9 +202,19 @@ impl Component for EventList { impl EventList { // Typeinspection of IDEA breaks with this :D //noinspection RsTypeCheck - fn get_event(&self, event: &MessageEvent) -> Html { + fn get_event(&self, prev_event: Option<&MessageEvent>, event: &MessageEvent) -> Html { // TODO make encryption supported + let new_user = if prev_event.is_some() { + if prev_event.unwrap().sender.to_string() == event.sender.to_string() { + false + } else { + true + } + } else { + true + }; + let sender_displayname = { let room = self.props.current_room.as_ref().unwrap(); match room.members.get(&event.sender) { @@ -210,6 +229,18 @@ impl EventList { match &event.content { MessageEventContent::Text(text_event) => { if text_event.formatted_body.is_some() { + let message = if new_user { + format!( + "<displayname>{}:</displayname> {}", + sender_displayname, + text_event.formatted_body.as_ref().unwrap() + ) + } else { + format!( + "{}", + text_event.formatted_body.as_ref().unwrap() + ) + }; let js_text_event = { let div = web_sys::window() .unwrap() @@ -218,12 +249,8 @@ impl EventList { .create_element("p") .unwrap(); div.set_inner_html( - format!( - "<displayname>{}:</displayname> {}", - sender_displayname, - text_event.formatted_body.as_ref().unwrap() - ) - .as_str(), + message + .as_str(), ); div }; @@ -231,14 +258,26 @@ impl EventList { let vnode = VNode::VRef(node); vnode } else { - html! { - <p><displayname>{sender_displayname}{": "}</displayname>{text_event.body.clone()}</p> + if new_user { + html! { + <p><displayname>{sender_displayname}{": "}</displayname>{text_event.body.clone()}</p> + } + } else { + html! { + <p>{text_event.body.clone()}</p> + } } } } MessageEventContent::Notice(notice_event) => { - html! { - <p style="opacity: .6;"><displayname>{sender_displayname}{": "}</displayname>{notice_event.body.clone()}</p> + if new_user { + html! { + <p style="opacity: .6;"><displayname>{sender_displayname}{": "}</displayname>{notice_event.body.clone()}</p> + } + } else { + html! { + <p style="opacity: .6;">{notice_event.body.clone()}</p> + } } } MessageEventContent::Image(image_event) => { @@ -249,12 +288,25 @@ impl EventList { 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 new_user { + html! { + <> + <p><displayname>{sender_displayname}{": "}</displayname></p> + <div uk-lightbox=""> + <a class="uk-inline" href=image_url data-caption=caption > + <img src=thumbnail alt=caption /> + </a> + </div> + </> + } + } else { + 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/sync.rs b/src/app/matrix/sync.rs @@ -2,12 +2,13 @@ use std::time::Duration; use log::*; use matrix_sdk::{ - api::r0::sync::sync_events::Response as SyncResponse, events::collections::all::RoomEvent, + api::r0::sync::sync_events::Response as SyncResponse, events::{collections::all::RoomEvent, room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},}, identifiers::RoomId, Client, SyncSettings, }; use yew::Callback; use crate::app::matrix::Response; +use crate::app::matrix::types::get_media_download_url; pub struct Sync { pub(crate) matrix_client: Client, @@ -42,14 +43,30 @@ impl Sync { async fn on_room_message(&self, room_id: &RoomId, event: RoomEvent) { // TODO handle all messages... - match event { - RoomEvent::RoomMessage(event) => { - let resp = Response::Sync((room_id.clone(), event)); - self.callback.emit(resp); - } - _ => { - return; + if let RoomEvent::RoomMessage(mut event) = event { + if let MessageEventContent::Image(mut image_event) = event.content { + if image_event.url.is_some() { + let new_url = Some(get_media_download_url( + self.matrix_client.clone(), + image_event.url.unwrap(), + )); + image_event.url = new_url; + } + if image_event.info.is_some() { + let mut info = image_event.info.unwrap(); + if info.thumbnail_url.is_some() { + let new_url = Some(get_media_download_url( + self.matrix_client.clone(), + info.thumbnail_url.unwrap(), + )); + info.thumbnail_url = new_url; + } + image_event.info = Some(info); + } + event.content = MessageEventContent::Image(image_event); } + let resp = Response::Sync((room_id.clone(), event.clone())); + self.callback.emit(resp); } } } diff --git a/static/custom-css.scss b/static/custom-css.scss @@ -74,7 +74,7 @@ displayname { font-weight: bold !important; } -.uk-active, .uk-nav-default > li > a:hover, .uk-nav-default > li > a:focus, .uk-nav-header { +.uk-active, .uk-nav-default > li > a:hover, .uk-nav-default > li > a:focus, .uk-nav-header, h1 { font-weight: bold !important; }