diff --git a/fluxer_app/src/features/voice/components/popout/PopoutWindow.tsx b/fluxer_app/src/features/voice/components/popout/PopoutWindow.tsx index 541862bb5..45f7d7879 100644 --- a/fluxer_app/src/features/voice/components/popout/PopoutWindow.tsx +++ b/fluxer_app/src/features/voice/components/popout/PopoutWindow.tsx @@ -36,6 +36,7 @@ interface PopoutWindowProps { onRestore: () => void; onClosed: (windowGeneration: number) => void; onWindowOpened?: (childWindow: Window, windowGeneration: number) => void; + existingWindow?: Window | null; children: React.ReactNode; } @@ -82,6 +83,7 @@ export const PopoutWindow: React.FC = ({ onRestore, onClosed, onWindowOpened, + existingWindow, children, }) => { const [childState, setChildState] = useState(null); @@ -89,11 +91,14 @@ export const PopoutWindow: React.FC = ({ const onWindowOpenedRef = useRef(onWindowOpened); const initialSizeRef = useRef({width, height}); const initialTitleRef = useRef(title); + const initialWindowRef = useRef(existingWindow); onClosedRef.current = onClosed; onWindowOpenedRef.current = onWindowOpened; useEffect(() => { const features = `width=${initialSizeRef.current.width},height=${initialSizeRef.current.height}`; - const childWindow = window.open('about:blank', windowKey, features); + const adoptedWindow = initialWindowRef.current; + const childWindow = + adoptedWindow && !adoptedWindow.closed ? adoptedWindow : window.open('about:blank', windowKey, features); if (!childWindow) { logger.warn('Failed to open popout window', {windowKey}); onClosedRef.current(windowGeneration); diff --git a/fluxer_app/src/features/voice/components/popout/VoicePopoutHost.tsx b/fluxer_app/src/features/voice/components/popout/VoicePopoutHost.tsx index cd3519acf..f9751fd71 100644 --- a/fluxer_app/src/features/voice/components/popout/VoicePopoutHost.tsx +++ b/fluxer_app/src/features/voice/components/popout/VoicePopoutHost.tsx @@ -92,6 +92,7 @@ const VoicePopoutWindowRenderer = observer(function VoicePopoutWindowRenderer({ onRestore={handleRestore} onClosed={handleClosed} onWindowOpened={handleWindowOpened} + existingWindow={PopoutWindowManager.getChildWindow(key)} data-flx="voice.voice-popout-host.popout-window" > diff --git a/fluxer_app/src/features/voice/engine/MediaEngineFacade.ts b/fluxer_app/src/features/voice/engine/MediaEngineFacade.ts index 7ddf2d20b..6034a7bf4 100644 --- a/fluxer_app/src/features/voice/engine/MediaEngineFacade.ts +++ b/fluxer_app/src/features/voice/engine/MediaEngineFacade.ts @@ -830,6 +830,7 @@ class MediaEngineFacade extends Store { ToastCommands.createToast({ type: 'info', children: this.i18n._(RECONNECT_SUCCEEDED_PICK_A_SCREEN_AGAIN_IF_YOU_DESCRIPTOR), + timeout: 5000, }); } } diff --git a/fluxer_app/src/features/voice/state/PopoutWindowManager.ts b/fluxer_app/src/features/voice/state/PopoutWindowManager.ts index fe2a1cab1..487380388 100644 --- a/fluxer_app/src/features/voice/state/PopoutWindowManager.ts +++ b/fluxer_app/src/features/voice/state/PopoutWindowManager.ts @@ -57,12 +57,6 @@ export function isVoicePopoutAlwaysOnTopSupported(): boolean { return typeof getElectronAPI()?.popoutSetAlwaysOnTop === 'function'; } -interface PopoutChildWindow { - closed: boolean; - focus: () => void; - close: () => void; -} - interface AlwaysOnTopOperationState { readonly descriptor: VoicePopoutDescriptor; desired: boolean; @@ -71,7 +65,7 @@ interface AlwaysOnTopOperationState { class PopoutWindowManagerStore { popouts: Record = {}; alwaysOnTopKeys: Record = {}; - private readonly childWindows = new Map(); + private readonly childWindows = new Map(); private readonly alwaysOnTopOperations = new Map(); private nextPopoutGeneration = 1; @@ -110,6 +104,12 @@ class PopoutWindowManagerStore { return null; } + getChildWindow(key: string): Window | null { + const childWindow = this.childWindows.get(key); + if (!childWindow || childWindow.closed) return null; + return childWindow; + } + isOpen(key: string): boolean { return key in this.popouts; } @@ -148,7 +148,7 @@ class PopoutWindowManagerStore { } } - attachWindow(key: string, generation: number, childWindow: PopoutChildWindow | null): void { + attachWindow(key: string, generation: number, childWindow: Window | null): void { if (!this.isCurrentPopout(key, generation)) return; if (childWindow === null) { this.childWindows.delete(key);