summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2024-08-25 13:34:43 +0300
committerVika <vika@fireburn.ru>2024-08-25 13:34:43 +0300
commit19585ee11171942f096104c26045fe33727752c1 (patch)
tree09327e13a0203dbc177f37d88ccdb6f7789952fd /src
parent847648330cc0e7af59fa6923f45222726d404250 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/components/signin.rs6
-rw-r--r--src/lib.rs72
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<Self>,
     ) -> impl std::future::Future<Output = AsyncComponentParts<Self>> {
         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<components::SignIn>,
+    post_editor: Controller<components::PostEditor<micropub::Error>>,
 }
 #[derive(Debug)]
 enum AuthState {
-    LoggedOut(AsyncController<components::SignIn>),
+    LoggedOut,
     LoggedIn {
         submit_busy_guard: Option<gtk::gio::ApplicationBusyGuard>,
-        post_editor: Controller<components::PostEditor<micropub::Error>>,
         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<Self>) {
         // 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;