Add “Processing…” overlay state when post-processing (#740)

* feat: add “Processing…” overlay state

* format

* missing translations

---------

Co-authored-by: CJ Pais <cj@cjpais.com>
This commit is contained in:
Anton Sotkov 2026-02-09 04:36:00 +02:00 committed by GitHub
parent a4999164ae
commit 82d5c759ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 59 additions and 53 deletions

View file

@ -7,7 +7,9 @@ use crate::managers::transcription::TranscriptionManager;
use crate::settings::{get_settings, AppSettings, APPLE_INTELLIGENCE_PROVIDER_ID}; use crate::settings::{get_settings, AppSettings, APPLE_INTELLIGENCE_PROVIDER_ID};
use crate::shortcut; use crate::shortcut;
use crate::tray::{change_tray_icon, TrayIconState}; use crate::tray::{change_tray_icon, TrayIconState};
use crate::utils::{self, show_recording_overlay, show_transcribing_overlay}; use crate::utils::{
self, show_processing_overlay, show_recording_overlay, show_transcribing_overlay,
};
use crate::ManagedToggleState; use crate::ManagedToggleState;
use ferrous_opencc::{config::BuiltinConfig, OpenCC}; use ferrous_opencc::{config::BuiltinConfig, OpenCC};
use log::{debug, error}; use log::{debug, error};
@ -341,6 +343,9 @@ impl ShortcutAction for TranscribeAction {
// Then apply LLM post-processing if this is the post-process hotkey // Then apply LLM post-processing if this is the post-process hotkey
// Uses final_text which may already have Chinese conversion applied // Uses final_text which may already have Chinese conversion applied
if post_process {
show_processing_overlay(&ah);
}
let processed = if post_process { let processed = if post_process {
post_process_transcription(&settings, &final_text).await post_process_transcription(&settings, &final_text).await
} else { } else {

View file

@ -272,39 +272,7 @@ pub fn create_recording_overlay(app_handle: &AppHandle) {
} }
} }
/// Shows the recording overlay window with fade-in animation fn show_overlay_state(app_handle: &AppHandle, state: &str) {
pub fn show_recording_overlay(app_handle: &AppHandle) {
// Check if overlay should be shown based on position setting
let settings = settings::get_settings(app_handle);
if settings.overlay_position == OverlayPosition::None {
return;
}
if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") {
// Update position before showing to prevent flicker from position changes
#[cfg(target_os = "linux")]
{
update_gtk_layer_shell_anchors(&overlay_window);
}
if let Some((x, y)) = calculate_overlay_position(app_handle) {
let _ = overlay_window
.set_position(tauri::Position::Logical(tauri::LogicalPosition { x, y }));
}
let _ = overlay_window.show();
// On Windows, aggressively re-assert "topmost" in the native Z-order after showing
#[cfg(target_os = "windows")]
force_overlay_topmost(&overlay_window);
// Emit event to trigger fade-in animation with recording state
let _ = overlay_window.emit("show-overlay", "recording");
}
}
/// Shows the transcribing overlay window
pub fn show_transcribing_overlay(app_handle: &AppHandle) {
// Check if overlay should be shown based on position setting // Check if overlay should be shown based on position setting
let settings = settings::get_settings(app_handle); let settings = settings::get_settings(app_handle);
if settings.overlay_position == OverlayPosition::None { if settings.overlay_position == OverlayPosition::None {
@ -320,11 +288,25 @@ pub fn show_transcribing_overlay(app_handle: &AppHandle) {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
force_overlay_topmost(&overlay_window); force_overlay_topmost(&overlay_window);
// Emit event to switch to transcribing state let _ = overlay_window.emit("show-overlay", state);
let _ = overlay_window.emit("show-overlay", "transcribing");
} }
} }
/// Shows the recording overlay window with fade-in animation
pub fn show_recording_overlay(app_handle: &AppHandle) {
show_overlay_state(app_handle, "recording");
}
/// Shows the transcribing overlay window
pub fn show_transcribing_overlay(app_handle: &AppHandle) {
show_overlay_state(app_handle, "transcribing");
}
/// Shows the processing overlay window
pub fn show_processing_overlay(app_handle: &AppHandle) {
show_overlay_state(app_handle, "processing");
}
/// Updates the overlay window position based on current settings /// Updates the overlay window position based on current settings
pub fn update_overlay_position(app_handle: &AppHandle) { pub fn update_overlay_position(app_handle: &AppHandle) {
if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") { if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") {

View file

@ -497,6 +497,7 @@
"description": "تغيير لغة واجهة Handy" "description": "تغيير لغة واجهة Handy"
}, },
"overlay": { "overlay": {
"transcribing": "...جاري التفريغ" "transcribing": "...جاري التفريغ",
"processing": "...جاري المعالجة"
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Změňte jazyk rozhraní Handy" "description": "Změňte jazyk rozhraní Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Přepisuji..." "transcribing": "Přepisuji...",
"processing": "Zpracovávám..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Sprache der Handy-Oberfläche ändern" "description": "Sprache der Handy-Oberfläche ändern"
}, },
"overlay": { "overlay": {
"transcribing": "Transkribiere..." "transcribing": "Transkribiere...",
"processing": "Verarbeite..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Change the language of the Handy interface" "description": "Change the language of the Handy interface"
}, },
"overlay": { "overlay": {
"transcribing": "Transcribing..." "transcribing": "Transcribing...",
"processing": "Processing..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Cambia el idioma de la interfaz de Handy" "description": "Cambia el idioma de la interfaz de Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Transcribiendo..." "transcribing": "Transcribiendo...",
"processing": "Procesando..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Changer la langue de l'interface de Handy" "description": "Changer la langue de l'interface de Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Transcription..." "transcribing": "Transcription...",
"processing": "Traitement..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Cambia la lingua dell'interfaccia di Handy" "description": "Cambia la lingua dell'interfaccia di Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Trascrizione..." "transcribing": "Trascrizione...",
"processing": "Elaborazione..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Handyインターフェースの言語を変更" "description": "Handyインターフェースの言語を変更"
}, },
"overlay": { "overlay": {
"transcribing": "文字起こし中..." "transcribing": "文字起こし中...",
"processing": "処理中..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Handy 인터페이스의 언어를 변경하세요" "description": "Handy 인터페이스의 언어를 변경하세요"
}, },
"overlay": { "overlay": {
"transcribing": "텍스트로 변환 중..." "transcribing": "텍스트로 변환 중...",
"processing": "처리 중..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Zmień język interfejsu Handy" "description": "Zmień język interfejsu Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Transkrypcja..." "transcribing": "Transkrypcja...",
"processing": "Przetwarzanie..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Alterar o idioma da interface do Handy" "description": "Alterar o idioma da interface do Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Transcrevendo..." "transcribing": "Transcrevendo...",
"processing": "Processando..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Изменить языка интерфейса Handy" "description": "Изменить языка интерфейса Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Расшифровка..." "transcribing": "Расшифровка...",
"processing": "Обработка..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Handy arayüzünün dilini değiştirin" "description": "Handy arayüzünün dilini değiştirin"
}, },
"overlay": { "overlay": {
"transcribing": "Transkribe ediliyor..." "transcribing": "Transkribe ediliyor...",
"processing": "İşleniyor..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Змінити мову інтерфейсу Handy" "description": "Змінити мову інтерфейсу Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Обробка..." "transcribing": "Обробка...",
"processing": "Постобробка..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "Thay đổi ngôn ngữ giao diện của Handy" "description": "Thay đổi ngôn ngữ giao diện của Handy"
}, },
"overlay": { "overlay": {
"transcribing": "Đang chuyển đổi..." "transcribing": "Đang chuyển đổi...",
"processing": "Đang xử lý..."
} }
} }

View file

@ -497,6 +497,7 @@
"description": "更改 Handy 界面的语言" "description": "更改 Handy 界面的语言"
}, },
"overlay": { "overlay": {
"transcribing": "正在转录..." "transcribing": "正在转录...",
"processing": "处理中..."
} }
} }

View file

@ -11,7 +11,7 @@ import { commands } from "@/bindings";
import i18n, { syncLanguageFromSettings } from "@/i18n"; import i18n, { syncLanguageFromSettings } from "@/i18n";
import { getLanguageDirection } from "@/lib/utils/rtl"; import { getLanguageDirection } from "@/lib/utils/rtl";
type OverlayState = "recording" | "transcribing"; type OverlayState = "recording" | "transcribing" | "processing";
const RecordingOverlay: React.FC = () => { const RecordingOverlay: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -96,6 +96,9 @@ const RecordingOverlay: React.FC = () => {
{state === "transcribing" && ( {state === "transcribing" && (
<div className="transcribing-text">{t("overlay.transcribing")}</div> <div className="transcribing-text">{t("overlay.transcribing")}</div>
)} )}
{state === "processing" && (
<div className="transcribing-text">{t("overlay.processing")}</div>
)}
</div> </div>
<div className="overlay-right"> <div className="overlay-right">