summary refs log tree commit diff
path: root/src/components
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2025-03-30 00:54:24 +0300
committerVika <vika@fireburn.ru>2025-03-30 00:54:24 +0300
commit2224f5557a3f2d522a82de27cee73234fa856298 (patch)
treeb0b8cd37a84766502f451ae101c2867d7d62ea55 /src/components
parent20f1d890bd87a3d0e72cb150e02433340abb0e9d (diff)
downloadbowl-main.tar.zst
Allow sending HTML without plain-text pre-processing by the server HEAD main
This might be useful if your server is misbehaving, or if you wish to
write your HTML by hand.

Alternative options (like client-side preprocessing) can also be added
in the future using this setting as a framework.
Diffstat (limited to 'src/components')
-rw-r--r--src/components/post_editor.rs36
-rw-r--r--src/components/preferences.rs51
2 files changed, 74 insertions, 13 deletions
diff --git a/src/components/post_editor.rs b/src/components/post_editor.rs
index 25069be..863e515 100644
--- a/src/components/post_editor.rs
+++ b/src/components/post_editor.rs
@@ -32,40 +32,52 @@ pub struct Post {
     pub visibility: Visibility
 }
 
-impl From<Post> for microformats::types::Item {
-    fn from(post: Post) -> Self {
-        use microformats::types::{Item, Class, KnownClass, PropertyValue};
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
+pub struct PostConversionSettings {
+    pub send_html_directly: bool,
+}
+
+impl Post {
+    pub fn into_mf2(self, settings: PostConversionSettings) -> microformats::types::Item {
+        use microformats::types::{Item, Class, KnownClass, PropertyValue, Fragment};
         let mut mf2 = Item::new(vec![Class::Known(KnownClass::Entry)]);
 
-        if let Some(name) = post.name {
+        if let Some(name) = self.name {
             mf2.properties.insert(
                 "name".to_owned(), vec![PropertyValue::Plain(name)]
             );
         }
 
-        if let Some(summary) = post.summary {
+        if let Some(summary) = self.summary {
             mf2.properties.insert(
                 "summary".to_owned(),
                 vec![PropertyValue::Plain(summary)]
             );
         }
 
-        if !post.tags.is_empty() {
+        if !self.tags.is_empty() {
             mf2.properties.insert(
                 "category".to_string(),
-                post.tags.into_iter().map(PropertyValue::Plain).collect()
+                self.tags.into_iter().map(PropertyValue::Plain).collect()
             );
         }
 
         mf2.properties.insert(
             "visibility".to_string(),
-            vec![PropertyValue::Plain(post.visibility.to_string())]
+            vec![PropertyValue::Plain(self.visibility.to_string())]
         );
 
-        mf2.properties.insert(
-            "content".to_string(),
-            vec![PropertyValue::Plain(post.content)]
-        );
+        let content = if settings.send_html_directly {
+            PropertyValue::Fragment(Fragment {
+                html: self.content.clone(),
+                value: self.content,
+                lang: None
+            })
+        } else {
+            PropertyValue::Plain(self.content)
+        };
+
+        mf2.properties.insert("content".to_string(), vec![content]);
 
         mf2
     }
diff --git a/src/components/preferences.rs b/src/components/preferences.rs
index 4c2c9fd..67075a2 100644
--- a/src/components/preferences.rs
+++ b/src/components/preferences.rs
@@ -8,6 +8,52 @@ pub struct Preferences {
     settings: gio::Settings,
 }
 
+#[allow(dead_code)]
+struct ComposerPreferencesWidgets {
+    page: adw::PreferencesPage,
+    general_group: adw::PreferencesGroup,
+    send_html_directly: adw::SwitchRow,
+}
+
+impl ComposerPreferencesWidgets {
+    fn new(settings: &gio::Settings) -> Self {
+        let page = adw::PreferencesPage::builder()
+            .title(gettext("Post composer"))
+            .description(gettext("Settings for composing new posts and editing existing ones."))
+            .icon_name("editor-symbolic")
+            .build();
+        let general_group = adw::PreferencesGroup::builder()
+            .title(gettext("General"))
+            .build();
+        let send_html_directly = adw::SwitchRow::new();
+        general_group.add(&send_html_directly);
+        page.add(&general_group);
+
+        let widgets = Self {
+            page,
+            general_group,
+            send_html_directly
+        };
+
+        let schema = settings.settings_schema().unwrap();
+
+        #[expect(clippy::single_element_loop)]
+        for (row, key, property) in [
+            (widgets.send_html_directly.upcast_ref::<adw::PreferencesRow>(), "send-html-directly", "active"),
+        ] {
+            let key_data = schema.key(key);
+            settings.bind(key, row, property)
+                .get()
+                .set()
+                .build();
+            row.set_title(&gettext(key_data.summary().unwrap()));
+            row.set_tooltip_markup(key_data.description().map(gettext).as_deref());
+        }
+
+        widgets
+    }
+}
+
 #[cfg(feature = "smart-summary")]
 #[allow(dead_code)]
 struct LanguageModelPreferencesWidgets {
@@ -28,7 +74,7 @@ struct LanguageModelPreferencesWidgets {
 impl LanguageModelPreferencesWidgets {
     fn new(settings: &gio::Settings) -> Self {
         let page = adw::PreferencesPage::builder()
-            .title(gettext("Language Models"))
+            .title(gettext("Language models"))
             .description(gettext("Settings for the language model integrations."))
             .icon_name("brain-augemnted") // sic!
             .build();
@@ -93,6 +139,7 @@ impl LanguageModelPreferencesWidgets {
 }
 
 pub struct PreferencesWidgets {
+    composer: ComposerPreferencesWidgets,
     #[cfg(feature = "smart-summary")]
     llm: LanguageModelPreferencesWidgets,
 }
@@ -121,9 +168,11 @@ impl Component for Preferences {
         model.settings.delay();
 
         let widgets = PreferencesWidgets {
+            composer: ComposerPreferencesWidgets::new(&model.settings),
             #[cfg(feature = "smart-summary")]
             llm: LanguageModelPreferencesWidgets::new(&model.settings),
         };
+        root.add(&widgets.composer.page);
         #[cfg(feature = "smart-summary")]
         root.add(&widgets.llm.page);