zit-studio-code index
From: Oliver Lin <oli...@liuxiaozhen.dev>
To: zit-studio-code@googlegroups.com
Subject: [GitTune][PATCH 1/2] feat(sendemail): add SMTP settings management
 for git send-email
Date: Tue, 06 Oct 2026 03:09:33 +0000
Message-ID: <CgcjxiiUAQAJ.txGqBtIv2tA@googlegroups.com>
---
 src/main.rs   |  63 ++++++++++++++-
 ui/main.slint | 211 ++++++++++++++++++++++++++++++++++----------------
 2 files changed, 205 insertions(+), 69 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 18cda0e..1c0d352 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,12 +13,32 @@ fn main() -> Result<(), slint::PlatformError> {
     let default_branch = gitconfig::read("init.defaultBranch").unwrap_or_default();
     let commit_gpgsign = gitconfig::read("commit.gpgsign").unwrap_or_default() == "true";
     let tag_gpgsign = gitconfig::read("tag.gpgsign").unwrap_or_default() == "true";
+    let smtp_from = gitconfig::read("sendemail.from").unwrap_or_default();
+    let smtp_user = gitconfig::read("sendemail.smtpuser").unwrap_or_default();
+    let smtp_server = gitconfig::read("sendemail.smtpserver").unwrap_or_default();
+    let smtp_port = gitconfig::read("sendemail.smtpserverport").unwrap_or_default();
+    let smtp_enc = gitconfig::read("sendemail.smtpencryption").unwrap_or_default();
 
     window.set_user_name(name.into());
     window.set_user_email(email.into());
     window.set_commit_gpgsign(commit_gpgsign);
     window.set_tag_gpgsign(tag_gpgsign);
 
+    window.set_sendemail_from(smtp_from.into());
+    window.set_sendemail_smtpuser(smtp_user.into());
+    window.set_sendemail_smtpserver(smtp_server.into());
+    window.set_sendemail_smtpserverport(smtp_port.into());
+
+    let encryption_options: Vec<slint::SharedString> =
+        vec!["none".into(), "ssl".into(), "tls".into()];
+    window.set_encryption_options(slint::ModelRc::new(slint::VecModel::from(encryption_options)));
+    let encryption_selected: slint::SharedString = match smtp_enc.as_str() {
+        "ssl" => "ssl".into(),
+        "tls" => "tls".into(),
+        _ => "none".into(),
+    };
+    window.set_encryption_selected_value(encryption_selected);
+
     // Load local GPG secret keys.
     let gpg_keys = gpg::list_keys().unwrap_or_default();
     let mut gpg_display_to_fpr: Vec<(slint::SharedString, String)> = Vec::new();
@@ -97,6 +117,12 @@ fn main() -> Result<(), slint::PlatformError> {
         let commit_gpg = if window.get_commit_gpgsign() { "true" } else { "false" };
         let tag_gpg = if window.get_tag_gpgsign() { "true" } else { "false" };
 
+        let smtp_from = window.get_sendemail_from();
+        let smtp_user = window.get_sendemail_smtpuser();
+        let smtp_server = window.get_sendemail_smtpserver();
+        let smtp_port = window.get_sendemail_smtpserverport();
+        let smtp_enc = window.get_encryption_selected_value();
+
         let result = gitconfig::write("user.name", &name)
             .and_then(|()| gitconfig::write("user.email", &email))
             .and_then(|()| {
@@ -114,7 +140,42 @@ fn main() -> Result<(), slint::PlatformError> {
                 }
             })
             .and_then(|()| gitconfig::write("commit.gpgsign", commit_gpg))
-            .and_then(|()| gitconfig::write("tag.gpgsign", tag_gpg));
+            .and_then(|()| gitconfig::write("tag.gpgsign", tag_gpg))
+            .and_then(|()| {
+                if smtp_from.is_empty() {
+                    gitconfig::unset("sendemail.from")
+                } else {
+                    gitconfig::write("sendemail.from", &smtp_from)
+                }
+            })
+            .and_then(|()| {
+                if smtp_user.is_empty() {
+                    gitconfig::unset("sendemail.smtpuser")
+                } else {
+                    gitconfig::write("sendemail.smtpuser", &smtp_user)
+                }
+            })
+            .and_then(|()| {
+                if smtp_server.is_empty() {
+                    gitconfig::unset("sendemail.smtpserver")
+                } else {
+                    gitconfig::write("sendemail.smtpserver", &smtp_server)
+                }
+            })
+            .and_then(|()| {
+                if smtp_port.is_empty() {
+                    gitconfig::unset("sendemail.smtpserverport")
+                } else {
+                    gitconfig::write("sendemail.smtpserverport", &smtp_port)
+                }
+            })
+            .and_then(|()| {
+                if smtp_enc == "none" {
+                    gitconfig::unset("sendemail.smtpencryption")
+                } else {
+                    gitconfig::write("sendemail.smtpencryption", &smtp_enc)
+                }
+            });
 
         let status = match result {
             Ok(()) => "Saved.".to_string(),
diff --git a/ui/main.slint b/ui/main.slint
index 9f02a1f..00dcc63 100644
--- a/ui/main.slint
+++ b/ui/main.slint
@@ -1,4 +1,4 @@
-import { Button, LineEdit, VerticalBox, ComboBox, CheckBox } from "std-widgets.slint";
+import { Button, LineEdit, VerticalBox, HorizontalBox, ComboBox, CheckBox, ScrollView } from "std-widgets.slint";
 
 export component MainWindow inherits Window {
     title: "GitTune";
@@ -19,95 +19,170 @@ export component MainWindow inherits Window {
     in-out property <bool> commit-gpgsign;
     in-out property <bool> tag-gpgsign;
 
+    in-out property <string> sendemail-from;
+    in-out property <string> sendemail-smtpuser;
+    in-out property <string> sendemail-smtpserver;
+    in-out property <string> sendemail-smtpserverport;
+
+    in property <[string]> encryption-options;
+    in-out property <string> encryption-selected-value;
+
     in property <string> status-text;
     callback save-clicked();
 
     property <bool> gpg-is-custom: root.gpg-selected-value == "Custom...";
     property <bool> branch-is-custom: root.branch-selected-value == "Custom...";
 
-    VerticalBox {
-        padding: 24px;
-        spacing: 12px;
+    ScrollView {
+        VerticalBox {
+            padding: 24px;
+            spacing: 12px;
 
-        Text {
-            text: "Git identity (global)";
-            font-size: 18px;
-            font-weight: 700;
-        }
+            Text {
+                text: "Git identity (global)";
+                font-size: 18px;
+                font-weight: 700;
+            }
 
-        Text {
-            text: "Name";
-        }
+            Text {
+                text: "Name";
+            }
 
-        LineEdit {
-            placeholder-text: "user.name";
-            text <=> root.user-name;
-        }
+            LineEdit {
+                placeholder-text: "user.name";
+                text <=> root.user-name;
+            }
 
-        Text {
-            text: "Email";
-        }
+            Text {
+                text: "Email";
+            }
 
-        LineEdit {
-            placeholder-text: "user.email";
-            text <=> root.user-email;
-        }
+            LineEdit {
+                placeholder-text: "user.email";
+                text <=> root.user-email;
+            }
 
-        Text {
-            text: "GPG signing key";
-            font-size: 16px;
-            font-weight: 700;
-        }
+            Text {
+                text: "GPG signing key";
+                font-size: 16px;
+                font-weight: 700;
+            }
 
-        ComboBox {
-            model: root.gpg-options;
-            current-value <=> root.gpg-selected-value;
-        }
+            ComboBox {
+                model: root.gpg-options;
+                current-value <=> root.gpg-selected-value;
+            }
 
-        LineEdit {
-            visible: root.gpg-is-custom;
-            placeholder-text: "Key fingerprint or ID";
-            text <=> root.gpg-custom-value;
-        }
+            LineEdit {
+                visible: root.gpg-is-custom;
+                placeholder-text: "Key fingerprint or ID";
+                text <=> root.gpg-custom-value;
+            }
 
-        Text {
-            text: "Default branch";
-            font-size: 16px;
-            font-weight: 700;
-        }
+            Text {
+                text: "Default branch";
+                font-size: 16px;
+                font-weight: 700;
+            }
 
-        ComboBox {
-            model: root.branch-options;
-            current-value <=> root.branch-selected-value;
-        }
+            ComboBox {
+                model: root.branch-options;
+                current-value <=> root.branch-selected-value;
+            }
 
-        LineEdit {
-            visible: root.branch-is-custom;
-            placeholder-text: "branch name";
-            text <=> root.branch-custom-value;
-        }
+            LineEdit {
+                visible: root.branch-is-custom;
+                placeholder-text: "branch name";
+                text <=> root.branch-custom-value;
+            }
 
-        CheckBox {
-            text: "Sign commits with GPG";
-            checked <=> root.commit-gpgsign;
-        }
+            CheckBox {
+                text: "Sign commits with GPG";
+                checked <=> root.commit-gpgsign;
+            }
 
-        CheckBox {
-            text: "Sign tags with GPG";
-            checked <=> root.tag-gpgsign;
-        }
+            CheckBox {
+                text: "Sign tags with GPG";
+                checked <=> root.tag-gpgsign;
+            }
 
-        Button {
-            text: "Save";
-            primary: true;
-            clicked => {
-                root.save-clicked();
+            Text {
+                text: "Email sending (sendemail)";
+                font-size: 16px;
+                font-weight: 700;
             }
-        }
 
-        Text {
-            text: root.status-text;
-            wrap: word-wrap;
+            Text {
+                text: "From";
+            }
+
+            LineEdit {
+                placeholder-text: "Name <y...@example.com>";
+                text <=> root.sendemail-from;
+            }
+
+            Text {
+                text: "SMTP username";
+            }
+
+            LineEdit {
+                placeholder-text: "sendemail.smtpuser";
+                text <=> root.sendemail-smtpuser;
+            }
+
+            HorizontalBox {
+                spacing: 12px;
+
+                VerticalBox {
+                    spacing: 4px;
+
+                    Text {
+                        text: "SMTP server";
+                    }
+
+                    LineEdit {
+                        placeholder-text: "smtp.example.com";
+                        text <=> root.sendemail-smtpserver;
+                    }
+                }
+
+                VerticalBox {
+                    spacing: 4px;
+
+                    Text {
+                        text: "Port";
+                    }
+
+                    LineEdit {
+                        width: 100px;
+                        input-type: number;
+                        placeholder-text: "465";
+                        text <=> root.sendemail-smtpserverport;
+                    }
+                }
+            }
+
+            Text {
+                text: "Encryption";
+            }
+
+            ComboBox {
+                model: root.encryption-options;
+                current-value <=> root.encryption-selected-value;
+            }
+
+            Button {
+                text: "Save";
+                primary: true;
+                clicked => {
+                    root.save-clicked();
+                }
+            }
+
+            Text {
+                text: root.status-text;
+                wrap: word-wrap;
+            }
         }
     }
 }
-- 
2.53.0


[next | thread overview | mbox]

archive of zit-studio-code@googlegroups.com