Skip to content

Commit 1befd1f

Browse files
committed
feat: add auto-fix for browser media pause permissions
1 parent edc3a8a commit 1befd1f

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

‎src-tauri/src/lib.rs‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,40 @@ async fn open_mac_settings() -> Result<(), String> {
10071007
Ok(())
10081008
}
10091009

1010+
#[tauri::command]
1011+
async fn fix_browser_permissions() -> Result<(), String> {
1012+
#[cfg(target_os = "macos")]
1013+
{
1014+
let bundles = vec![
1015+
"com.google.Chrome",
1016+
"com.google.Chrome.canary",
1017+
"company.thebrowser.Browser", // Arc
1018+
"com.apple.Safari",
1019+
"ru.yandex.desktop.yandex-browser",
1020+
"com.brave.Browser",
1021+
"com.microsoft.edgemac",
1022+
"com.vivaldi.Vivaldi"
1023+
];
1024+
1025+
for bundle in bundles {
1026+
let _ = std::process::Command::new("defaults")
1027+
.args(["write", bundle, "AllowJavaScriptFromAppleEvents", "-bool", "true"])
1028+
.status();
1029+
}
1030+
1031+
// Specially for Safari: also enable Develop menu so the user sees the result
1032+
let _ = std::process::Command::new("defaults")
1033+
.args(["write", "com.apple.Safari", "IncludeDevelopMenu", "-bool", "true"])
1034+
.status();
1035+
1036+
Ok(())
1037+
}
1038+
#[cfg(not(target_os = "macos"))]
1039+
{
1040+
Ok(())
1041+
}
1042+
}
1043+
10101044
// ── Toggle window ─────────────────────────────────────────────────────────────
10111045
fn toggle_window<R: Runtime>(app: &AppHandle<R>) {
10121046
if let Some(w) = app.get_webview_window("main") {
@@ -1283,6 +1317,7 @@ pub fn run() {
12831317
download_whisper_model,
12841318
delete_whisper_model,
12851319
open_mac_settings,
1320+
fix_browser_permissions,
12861321
reset_window_position,
12871322
get_start_minimized,
12881323
set_start_minimized,

‎src/components/SettingsPanel.tsx‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ export const CONTENT = {
9999
autoPauseBrowserChrome: 'Chrome → View → Developer → Allow JavaScript from Apple Events',
100100
autoPauseBrowserSafari: 'Safari → Develop → Allow JavaScript from Apple Events',
101101
autoPauseBrowserNote: 'Music и Spotify работают без дополнительных настроек.',
102+
autoPauseBrowserFixBtn: 'Разрешить автоматически (Beta)',
103+
autoPauseBrowserFixSuccess: 'Готово! Перезапустите браузеры.',
102104
accessibility: 'macOS: Универсальный доступ',
103105
accessibilityDesc: 'Для автовставки необходимо разрешение «Универсальный доступ» для NYX Vox.',
104106
accessibilityBtn: 'Открыть настройки',
@@ -245,6 +247,8 @@ export const CONTENT = {
245247
autoPauseBrowserChrome: 'Chrome → View → Developer → Allow JavaScript from Apple Events',
246248
autoPauseBrowserSafari: 'Safari → Develop → Allow JavaScript from Apple Events',
247249
autoPauseBrowserNote: 'Music and Spotify work without extra setup.',
250+
autoPauseBrowserFixBtn: 'Allow Automatically (Beta)',
251+
autoPauseBrowserFixSuccess: 'Done! Restart your browsers.',
248252
accessibility: 'macOS: Accessibility',
249253
accessibilityDesc: 'Auto-paste requires Accessibility permission for NYX Vox in System Settings.',
250254
accessibilityBtn: 'Open Settings',
@@ -337,6 +341,7 @@ export function SettingsPanel({ onClose, autoPaste, clearOnPaste, onToggleAutoPa
337341
const [tab, setTab] = useState<Tab>('guide');
338342
const [lang, setLang] = useState<Lang>('ru');
339343
const [showFeedback, setShowFeedback] = useState(false);
344+
const [browserFixed, setBrowserFixed] = useState(false);
340345
const [sttMode, setSttMode] = useState<'deepgram' | 'whisper' | 'groq'>('deepgram');
341346
const [dgLanguage, setDgLanguage] = useState<'auto' | 'ru' | 'en'>('auto');
342347
const [whisperLanguage, setWhisperLanguage] = useState<'auto' | 'ru' | 'en'>('ru');
@@ -641,6 +646,24 @@ export function SettingsPanel({ onClose, autoPaste, clearOnPaste, onToggleAutoPa
641646
<code className="text-[10px] text-white/50 font-mono leading-relaxed">{c.settings.autoPauseBrowserSafari}</code>
642647
</div>
643648
</div>
649+
<div className="pt-1">
650+
<button
651+
onClick={async () => {
652+
if (window.__TAURI_INTERNALS__) {
653+
await invoke('fix_browser_permissions');
654+
setBrowserFixed(true);
655+
setTimeout(() => setBrowserFixed(false), 5000);
656+
}
657+
}}
658+
className={`w-full py-2 px-3 rounded-lg text-[10px] font-bold transition-all border ${
659+
browserFixed
660+
? 'bg-emerald-500/20 border-emerald-500/30 text-emerald-400'
661+
: 'bg-sky-500/10 border-sky-500/20 text-sky-300 hover:bg-sky-500/20'
662+
}`}
663+
>
664+
{browserFixed ? c.settings.autoPauseBrowserFixSuccess : c.settings.autoPauseBrowserFixBtn}
665+
</button>
666+
</div>
644667
<p className="text-[10px] text-white/25 italic">{c.settings.autoPauseBrowserNote}</p>
645668
</div>
646669
)}

0 commit comments

Comments
 (0)