Browse Source

session: Add Supervisor aka EventHandler

The Supervisor implements `matrix_sdk::EventHanlder` and forwards
events to via channels so we can update the UI.
merge-requests/1327/merge
Julian Sparber 5 years ago committed by Alejandro Domínguez
parent
commit
b601f159ad
  1. 1
      src/meson.build
  2. 13
      src/session/content.rs
  3. 9
      src/session/mod.rs
  4. 13
      src/session/sidebar.rs
  5. 90
      src/session/supervisor.rs

1
src/meson.build

@ -28,6 +28,7 @@ sources = files(
'session/mod.rs',
'session/content.rs',
'session/sidebar.rs',
'session/supervisor.rs',
)
custom_target(

13
src/session/content.rs

@ -2,7 +2,8 @@ use adw;
use adw::subclass::prelude::BinImpl;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
use gtk::{glib, CompositeTemplate};
use gtk::{glib, glib::SyncSender, CompositeTemplate};
use matrix_sdk::identifiers::RoomId;
mod imp {
use super::*;
@ -102,4 +103,14 @@ impl FrctlContent {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create FrctlContent")
}
/// Sets up the required channel to recive async updates from the `Client`
pub fn setup_channel(&self) -> SyncSender<RoomId> {
let (sender, receiver) = glib::MainContext::sync_channel::<RoomId>(Default::default(), 100);
receiver.attach(None, move |_room_id| {
//TODO: actually do something: update the message GListModel
glib::Continue(true)
});
sender
}
}

9
src/session/mod.rs

@ -1,8 +1,10 @@
mod content;
mod sidebar;
mod supervisor;
use self::content::FrctlContent;
use self::sidebar::FrctlSidebar;
use self::supervisor::Supervisor;
use crate::secret;
use crate::RUNTIME;
@ -169,8 +171,15 @@ impl FrctlSession {
let client = client.unwrap();
let sidebar_sender = priv_.sidebar.get().setup_channel();
let content_sender = priv_.content.get().setup_channel();
let handler = Supervisor::new(sidebar_sender, content_sender);
RUNTIME.block_on(async {
tokio::spawn(async move {
client.set_event_handler(Box::new(handler)).await;
let success = match method {
CreationMethod::SessionRestore(session) => {
let res = client.restore_login(session).await;

13
src/session/sidebar.rs

@ -2,7 +2,8 @@ use adw;
use adw::subclass::prelude::BinImpl;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
use gtk::{glib, CompositeTemplate};
use gtk::{glib, glib::SyncSender, CompositeTemplate};
use matrix_sdk::{identifiers::RoomId, Client};
mod imp {
use super::*;
@ -102,4 +103,14 @@ impl FrctlSidebar {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create FrctlSidebar")
}
/// Sets up the required channel to recive async updates from the `Client`
pub fn setup_channel(&self) -> SyncSender<RoomId> {
let (sender, receiver) = glib::MainContext::sync_channel::<RoomId>(Default::default(), 100);
receiver.attach(None, move |_room_id| {
//TODO: actually do something: update the message GListModel
glib::Continue(true)
});
sender
}
}

90
src/session/supervisor.rs

@ -0,0 +1,90 @@
use gtk::glib;
use gtk_macros::send;
use log::error;
use matrix_sdk::{
self, async_trait,
events::{
room::{
aliases::AliasesEventContent, avatar::AvatarEventContent,
canonical_alias::CanonicalAliasEventContent, join_rules::JoinRulesEventContent,
message::MessageEventContent, name::NameEventContent, tombstone::TombstoneEventContent,
},
SyncMessageEvent, SyncStateEvent,
},
identifiers::RoomId,
room::Room,
CustomEvent, EventHandler,
};
use serde_json::value::RawValue as RawJsonValue;
use std::sync::{Arc, RwLock};
/// The `Supervisor` implements the `matrix_sdk::EventHandler`.
///
/// The idea is that the `Supervisor` sends a message to a `channel` when a matrix event is
/// received.
/// Every major UI component should provide a `glib::SyncSender<T>` where `T` is the message the UI
/// compnent excpects to receive for a matrix event.
///
pub struct Supervisor {
sidebar: glib::SyncSender<RoomId>,
// TODO: figure out what infromation the content actually needs and should receive from an
// event
content: glib::SyncSender<RoomId>,
/// The ID of the room we want to receive updates for in the content, this is usually the
/// user visible room.
pub room_of_intressed: Arc<RwLock<Option<RoomId>>>,
}
impl Supervisor {
pub fn new(sidebar: glib::SyncSender<RoomId>, content: glib::SyncSender<RoomId>) -> Self {
Self {
sidebar,
content,
room_of_intressed: Arc::new(RwLock::new(None)),
}
}
}
#[async_trait]
impl EventHandler for Supervisor {
async fn on_room_name(&self, room: Room, _: &SyncStateEvent<NameEventContent>) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_room_canonical_alias(
&self,
room: Room,
_: &SyncStateEvent<CanonicalAliasEventContent>,
) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_room_aliases(&self, room: Room, _: &SyncStateEvent<AliasesEventContent>) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_room_avatar(&self, room: Room, _: &SyncStateEvent<AvatarEventContent>) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_room_message(&self, room: Room, _: &SyncMessageEvent<MessageEventContent>) {
// TODO: get the correct event for new notification count
send!(self.sidebar, room.room_id().clone());
send!(self.content, room.room_id().clone());
}
async fn on_room_join_rules(&self, room: Room, _: &SyncStateEvent<JoinRulesEventContent>) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_room_tombstone(&self, room: Room, _: &SyncStateEvent<TombstoneEventContent>) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_unrecognized_event(&self, room: Room, _: &RawJsonValue) {
send!(self.sidebar, room.room_id().clone());
}
async fn on_custom_event(&self, room: Room, _: &CustomEvent<'_>) {
send!(self.sidebar, room.room_id().clone());
}
}
Loading…
Cancel
Save