diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/preferences.rs | 90 | ||||
-rw-r--r-- | src/lib.rs | 14 |
2 files changed, 103 insertions, 1 deletions
diff --git a/src/components/preferences.rs b/src/components/preferences.rs new file mode 100644 index 0000000..9bbc313 --- /dev/null +++ b/src/components/preferences.rs @@ -0,0 +1,90 @@ +use gettextrs::*; +use gio::prelude::*; +use adw::prelude::*; +use relm4::prelude::*; + +pub struct Preferences { + settings: gio::Settings, +} + +#[relm4::component(pub)] +impl Component for Preferences { + type CommandOutput = (); + type Input = Option<gtk::Widget>; + type Output = (); + type Init = (); + + 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( + _: Self::Init, + root: Self::Root, + _sender: ComponentSender<Self>, + ) -> ComponentParts<Self> { + let model = Self { + settings: gio::Settings::new(crate::APPLICATION_ID), + }; + + 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())); + } + + root.connect_closed(glib::clone!( + #[strong(rename_to = settings)] + model.settings, + move |_| { + settings.apply() + } + )); + + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>, root: &Self::Root) { + root.present(msg.as_ref()); + } + + fn shutdown(&mut self, _: &mut Self::Widgets, _: relm4::Sender<()>) { + self.settings.apply() + } +} diff --git a/src/lib.rs b/src/lib.rs index 30cba6f..6421560 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,9 @@ pub mod components { pub mod signin; pub use signin::{SignIn, Output as SignInOutput}; + + pub mod preferences; + pub use preferences::Preferences; } use components::{post_editor::Post, PostEditorInput}; @@ -274,8 +277,17 @@ impl AsyncComponent for App { let about_action: RelmAction<AboutAction> = RelmAction::new_stateless(move |_| { App::about().present(weak_window.upgrade().as_ref()); }); + let weak_window = window.downgrade(); let preferences_action: RelmAction<PreferencesAction> = RelmAction::new_stateless(move |_| { - log::warn!("Ain't implemented yet!"); + // This could be built as an action that sends an input to open preferences. + // + // But I find this an acceptable alternative. + let mut prefs = components::Preferences::builder() + .launch(()) + .detach(); + + prefs.emit(weak_window.upgrade().map(|w| w.upcast())); + prefs.detach_runtime(); }); let sign_out_action: RelmAction<SignOutAction> = RelmAction::new_stateless(move |_| { input_sender.emit(Input::SignOut) |