Basic timeline and member list

This commit is contained in:
Amanda Graven 2021-10-18 20:59:00 +02:00
parent aa8125dfef
commit eac3d4bc3f
Signed by: amanda
GPG key ID: 45C461CDC9286390
2 changed files with 84 additions and 10 deletions

View file

@ -6,7 +6,11 @@ use std::sync::{
}; };
use crossbeam_channel::Sender; 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 tokio::sync::{mpsc::UnboundedReceiver, Notify};
use url::Url; use url::Url;
@ -20,16 +24,20 @@ pub enum Request {
Restore(matrix_sdk::Session), Restore(matrix_sdk::Session),
/// Get the calculated name for a room /// Get the calculated name for a room
RoomName(RoomId), RoomName(RoomId),
/// Get a member from a joined room
JoinedMember(Joined, UserId),
/// Stop syncing /// Stop syncing
Quit, Quit,
} }
/// Response to a request. /// Response produced while running the sync loop.
pub enum Response { pub enum Response {
/// Response from the synchronization loop /// Response from the synchronization loop
Sync(matrix_sdk::deserialized_responses::SyncResponse), Sync(matrix_sdk::deserialized_responses::SyncResponse),
/// Calculated the name for a room /// Calculated the name for a room
RoomName(RoomId, String), RoomName(RoomId, String),
/// Retrived a member frmo a joined room.
JoinedMember(RoomId, RoomMember),
/// An error happened while responding to a request /// An error happened while responding to a request
Error(matrix_sdk::Error), Error(matrix_sdk::Error),
} }
@ -75,6 +83,7 @@ pub fn run(client: Client, mut request: UnboundedReceiver<Request>, response: Se
}); });
} }
/// Process an incoming request.
async fn handle_request( async fn handle_request(
request: Request, request: Request,
client: Client, client: Client,
@ -88,6 +97,11 @@ async fn handle_request(
Some(room) => response.send(Response::RoomName(room_id, room.display_name().await?))?, Some(room) => response.send(Response::RoomName(room_id, room.display_name().await?))?,
None => (), 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 => { Request::Quit => {
dbg!(quit.store(true, Ordering::SeqCst)); dbg!(quit.store(true, Ordering::SeqCst));
QUIT.notify_one(); QUIT.notify_one();

View file

@ -1,11 +1,17 @@
use std::{borrow::Cow, collections::HashMap}; use std::{
borrow::Cow,
collections::{HashMap, HashSet},
};
use crossbeam_channel::Receiver; use crossbeam_channel::Receiver;
use eframe::egui::{self, Color32, ScrollArea, Sense}; use eframe::egui::{self, Color32, Label, ScrollArea, Sense};
use matrix_sdk::{ use matrix_sdk::{
deserialized_responses::SyncResponse, deserialized_responses::SyncResponse,
room::Room, room::Room,
ruma::{events::AnyRoomEvent, RoomId, UserId}, ruma::{
events::{room::message::MessageType, AnyMessageEvent, AnyRoomEvent},
RoomId, UserId,
},
Client, RoomMember, Client, RoomMember,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -39,6 +45,8 @@ pub struct Timeline {
messages: Vec<AnyRoomEvent>, messages: Vec<AnyRoomEvent>,
#[serde(skip)] #[serde(skip)]
member: HashMap<UserId, RoomMember>, member: HashMap<UserId, RoomMember>,
#[serde(skip)]
member_pending: HashSet<UserId>,
} }
impl RoomList { impl RoomList {
@ -136,17 +144,62 @@ impl App {
egui::SidePanel::right(Id::MemberList).show(ctx, |ui| { egui::SidePanel::right(Id::MemberList).show(ctx, |ui| {
ui.heading("Members"); 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 { let joined = match room {
Room::Joined(room) => room, Room::Joined(ref room) => room,
_ => return, _ => return,
}; };
let timeline = self.timelines.entry(room.room_id().clone()).or_default();
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ScrollArea::auto_sized().show(ui, |ui| { ScrollArea::auto_sized().show(ui, |ui| {
for message in timeline.messages.iter() { let timeline = self.timelines.entry(room.room_id().clone()).or_default();
ui.label(message.sender().as_str()); 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(&notice.body).weak());
}
MessageType::ServerNotice(notice) => {
ui.add(Label::new(name).strong())
.on_hover_text(event.sender());
ui.add(egui::Label::new(&notice.body).weak());
}
MessageType::Emote(emote) => {
ui.label(format!("* {} {}", name, emote.body));
}
_ => (),
}
}
_ => (),
}
} }
}) })
}); });
@ -157,6 +210,13 @@ impl App {
sync::Response::RoomName(room, name) => { sync::Response::RoomName(room, name) => {
self.room_list.room_name.insert(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) => { sync::Response::Error(e) => {
self.error = Some(e.to_string()); self.error = Some(e.to_string());
} }