From eac3d4bc3fe5ff95a1c2e1e3ee00d079533afe5b Mon Sep 17 00:00:00 2001 From: Amanda Graven Date: Mon, 18 Oct 2021 20:59:00 +0200 Subject: [PATCH] Basic timeline and member list --- src/sync.rs | 18 +++++++++-- src/ui/session.rs | 76 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/sync.rs b/src/sync.rs index b77a760..7c544e1 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -6,7 +6,11 @@ use std::sync::{ }; use crossbeam_channel::Sender; -use matrix_sdk::{ruma::RoomId, Client}; +use matrix_sdk::{ + room::Joined, + ruma::{RoomId, UserId}, + Client, RoomMember, +}; use tokio::sync::{mpsc::UnboundedReceiver, Notify}; use url::Url; @@ -20,16 +24,20 @@ pub enum Request { Restore(matrix_sdk::Session), /// Get the calculated name for a room RoomName(RoomId), + /// Get a member from a joined room + JoinedMember(Joined, UserId), /// Stop syncing Quit, } -/// Response to a request. +/// Response produced while running the sync loop. pub enum Response { /// Response from the synchronization loop Sync(matrix_sdk::deserialized_responses::SyncResponse), /// Calculated the name for a room RoomName(RoomId, String), + /// Retrived a member frmo a joined room. + JoinedMember(RoomId, RoomMember), /// An error happened while responding to a request Error(matrix_sdk::Error), } @@ -75,6 +83,7 @@ pub fn run(client: Client, mut request: UnboundedReceiver, response: Se }); } +/// Process an incoming request. async fn handle_request( request: Request, client: Client, @@ -88,6 +97,11 @@ async fn handle_request( Some(room) => response.send(Response::RoomName(room_id, room.display_name().await?))?, None => (), }, + Request::JoinedMember(room, user) => { + if let Some(member) = room.get_member(&user).await? { + response.send(Response::JoinedMember(room.room_id().clone(), member)); + } + } Request::Quit => { dbg!(quit.store(true, Ordering::SeqCst)); QUIT.notify_one(); diff --git a/src/ui/session.rs b/src/ui/session.rs index e6ed39d..50ded11 100644 --- a/src/ui/session.rs +++ b/src/ui/session.rs @@ -1,11 +1,17 @@ -use std::{borrow::Cow, collections::HashMap}; +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, +}; use crossbeam_channel::Receiver; -use eframe::egui::{self, Color32, ScrollArea, Sense}; +use eframe::egui::{self, Color32, Label, ScrollArea, Sense}; use matrix_sdk::{ deserialized_responses::SyncResponse, room::Room, - ruma::{events::AnyRoomEvent, RoomId, UserId}, + ruma::{ + events::{room::message::MessageType, AnyMessageEvent, AnyRoomEvent}, + RoomId, UserId, + }, Client, RoomMember, }; use serde::{Deserialize, Serialize}; @@ -39,6 +45,8 @@ pub struct Timeline { messages: Vec, #[serde(skip)] member: HashMap, + #[serde(skip)] + member_pending: HashSet, } impl RoomList { @@ -136,17 +144,62 @@ impl App { egui::SidePanel::right(Id::MemberList).show(ctx, |ui| { ui.heading("Members"); + let timeline = self.timelines.entry(room.room_id().clone()).or_default(); + for member in timeline.member.values() { + ui.label(member.name()); + } }); - let room = match room { - Room::Joined(room) => room, + let joined = match room { + Room::Joined(ref room) => room, _ => return, }; - let timeline = self.timelines.entry(room.room_id().clone()).or_default(); + egui::CentralPanel::default().show(ctx, |ui| { ScrollArea::auto_sized().show(ui, |ui| { - for message in timeline.messages.iter() { - ui.label(message.sender().as_str()); + let timeline = self.timelines.entry(room.room_id().clone()).or_default(); + for event in timeline.messages.iter() { + let sender = event.sender(); + let name = match timeline.member.get(sender) { + Some(member) => member.name(), + None => { + if !timeline.member_pending.contains(sender) { + self.request + .send(sync::Request::JoinedMember( + joined.clone(), + sender.clone(), + )) + .ok(); + } + sender.localpart() + } + }; + match event { + AnyRoomEvent::Message(AnyMessageEvent::RoomMessage(msg)) => { + match &msg.content.msgtype { + MessageType::Text(text) => { + ui.add(Label::new(name).strong()) + .on_hover_text(event.sender()); + ui.label(&text.body); + } + MessageType::Notice(notice) => { + ui.add(Label::new(name).strong()) + .on_hover_text(event.sender()); + ui.add(egui::Label::new(¬ice.body).weak()); + } + MessageType::ServerNotice(notice) => { + ui.add(Label::new(name).strong()) + .on_hover_text(event.sender()); + ui.add(egui::Label::new(¬ice.body).weak()); + } + MessageType::Emote(emote) => { + ui.label(format!("* {} {}", name, emote.body)); + } + _ => (), + } + } + _ => (), + } } }) }); @@ -157,6 +210,13 @@ impl App { sync::Response::RoomName(room, name) => { self.room_list.room_name.insert(room, name); } + sync::Response::JoinedMember(room, member) => { + self.timelines + .entry(room) + .or_default() + .member + .insert(member.user_id().clone(), member); + } sync::Response::Error(e) => { self.error = Some(e.to_string()); }