mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
refactor: update quit on close logic
This commit is contained in:
parent
31121aab21
commit
3bef434f42
3 changed files with 84 additions and 15 deletions
|
|
@ -21,6 +21,7 @@ const RouterWithProtectedRoutes = withCoreSuspender(withProtectedRoutes(Router))
|
|||
const App = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const shell = useShell();
|
||||
const [windowHidden, setWindowHidden] = React.useState(false);
|
||||
const onPathNotMatch = React.useCallback(() => {
|
||||
return NotFound;
|
||||
}, []);
|
||||
|
|
@ -98,6 +99,17 @@ const App = () => {
|
|||
services.chromecast.off('stateChanged', onChromecastStateChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Handle shell window visibility changed event
|
||||
React.useEffect(() => {
|
||||
const onWindowVisibilityChanged = (state) => {
|
||||
setWindowHidden(state.visible === false && state.visibility === 0);
|
||||
};
|
||||
|
||||
shell.on('win-visibility-changed', onWindowVisibilityChanged);
|
||||
return () => shell.off('win-visibility-changed', onWindowVisibilityChanged);
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
const onCoreEvent = ({ event, args }) => {
|
||||
switch (event) {
|
||||
|
|
@ -105,9 +117,11 @@ const App = () => {
|
|||
if (args && args.settings && typeof args.settings.interfaceLanguage === 'string') {
|
||||
i18n.changeLanguage(args.settings.interfaceLanguage);
|
||||
}
|
||||
if (args?.settings) {
|
||||
shell.send('update-settings', args.settings);
|
||||
|
||||
if (args?.settings?.quitOnClose && windowHidden) {
|
||||
shell.send('quit');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -117,8 +131,8 @@ const App = () => {
|
|||
i18n.changeLanguage(state.profile.settings.interfaceLanguage);
|
||||
}
|
||||
|
||||
if (state?.profile?.settings) {
|
||||
shell.send('update-settings', state.profile.settings);
|
||||
if (state?.profile?.settings?.quitOnClose && windowHidden) {
|
||||
shell.send('quit');
|
||||
}
|
||||
};
|
||||
const onWindowFocus = () => {
|
||||
|
|
@ -162,7 +176,7 @@ const App = () => {
|
|||
services.core.transport.off('CoreEvent', onCoreEvent);
|
||||
}
|
||||
};
|
||||
}, [initialized]);
|
||||
}, [initialized, windowHidden]);
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<ServicesProvider services={services}>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,71 @@
|
|||
import { useEffect } from 'react';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
const SHELL_EVENT_OBJECT = 'transport';
|
||||
const transport = globalThis?.qt?.webChannelTransport;
|
||||
const events = new EventEmitter();
|
||||
|
||||
enum ShellEventType {
|
||||
SIGNAL = 1,
|
||||
INVOKE_METHOD = 6,
|
||||
}
|
||||
|
||||
type ShellEvent = {
|
||||
id: number;
|
||||
type: ShellEventType;
|
||||
object: string;
|
||||
args: string[];
|
||||
};
|
||||
|
||||
|
||||
|
||||
const createId = () => Math.floor(Math.random() * 9999) + 1;
|
||||
|
||||
const useShell = () => {
|
||||
const transport = globalThis?.qt?.webChannelTransport;
|
||||
|
||||
const send = (method: string, ...args: (string | number)[]) => {
|
||||
transport?.send(JSON.stringify({
|
||||
id: createId(),
|
||||
type: 6,
|
||||
object: 'transport',
|
||||
method: 'onEvent',
|
||||
args: [method, ...args],
|
||||
}));
|
||||
try {
|
||||
transport?.send(JSON.stringify({
|
||||
id: createId(),
|
||||
type: ShellEventType.INVOKE_METHOD,
|
||||
object: SHELL_EVENT_OBJECT,
|
||||
method: 'onEvent',
|
||||
args: [method, ...args],
|
||||
}));
|
||||
} catch(e) {
|
||||
console.error('Shell', 'Failed to send event', e);
|
||||
}
|
||||
};
|
||||
|
||||
const on = (name: string, listener: (arg: any) => void) => {
|
||||
events.on(name, listener);
|
||||
};
|
||||
|
||||
const off = (name: string, listener: (arg: any) => void) => {
|
||||
events.off(name, listener);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!transport) return;
|
||||
|
||||
transport.onmessage = ({ data }) => {
|
||||
try {
|
||||
const { type, args } = JSON.parse(data) as ShellEvent;
|
||||
|
||||
if (type === ShellEventType.SIGNAL) {
|
||||
const [methodName, methodArg] = args;
|
||||
events.emit(methodName, methodArg);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Shell', 'Failed to handle event', e);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return {
|
||||
active: !!transport,
|
||||
send,
|
||||
on,
|
||||
off,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
7
src/types/global.d.ts
vendored
7
src/types/global.d.ts
vendored
|
|
@ -1,7 +1,12 @@
|
|||
/* eslint-disable no-var */
|
||||
|
||||
type QtTransportMessage = {
|
||||
data: string;
|
||||
};
|
||||
|
||||
interface QtTransport {
|
||||
send: (message: string) => void,
|
||||
onmessage: (message: QtTransportMessage) => void,
|
||||
}
|
||||
|
||||
interface Qt {
|
||||
|
|
@ -12,4 +17,4 @@ declare global {
|
|||
var qt: Qt | undefined;
|
||||
}
|
||||
|
||||
export { };
|
||||
export {}
|
||||
Loading…
Reference in a new issue