From 19585ee11171942f096104c26045fe33727752c1 Mon Sep 17 00:00:00 2001 From: Vika Date: Sun, 25 Aug 2024 13:34:43 +0300 Subject: Bring child components onto the top-level and use a single SoupSession This helps unify HTTP-related settings in one place. In Relm4 Matrix chatroom, it was said that deconstructing child components makes little sense in terms of optimizations. --- src/components/signin.rs | 6 ++-- src/lib.rs | 72 ++++++++++++++++++++++++------------------------ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/components/signin.rs b/src/components/signin.rs index 159711e..c595bde 100644 --- a/src/components/signin.rs +++ b/src/components/signin.rs @@ -181,7 +181,7 @@ impl AsyncComponent for SignIn { type Input = Input; type Output = Output; /// Client ID for authorizing. - type Init = glib::Uri; + type Init = (glib::Uri, soup::Session); view! { #[root] @@ -254,10 +254,10 @@ impl AsyncComponent for SignIn { sender: AsyncComponentSender, ) -> impl std::future::Future> { let model = Self { - client_id: init, + client_id: init.0, me_buffer: Default::default(), - http: soup::Session::new(), + http: init.1, callback_server: None, busy_guard: None, diff --git a/src/lib.rs b/src/lib.rs index d530212..253f8b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ pub mod components { pub use signin::{SignIn, Output as SignInOutput}; } -use components::post_editor::Post; +use components::{post_editor::Post, PostEditorInput}; pub mod secrets; pub mod micropub; @@ -34,14 +34,19 @@ pub const VISIBILITY: [&str; 2] = ["public", "private"]; #[derive(Debug)] pub struct App { - state: AuthState + state: AuthState, + + secret_schema: libsecret::Schema, + http: soup::Session, + + signin: AsyncController, + post_editor: Controller>, } #[derive(Debug)] enum AuthState { - LoggedOut(AsyncController), + LoggedOut, LoggedIn { submit_busy_guard: Option, - post_editor: Controller>, micropub: micropub::Client } } @@ -113,13 +118,7 @@ impl AsyncComponent for App { }, libsecret::SearchFlags::ALL).await { Ok(mut retrievables) => { if retrievables.is_empty() { - AuthState::LoggedOut( - components::SignIn::builder() - .launch(glib::Uri::parse( - CLIENT_ID_STR, glib::UriFlags::NONE - ).unwrap()) - .forward(sender.input_sender(), |o| Self::Input::Authorize(Box::new(o))) - ) + AuthState::LoggedOut } else { retrievables.sort_by_key(|s| s.created()); let retrievable = retrievables.last().unwrap(); @@ -131,9 +130,6 @@ impl AsyncComponent for App { .unwrap(); AuthState::LoggedIn { - post_editor: components::PostEditor::builder() - .launch(None) - .forward(sender.clone().input_sender(), Self::Input::PostEditor), micropub: crate::micropub::Client::new( micropub_uri, retrievable.retrieve_secret_future().await.unwrap().unwrap().text().unwrap().to_string() @@ -144,18 +140,30 @@ impl AsyncComponent for App { }, Err(err) => { log::warn!("Error retrieving secrets: {}", err); - AuthState::LoggedOut( - components::SignIn::builder() - .launch(glib::Uri::parse( - CLIENT_ID_STR, glib::UriFlags::NONE - ).unwrap()) - .forward(sender.input_sender(), |o| Self::Input::Authorize(Box::new(o))) - ) + AuthState::LoggedOut }, }; + let http = soup::Session::builder() + .user_agent(concat!(env!("CARGO_PKG_NAME"),"/",env!("CARGO_PKG_VERSION")," ")) + .build(); let model = App { state, + + http: http.clone(), + secret_schema: crate::secrets::get_schema(), + + post_editor: components::PostEditor::builder() + .launch(None) + .forward(sender.input_sender(), Self::Input::PostEditor), + signin: components::SignIn::builder() + .launch((glib::Uri::parse( + CLIENT_ID_STR, glib::UriFlags::NONE + ).unwrap(), http)) + .forward( + sender.input_sender(), + |o| Self::Input::Authorize(Box::new(o)) + ) }; let mut widgets = Self::Widgets { @@ -187,18 +195,17 @@ impl AsyncComponent for App { fn update_view(&self, widgets: &mut Self::Widgets, _sender: AsyncComponentSender) { // Bind the child component, if any, here. match &self.state { - AuthState::LoggedOut(signin) => { + AuthState::LoggedOut => { widgets.root.set_title(Some("Sign in with your website")); - widgets.toolbar_view.set_content(Some(signin.widget())); + widgets.toolbar_view.set_content(Some(self.signin.widget())); widgets.top_bar_btn.set_visible(false); }, AuthState::LoggedIn { - post_editor, submit_busy_guard, .. } => { widgets.root.set_title(Some("Create post")); - widgets.toolbar_view.set_content(Some(post_editor.widget())); + widgets.toolbar_view.set_content(Some(self.post_editor.widget())); widgets.top_bar_btn.set_sensitive(submit_busy_guard.is_none()); widgets.top_bar_btn.set_visible(true); } @@ -256,9 +263,6 @@ impl AsyncComponent for App { } self.state = AuthState::LoggedIn { - post_editor: components::PostEditor::builder() - .launch(None) - .forward(_sender.clone().input_sender(), Self::Input::PostEditor), micropub: crate::micropub::Client::new( data.micropub.clone(), data.access_token.clone() ), @@ -268,11 +272,10 @@ impl AsyncComponent for App { Input::SubmitButtonPressed => { if let AuthState::LoggedIn { ref mut submit_busy_guard, - ref post_editor, .. } = &mut self.state { *submit_busy_guard = Some(relm4::main_adw_application().mark_busy()); - post_editor.sender().emit(components::PostEditorInput::Submit); + self.post_editor.emit(PostEditorInput::Submit); }; }, Input::PostEditor(None) => { @@ -286,20 +289,17 @@ impl AsyncComponent for App { Input::PostEditor(Some(post)) => { if let AuthState::LoggedIn { ref mut submit_busy_guard, - ref post_editor, - ref micropub, + ref micropub } = &mut self.state { let mf2 = post.into(); log::debug!("Submitting post: {:#}", serde_json::to_string(&mf2).unwrap()); match micropub.send_post(mf2).await { Ok(uri) => { - post_editor.sender() - .emit(components::PostEditorInput::SubmitDone(uri)); + self.post_editor.emit(PostEditorInput::SubmitDone(uri)); }, Err(err) => { log::warn!("Error sending post: {}", err); - post_editor.sender() - .emit(components::PostEditorInput::SubmitError(err)); + self.post_editor.emit(PostEditorInput::SubmitError(err)); } } *submit_busy_guard = None; -- cgit 1.4.1