From 6af9ed87205fa83c0982ac71396a19ef0fb82757 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 29 Dec 2021 20:31:06 +0100 Subject: Extract handling code into helper module Signed-off-by: Matthias Beyer --- gui/src/app/handler.rs | 162 +++++++++++++++++++++++++++++++++++++++++++++++++ gui/src/app/mod.rs | 157 ++--------------------------------------------- 2 files changed, 167 insertions(+), 152 deletions(-) create mode 100644 gui/src/app/handler.rs diff --git a/gui/src/app/handler.rs b/gui/src/app/handler.rs new file mode 100644 index 0000000..a64b34b --- /dev/null +++ b/gui/src/app/handler.rs @@ -0,0 +1,162 @@ +use iced::text_input; +use iced::scrollable; +use tokio::sync::RwLock; + +use crate::app::Distrox; +use crate::app::Message; +use crate::timeline::Timeline; + +pub(super) fn handle_message(app: &mut Distrox, message: Message) -> iced::Command { + log::trace!("Received message: {}", message.description()); + + if let Distrox::Loading { gossip_subscription_recv } = app { + if let Message::Loaded(profile) = message { + *app = Distrox::Loaded { + profile, + + // Don't even try to think what hoops I am jumping through here... + gossip_subscription_recv: std::mem::replace(gossip_subscription_recv, RwLock::new(tokio::sync::oneshot::channel().1)), + scroll: scrollable::State::default(), + input: text_input::State::default(), + input_value: String::default(), + timeline: Timeline::new(), + log_visible: false, + log: std::collections::VecDeque::with_capacity(1000), + }; + return iced::Command::none() + } + } + + match (app, message) { + (Distrox::Loading { .. }, _) => iced::Command::none(), + + (Distrox::Loaded { input_value, .. }, Message::InputChanged(input)) => { + *input_value = input; + iced::Command::none() + }, + + (Distrox::Loaded { profile, input_value, .. }, Message::CreatePost) => { + if !input_value.is_empty() { + let input = input_value.clone(); + let profile = profile.clone(); + log::trace!("Posting..."); + iced::Command::perform(async move { + log::trace!("Posting: '{}'", input); + profile.write().await.post_text(input).await + }, + |res| match res { + Ok(cid) => Message::PostCreated(cid), + Err(e) => Message::PostCreationFailed(e.to_string()) + }) + } else { + iced::Command::none() + } + }, + + (Distrox::Loaded { profile, input_value, .. }, Message::PostCreated(cid)) => { + *input_value = String::new(); + log::info!("Post created: {}", cid); + + let profile = profile.clone(); + iced::Command::perform(async move { + if let Err(e) = profile.read().await.save().await { + Message::ProfileStateSavingFailed(e.to_string()) + } else { + Message::ProfileStateSaved + } + }, |m: Message| -> Message { m }) + }, + + (_, Message::ProfileStateSaved) => { + log::info!("Profile state saved"); + iced::Command::none() + }, + + (_, Message::ProfileStateSavingFailed(e)) => { + log::error!("Saving profile failed: {}", e); + iced::Command::none() + }, + + (_, Message::PostCreationFailed(err)) => { + log::error!("Post creation failed: {}", err); + iced::Command::none() + }, + + (Distrox::Loaded { timeline, .. }, Message::PostLoaded((payload, content))) => { + timeline.push(payload, content); + iced::Command::none() + }, + + (_, Message::PostLoadingFailed) => { + log::error!("Failed to load some post, TODO: Better error logging"); + iced::Command::none() + }, + + (_, Message::TimelineScrolled(f)) => { + log::trace!("Timeline scrolled: {}", f); + iced::Command::none() + }, + + (Distrox::Loaded { log_visible, .. }, Message::ToggleLog) => { + log::trace!("Log toggled"); + *log_visible = !*log_visible; + iced::Command::none() + }, + + (_, Message::GossipMessage(source, msg)) => { + log::trace!("Received Gossip from {}: {:?}", source, msg); + iced::Command::perform(async { + Message::GossipHandled(msg) + }, |m: Message| -> Message { m }) + }, + + (Distrox::Loaded { log, .. }, Message::GossipHandled(msg)) => { + use distrox_lib::gossip::GossipMessage; + + log::trace!("Gossip handled, adding to log: {:?}", msg); + let msg = match msg { + GossipMessage::CurrentProfileState { peer_id, cid } => { + format!("Peer {:?} is at {:?}", peer_id, cid) + } + }; + log.push_back(msg); + while log.len() > 1000 { + let _ = log.pop_front(); + } + iced::Command::none() + }, + + (Distrox::Loaded { profile, .. }, Message::PublishGossipAboutMe) => { + let profile = profile.clone(); + iced::Command::perform(async move { + if let Err(e) = profile.read().await.gossip_own_state("distrox".to_string()).await { + Message::GossippingFailed(e.to_string()) + } else { + Message::OwnStateGossipped + } + }, |m: Message| -> Message { m }) + }, + + (Distrox::Loaded { log, .. }, Message::OwnStateGossipped) => { + log::trace!("Gossipped own state"); + log.push_back("Gossipped own state".to_string()); + iced::Command::none() + }, + + (Distrox::Loaded { log, .. }, Message::GossippingFailed(e)) => { + log::trace!("Gossipped failed: {}", e); + log.push_back(format!("Gossipped failed: {}", e)); + iced::Command::none() + }, + + (Distrox::Loaded { .. }, msg) => { + log::warn!("Unhandled message: {:?}", msg); + iced::Command::none() + } + + (Distrox::FailedToStart, _) => { + unimplemented!() + }, + } +} + diff --git a/gui/src/app/mod.rs b/gui/src/app/mod.rs index ac9e43d..f66bd7c 100644 --- a/gui/src/app/mod.rs +++ b/gui/src/app/mod.rs @@ -19,10 +19,13 @@ use crate::timeline::PostLoadingRecipe; mod message; pub use message::Message; +mod handler; + + use crate::gossip::GossipRecipe; #[derive(Debug)] -enum Distrox { +pub(crate) enum Distrox { Loading { gossip_subscription_recv: RwLock>, }, @@ -86,157 +89,7 @@ impl Application for Distrox { } fn update(&mut self, message: Self::Message) -> iced::Command { - log::trace!("Received message: {}", message.description()); - match self { - Distrox::Loading { gossip_subscription_recv } => { - if let Message::Loaded(profile) = message { - *self = Distrox::Loaded { - profile, - - // Don't even try to think what hoops I am jumping through here... - gossip_subscription_recv: std::mem::replace(gossip_subscription_recv, RwLock::new(tokio::sync::oneshot::channel().1)), - scroll: scrollable::State::default(), - input: text_input::State::default(), - input_value: String::default(), - timeline: Timeline::new(), - log_visible: false, - log: std::collections::VecDeque::with_capacity(1000), - }; - - - } - iced::Command::none() - }, - - Distrox::Loaded { profile, ref mut input_value, timeline, log_visible, log, .. } => { - match message { - Message::InputChanged(input) => { - *input_value = input; - iced::Command::none() - } - - Message::CreatePost => { - if !input_value.is_empty() { - let input = input_value.clone(); - let profile = profile.clone(); - log::trace!("Posting..."); - iced::Command::perform(async move { - log::trace!("Posting: '{}'", input); - profile.write().await.post_text(input).await - }, - |res| match res { - Ok(cid) => Message::PostCreated(cid), - Err(e) => Message::PostCreationFailed(e.to_string()) - }) - } else { - iced::Command::none() - } - } - - Message::PostCreated(cid) => { - *input_value = String::new(); - log::info!("Post created: {}", cid); - - let profile = profile.clone(); - iced::Command::perform(async move { - if let Err(e) = profile.read().await.save().await { - Message::ProfileStateSavingFailed(e.to_string()) - } else { - Message::ProfileStateSaved - } - }, |m: Message| -> Message { m }) - } - - Message::ProfileStateSaved => { - log::info!("Profile state saved"); - iced::Command::none() - }, - - Message::ProfileStateSavingFailed(e) => { - log::error!("Saving profile failed: {}", e); - iced::Command::none() - }, - - Message::PostCreationFailed(err) => { - log::error!("Post creation failed: {}", err); - iced::Command::none() - } - - Message::PostLoaded((payload, content)) => { - timeline.push(payload, content); - iced::Command::none() - } - - Message::PostLoadingFailed => { - log::error!("Failed to load some post, TODO: Better error logging"); - iced::Command::none() - } - - Message::TimelineScrolled(f) => { - log::trace!("Timeline scrolled: {}", f); - iced::Command::none() - } - - Message::ToggleLog => { - log::trace!("Log toggled"); - *log_visible = !*log_visible; - iced::Command::none() - } - - Message::GossipMessage(source, msg) => { - log::trace!("Received Gossip from {}: {:?}", source, msg); - iced::Command::perform(async { - Message::GossipHandled(msg) - }, |m: Message| -> Message { m }) - } - - Message::GossipHandled(msg) => { - use distrox_lib::gossip::GossipMessage; - - log::trace!("Gossip handled, adding to log: {:?}", msg); - let msg = match msg { - GossipMessage::CurrentProfileState { peer_id, cid } => { - format!("Peer {:?} is at {:?}", peer_id, cid) - } - }; - log.push_back(msg); - while log.len() > 1000 { - let _ = log.pop_front(); - } - iced::Command::none() - } - - Message::PublishGossipAboutMe => { - let profile = profile.clone(); - iced::Command::perform(async move { - if let Err(e) = profile.read().await.gossip_own_state("distrox".to_string()).await { - Message::GossippingFailed(e.to_string()) - } else { - Message::OwnStateGossipped - } - }, |m: Message| -> Message { m }) - } - - Message::OwnStateGossipped => { - log::trace!("Gossipped own state"); - log.push_back("Gossipped own state".to_string()); - iced::Command::none() - } - - Message::GossippingFailed(e) => { - log::trace!("Gossipped failed: {}", e); - log.push_back(format!("Gossipped failed: {}", e)); - iced::Command::none() - } - - _ => iced::Command::none(), - } - } - - Distrox::FailedToStart => { - unimplemented!() - } - } + handler::handle_message(self, message) } fn view(&mut self) -> iced::Element { -- cgit v1.2.3