From ebb404edc0108589734b75e2c6068615cd13ca7f Mon Sep 17 00:00:00 2001 From: kylethedeveloper <8023096+kylethedeveloper@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:53:19 -0400 Subject: [PATCH] feat: Add a settings menu --- README.md | 11 ++-- TODO.md | 8 ++- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/index.html | 43 +++++++++++++++- src/main.js | 103 +++++++++++++++++++++++++++++++------- src/styles.css | 62 +++++++++++++++++++++++ 8 files changed, 204 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index bb37368..49d07dd 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,13 @@ Built with [Tauri v2](https://tauri.app/) and [whisper.cpp](https://github.com/g - **Backend**: Rust with [whisper-rs](https://github.com/tazz4843/whisper-rs) bindings - **Audio conversion**: FFmpeg (must be installed separately) +## Installation -## Usage +You can download the latest installers and packages for your operating system from the [GitHub Releases](https://github.com/kylethedeveloper/OratioText/releases) page. + +Choose the appropriate `.dmg` or `.msi` file to install OratioText easily! + +## Basic Usage 1. Select an audio/video file using the file picker 2. Choose a Whisper model (download if needed) @@ -36,7 +41,7 @@ Built with [Tauri v2](https://tauri.app/) and [whisper.cpp](https://github.com/g - FFmpeg installed and in PATH - Internet connection for initial model download -## macOS Installation Note +### macOS Installation Note Since the app is not signed with an Apple Developer certificate (yet), macOS Gatekeeper may show a warning saying **"OratioText is damaged and can't be opened"**. This is expected for unsigned open-source apps. @@ -46,7 +51,7 @@ To fix this, run the following command in Terminal after installing the app: xattr -cr /Applications/OratioText.app ``` -Then open the app normally. Alternatively, you can right-click the app and select **Open** to bypass the warning on first launch. +Then open the app normally. ## Development diff --git a/TODO.md b/TODO.md index f8fcc16..e7d0ff4 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,10 @@ - [x] Add an icon - [x] Build for Windows and macOS (see [BUILD.md](./BUILD.md)) - [x] Add language selection option (or detect automatically) -- [ ] Add an about menu (feedback, donate, etc) +- [x] Add an about menu (feedback, donate, etc) +- [x] Add a settings menu +- [ ] Add option to transcribe from URL - [ ] Build for Linux -- [ ] Add history of transcriptions \ No newline at end of file +- [ ] Add history of transcriptions +- [ ] Send notifications when transcription is complete +- [ ] Add option to manage downloaded models in Settings (delete, etc.) \ No newline at end of file diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 650482d..95f5c9a 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2372,7 +2372,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "oratiotext" -version = "1.0.1" +version = "1.0.3" dependencies = [ "dirs", "futures-util", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f3d7e33..fac14cd 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oratiotext" -version = "1.0.2" +version = "1.0.3" description = "A cross-platform desktop application for converting speech to text using Whisper" authors = ["kylethedeveloper"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4c66ab1..585dc34 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-config-schema/schema.json", "productName": "OratioText", - "version": "1.0.2", + "version": "1.0.3", "identifier": "com.oratiotext.app", "build": { "frontendDist": "../src" diff --git a/src/index.html b/src/index.html index dc306e7..2938200 100644 --- a/src/index.html +++ b/src/index.html @@ -24,11 +24,12 @@ -
OratioText @@ -154,6 +159,40 @@

OratioText

+
+
+ + +
+
+
+ Theme + Application appearance +
+
+ +
+
+ +
+
+ Language + Application interface language +
+
+ +
+
+
+
+
+
{ + if ((localStorage.getItem("oratiotext-theme") || "system") === "system") { + applyTheme("system"); + } + }); } function toggleTheme() { - const isLight = document.documentElement.getAttribute("data-theme") === "light"; - if (isLight) { - document.documentElement.removeAttribute("data-theme"); - localStorage.setItem("oratiotext-theme", "dark"); - setThemeIcons(false); + const currentSaved = localStorage.getItem("oratiotext-theme") || "system"; + let nextTheme = "dark"; + + if (currentSaved === "dark") { + nextTheme = "light"; + } else if (currentSaved === "light") { + nextTheme = "system"; } else { - document.documentElement.setAttribute("data-theme", "light"); - localStorage.setItem("oratiotext-theme", "light"); - setThemeIcons(true); + nextTheme = "dark"; // Default to dark from system + } + + localStorage.setItem("oratiotext-theme", nextTheme); + if (appThemeSelect) { + appThemeSelect.value = nextTheme; } + applyTheme(nextTheme); } themeToggle.addEventListener("click", toggleTheme); -initTheme(); + +function initSettings() { + initTheme(); + + if (appThemeSelect) { + appThemeSelect.addEventListener("change", (e) => { + const theme = e.target.value; + localStorage.setItem("oratiotext-theme", theme); + applyTheme(theme); + }); + } + + const savedLang = localStorage.getItem("oratiotext-app-language"); + if (savedLang && appLanguageSelect) { + appLanguageSelect.value = savedLang; + } + + if (appLanguageSelect) { + appLanguageSelect.addEventListener("change", (e) => { + localStorage.setItem("oratiotext-app-language", e.target.value); + }); + } +} + +initSettings(); // ---- Update Check --------------------------------------------------------- diff --git a/src/styles.css b/src/styles.css index 96e4172..d6e914e 100644 --- a/src/styles.css +++ b/src/styles.css @@ -233,6 +233,68 @@ body { margin-bottom: var(--spacing-sm); } +/* ========================================================================== + Settings Page + ========================================================================== */ + +.settings-list { + display: flex; + flex-direction: column; + gap: var(--spacing-md); + margin-top: var(--spacing-md); +} + +.setting-item { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: var(--spacing-md); + border-bottom: 1px solid var(--color-border); +} + +.setting-item:last-child { + padding-bottom: 0; + border-bottom: none; +} + +.setting-info { + display: flex; + flex-direction: column; + gap: 2px; +} + +.setting-name { + font-size: 0.95rem; + font-weight: 600; + color: var(--color-text); +} + +.setting-description { + font-size: 0.8rem; + color: var(--color-text-muted); +} + +.setting-control select { + background: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + padding: var(--spacing-xs) var(--spacing-md); + color: var(--color-text); + font-family: var(--font-family); + font-size: 0.875rem; + outline: none; + cursor: pointer; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8ea0' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 12px center; + padding-right: 36px; + width: 180px; +} + +.setting-control select:focus { + border-color: var(--color-primary); +} /* ========================================================================== File Picker ========================================================================== */