Skip to content

Commit 3d0a4c0

Browse files
committed
fix(electron): sync tray and web UI state without flicker
1 parent d28c214 commit 3d0a4c0

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

electron/main/tray.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import { Tray, Menu, nativeImage, app, NativeImage } from 'electron';
1+
import { Tray, Menu, nativeImage, app, NativeImage, BrowserWindow } from 'electron';
22
import * as path from 'path';
33
import { createMainWindow } from './index';
44
import { useKey, maskKey, getKeyList, type KeyInfo } from './keyManager';
55

6+
function notifyWebContents(): void {
7+
BrowserWindow.getAllWindows().forEach(win => {
8+
win.webContents.send('keys-updated');
9+
});
10+
}
11+
612
let tray: Tray | null = null;
713

814
function getTrayIcon(): NativeImage {
@@ -64,6 +70,7 @@ function buildContextMenu(keys: KeyInfo[]): Menu {
6470
if (result.success) {
6571
const newKeys = await getKeyList();
6672
updateTrayMenu(newKeys);
73+
notifyWebContents();
6774
}
6875
},
6976
});

web/src/components/KeyList.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState, useEffect, useCallback } from 'react';
22
import { Trash2, Plus, RefreshCw, Terminal, CheckCircle2, Copy, Circle } from 'lucide-react';
33
import { decryptKeys, maskKey } from '@/utils/crypto';
4-
import { fetchEncryptedKeys, fetchCurrentIndex, fetchCache, addKey, removeKey, useKey, refreshCache } from '@/utils/api';
4+
import { fetchEncryptedKeys, fetchCurrentIndex, fetchCache, addKey, removeKey, useKey, refreshCache, isElectron } from '@/utils/api';
55
import type { KeyInfo, KeyUsage } from '@/utils/api';
66
import { cn } from '@/lib/utils';
77
import { Button } from '@/components/ui/button';
@@ -110,10 +110,12 @@ export default function KeyList() {
110110
const [newKey, setNewKey] = useState('');
111111
const [adding, setAdding] = useState(false);
112112

113-
const loadData = useCallback(async (showRefreshing = false, autoRefresh = true) => {
113+
const loadData = useCallback(async (showRefreshing = false, autoRefresh = true, silent = false) => {
114114
try {
115-
if (showRefreshing) setRefreshing(true);
116-
else setLoading(true);
115+
if (!silent) {
116+
if (showRefreshing) setRefreshing(true);
117+
else setLoading(true);
118+
}
117119
setError(null);
118120

119121
const [encryptedData, currentIndex, cache] = await Promise.all([
@@ -157,6 +159,14 @@ export default function KeyList() {
157159

158160
useEffect(() => {
159161
loadData();
162+
163+
// Listen for updates from tray menu (Electron only)
164+
if (isElectron) {
165+
const unsubscribe = window.oroio.on('keys-updated', () => {
166+
loadData(false, false, true);
167+
});
168+
return unsubscribe;
169+
}
160170
}, [loadData]);
161171

162172
const handleRefresh = async () => {

0 commit comments

Comments
 (0)