[fractal/fractal-next] session: Add Supervisor aka EventHandler
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] session: Add Supervisor aka EventHandler
- Date: Sat, 27 Mar 2021 18:13:18 +0000 (UTC)
commit b601f159ad1d26449c13ac62a5e0b8d21acf48a1
Author: Julian Sparber <julian sparber net>
Date: Wed Mar 24 12:05:21 2021 +0100
session: Add Supervisor aka EventHandler
The Supervisor implements `matrix_sdk::EventHanlder` and forwards
events to via channels so we can update the UI.
src/meson.build | 1 +
src/session/content.rs | 13 ++++++-
src/session/mod.rs | 9 +++++
src/session/sidebar.rs | 13 ++++++-
src/session/supervisor.rs | 90 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 124 insertions(+), 2 deletions(-)
---
diff --git a/src/meson.build b/src/meson.build
index d03ab188..27d6c064 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -28,6 +28,7 @@ sources = files(
'session/mod.rs',
'session/content.rs',
'session/sidebar.rs',
+ 'session/supervisor.rs',
)
custom_target(
diff --git a/src/session/content.rs b/src/session/content.rs
index 112a3c48..eab6b0b9 100644
--- a/src/session/content.rs
+++ b/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
+ }
}
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 9f38105a..a131c9e8 100644
--- a/src/session/mod.rs
+++ b/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;
diff --git a/src/session/sidebar.rs b/src/session/sidebar.rs
index 10a9c4df..19396b39 100644
--- a/src/session/sidebar.rs
+++ b/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
+ }
}
diff --git a/src/session/supervisor.rs b/src/session/supervisor.rs
new file mode 100644
index 00000000..70c4fcd6
--- /dev/null
+++ b/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());
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]