summary refs log tree commit diff
path: root/src/components
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2024-09-04 22:15:32 +0300
committerVika <vika@fireburn.ru>2024-09-04 22:15:32 +0300
commit406509dc549cb58d788a3dbd5572f28008c84546 (patch)
treeaff6115c0bfbd12ca447503d6d850feccfd9ad89 /src/components
parentf16cac2d35487b1772d1c2524ed223c779f45f23 (diff)
downloadbowl-406509dc549cb58d788a3dbd5572f28008c84546.tar.zst
Make LLM enhancements optional
Diffstat (limited to 'src/components')
-rw-r--r--src/components/post_editor.rs45
-rw-r--r--src/components/preferences.rs137
-rw-r--r--src/components/smart_summary.rs1
3 files changed, 125 insertions, 58 deletions
diff --git a/src/components/post_editor.rs b/src/components/post_editor.rs
index f2268ad..c42b06a 100644
--- a/src/components/post_editor.rs
+++ b/src/components/post_editor.rs
@@ -1,11 +1,12 @@
 use gettextrs::*;
-use crate::components;
 use crate::components::tag_pill::*;
 use adw::prelude::*;
 
 use glib::translate::IntoGlib;
 use gtk::GridLayoutChild;
-use relm4::{gtk, prelude::{ComponentController, Controller, DynamicIndex}, factory::FactoryVecDeque, Component, ComponentParts, ComponentSender, RelmWidgetExt};
+use relm4::{factory::FactoryVecDeque, gtk, prelude::{Controller, DynamicIndex}, Component, ComponentParts, ComponentSender, RelmWidgetExt};
+#[cfg(feature = "smart-summary")]
+use relm4::prelude::ComponentController;
 
 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, glib::Enum)]
 #[enum_type(name = "MicropubVisibility")]
@@ -87,7 +88,8 @@ pub(crate) struct PostEditor<E> {
 
     #[do_not_track] wide_layout: gtk::GridLayout,
 
-    #[do_not_track] smart_summary: Controller<components::SmartSummaryButton>,
+    #[cfg(feature = "smart-summary")]
+    #[do_not_track] smart_summary: Controller<crate::components::SmartSummaryButton>,
     _err: std::marker::PhantomData<E>
 }
 
@@ -104,7 +106,8 @@ impl<E> PostEditor<E> {
 #[allow(private_interfaces)] // intentional
 #[allow(clippy::manual_non_exhaustive)] // false positive
 pub enum Input<E: std::error::Error + std::fmt::Debug + Send + 'static> {
-    #[doc(hidden)] SmartSummary(components::smart_summary::Output),
+    #[cfg(feature = "smart-summary")]
+    #[doc(hidden)] SmartSummary(crate::components::smart_summary::Output),
     #[doc(hidden)] VisibilitySelected(Visibility),
     #[doc(hidden)] AddTagFromBuffer,
     #[doc(hidden)] RemoveTag(DynamicIndex),
@@ -115,7 +118,10 @@ pub enum Input<E: std::error::Error + std::fmt::Debug + Send + 'static> {
 
 #[relm4::component(pub)]
 impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for PostEditor<E> {
-    type Init = (<components::SmartSummaryButton as relm4::Component>::Init, Option<Post>);
+    #[cfg(feature = "smart-summary")]
+    type Init = (soup::Session, Option<Post>);
+    #[cfg(not(feature = "smart-summary"))]
+    type Init = Option<Post>;
     type Output = Option<Post>;
     type Input = Input<E>;
     type CommandOutput = ();
@@ -169,8 +175,6 @@ impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for Post
                                 #[track = "model.busy_changed()"]
                                 set_sensitive: !model.busy(),
                             },
-
-                            model.smart_summary.widget(),
                         },
 
                         #[name = "tag_label"]
@@ -331,10 +335,13 @@ impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for Post
     }
 
     fn init(
-        (http, init): Self::Init,
+        init: Self::Init,
         root: Self::Root,
         sender: ComponentSender<Self>
     ) -> ComponentParts<Self> {
+        #[cfg(feature = "smart-summary")]
+        let (http, init) = init;
+
         let mut model = Self {
             smart_summary_busy_guard: None,
             sending: false,
@@ -359,7 +366,8 @@ impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for Post
 
             wide_layout: gtk::GridLayout::new(),
 
-            smart_summary: components::SmartSummaryButton::builder()
+            #[cfg(feature = "smart-summary")]
+            smart_summary: crate::components::SmartSummaryButton::builder()
                 .launch(http)
                 .forward(sender.input_sender(), Input::SmartSummary),
 
@@ -371,6 +379,9 @@ impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for Post
 
         let widgets = view_output!();
 
+        #[cfg(feature = "smart-summary")]
+        widgets.summary_field.append(model.smart_summary.widget());
+
         widgets.visibility_selector.set_expression(Some(
             gtk::ClosureExpression::new::<String>(
                 [] as [gtk::Expression; 0],
@@ -459,11 +470,12 @@ impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for Post
     fn update_with_view(&mut self, widgets: &mut Self::Widgets, msg: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
         self.reset();
         match msg {
-            Input::SmartSummary(components::SmartSummaryOutput::Start) => {
+            #[cfg(feature = "smart-summary")]
+            Input::SmartSummary(crate::components::SmartSummaryOutput::Start) => {
                 widgets.content_textarea.set_sensitive(false);
                 if self.content_buffer.char_count() == 0 {
                     let _ = self.smart_summary.sender().send(
-                        components::SmartSummaryInput::Cancel
+                        crate::components::SmartSummaryInput::Cancel
                     );
                 } else {
                     let text = self.content_buffer.text(
@@ -476,20 +488,23 @@ impl<E: std::error::Error + std::fmt::Debug + Send + 'static> Component for Post
                         Some(relm4::main_adw_application().mark_busy())
                     );
                     if self.smart_summary.sender().send(
-                        components::SmartSummaryInput::Text(text.into())
+                        crate::components::SmartSummaryInput::Text(text.into())
                     ).is_ok() {
                         self.summary_buffer.set_text("");
                     }
                 }
                 widgets.content_textarea.set_sensitive(true);
             },
-            Input::SmartSummary(components::SmartSummaryOutput::Chunk(text)) => {
+            #[cfg(feature = "smart-summary")]
+            Input::SmartSummary(crate::components::SmartSummaryOutput::Chunk(text)) => {
                 self.summary_buffer.insert_text(self.summary_buffer.length(), text);
             },
-            Input::SmartSummary(components::SmartSummaryOutput::Done) => {
+            #[cfg(feature = "smart-summary")]
+            Input::SmartSummary(crate::components::SmartSummaryOutput::Done) => {
                 self.set_smart_summary_busy_guard(None);
             },
-            Input::SmartSummary(components::SmartSummaryOutput::Error(err)) => {
+            #[cfg(feature = "smart-summary")]
+            Input::SmartSummary(crate::components::SmartSummaryOutput::Error(err)) => {
                 self.set_smart_summary_busy_guard(None);
 
                 let toast = adw::Toast::new(&gettext!("Smart Summary error: {}", err));
diff --git a/src/components/preferences.rs b/src/components/preferences.rs
index 9bbc313..fbf406d 100644
--- a/src/components/preferences.rs
+++ b/src/components/preferences.rs
@@ -1,4 +1,3 @@
-use gettextrs::*;
 use gio::prelude::*;
 use adw::prelude::*;
 use relm4::prelude::*;
@@ -7,38 +6,100 @@ pub struct Preferences {
     settings: gio::Settings,
 }
 
-#[relm4::component(pub)]
+#[cfg(feature = "smart-summary")]
+#[allow(dead_code)]
+struct LanguageModelPreferencesWidgets {
+    page: adw::PreferencesPage,
+
+    general_group: adw::PreferencesGroup,
+    llm_endpoint: adw::EntryRow,
+
+    smart_summary_group: adw::PreferencesGroup,
+    smart_summary_model: adw::EntryRow,
+    smart_summary_system_prompt: adw::EntryRow,
+    smart_summary_prompt_prefix: adw::EntryRow,
+    smart_summary_prompt_suffix: adw::EntryRow,
+}
+
+#[cfg(feature = "smart-summary")]
+impl LanguageModelPreferencesWidgets {
+    fn new(settings: &gio::Settings) -> Self {
+        use gettextrs::*;
+
+        let page = adw::PreferencesPage::builder()
+            .title(gettext("Language Models"))
+            .description(gettext("Settings for the language model integrations."))
+            .icon_name("magic-wand")
+            .build();
+
+        let general_group = adw::PreferencesGroup::builder()
+            .title(gettext("General"))
+            .build();
+        let llm_endpoint = adw::EntryRow::new();
+        general_group.add(&llm_endpoint);
+        page.add(&general_group);
+
+        let smart_summary_group = adw::PreferencesGroup::builder()
+            .title(gettext("Smart Summary"))
+            .build();
+        let smart_summary_model = adw::EntryRow::new();
+        let smart_summary_system_prompt = adw::EntryRow::new();
+        let smart_summary_prompt_prefix = adw::EntryRow::new();
+        let smart_summary_prompt_suffix = adw::EntryRow::new();
+        smart_summary_group.add(&smart_summary_model);
+        smart_summary_group.add(&smart_summary_system_prompt);
+        smart_summary_group.add(&smart_summary_prompt_prefix);
+        smart_summary_group.add(&smart_summary_prompt_suffix);
+        page.add(&smart_summary_group);
+
+        let widgets = Self {
+            page,
+
+            general_group,
+            llm_endpoint,
+
+            smart_summary_group,
+            smart_summary_model,
+            smart_summary_system_prompt,
+            smart_summary_prompt_prefix,
+            smart_summary_prompt_suffix
+        };
+
+        let schema = settings.settings_schema().unwrap();
+
+        for (row, key) in [
+            (&widgets.llm_endpoint, "llm-endpoint"),
+            (&widgets.smart_summary_model, "smart-summary-model"),
+            (&widgets.smart_summary_system_prompt, "smart-summary-system-prompt"),
+            (&widgets.smart_summary_prompt_prefix, "smart-summary-prompt-prefix"),
+            (&widgets.smart_summary_prompt_suffix, "smart-summary-prompt-suffix"),
+        ] {
+            settings.bind(key, row, "text")
+                .get()
+                .set()
+                .build();
+            row.set_title(&gettext(schema.key(key).summary().unwrap()));
+        }
+
+        widgets
+    }
+}
+
+pub struct PreferencesWidgets {
+    #[cfg(feature = "smart-summary")]
+    llm: LanguageModelPreferencesWidgets
+}
+
 impl Component for Preferences {
     type CommandOutput = ();
     type Input = Option<gtk::Widget>;
     type Output = ();
     type Init = ();
+    type Root = adw::PreferencesDialog;
+    type Widgets = PreferencesWidgets;
 
-    view! {
-        #[root]
-        adw::PreferencesDialog {
-            add = &adw::PreferencesPage {
-                set_title: &gettext("Language Models"),
-                set_description: &gettext("Settings for the language model integrations."),
-                set_icon_name: Some("magic-wand"),
-
-                adw::PreferencesGroup {
-                    set_title: &gettext("General"),
-
-                    #[name = "llm_endpoint"]
-                    adw::EntryRow {},
-                },
-
-                adw::PreferencesGroup {
-                    set_title: &gettext("Smart Summary"),
-
-                    #[name = "smart_summary_model"] adw::EntryRow {},
-                    #[name = "smart_summary_system_prompt"] adw::EntryRow {},
-                    #[name = "smart_summary_prompt_prefix"] adw::EntryRow {},
-                    #[name = "smart_summary_prompt_suffix"] adw::EntryRow {},
-                }
-            }
-        }
+    fn init_root() -> Self::Root {
+        adw::PreferencesDialog::new()
     }
 
     fn init(
@@ -51,23 +112,13 @@ impl Component for Preferences {
         };
 
         model.settings.delay();
-        let schema = model.settings.settings_schema().unwrap();
 
-        let widgets = view_output!();
-
-        for (row, key) in [
-            (&widgets.llm_endpoint, "llm-endpoint"),
-            (&widgets.smart_summary_model, "smart-summary-model"),
-            (&widgets.smart_summary_system_prompt, "smart-summary-system-prompt"),
-            (&widgets.smart_summary_prompt_prefix, "smart-summary-prompt-prefix"),
-            (&widgets.smart_summary_prompt_suffix, "smart-summary-prompt-suffix"),
-        ] {
-            model.settings.bind(key, row, "text")
-                .get()
-                .set()
-                .build();
-            row.set_title(&gettext(schema.key(key).summary().unwrap()));
-        }
+        let widgets = PreferencesWidgets {
+            #[cfg(feature = "smart-summary")]
+            llm: LanguageModelPreferencesWidgets::new(&model.settings),
+        };
+        #[cfg(feature = "smart-summary")]
+        root.add(&widgets.llm.page);
 
         root.connect_closed(glib::clone!(
             #[strong(rename_to = settings)]
diff --git a/src/components/smart_summary.rs b/src/components/smart_summary.rs
index 7b2df7d..2795b09 100644
--- a/src/components/smart_summary.rs
+++ b/src/components/smart_summary.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "smart-summary")]
 use futures::AsyncBufReadExt;
 use gio::prelude::SettingsExtManual;
 use soup::prelude::*;