Fix video and audio playback to pause on window close

This commit is contained in:
ayumi-signal 2024-02-02 15:39:32 -08:00 committed by GitHub
parent d215e1b9be
commit 96131112da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 98 additions and 1 deletions

View file

@ -832,6 +832,12 @@ async function createWindow() {
// App dock icon bounce // App dock icon bounce
bounce.init(mainWindow); bounce.init(mainWindow);
mainWindow.on('hide', () => {
if (mainWindow && !windowState.shouldQuit()) {
mainWindow.webContents.send('set-media-playback-disabled', true);
}
});
// Emitted when the window is about to be closed. // Emitted when the window is about to be closed.
// Note: We do most of our shutdown logic here because all windows are closed by // Note: We do most of our shutdown logic here because all windows are closed by
// Electron before the app quits. // Electron before the app quits.
@ -937,6 +943,12 @@ async function createWindow() {
} }
}); });
mainWindow.on('show', () => {
if (mainWindow) {
mainWindow.webContents.send('set-media-playback-disabled', false);
}
});
mainWindow.once('ready-to-show', async () => { mainWindow.once('ready-to-show', async () => {
getLogger().info('main window is ready-to-show'); getLogger().info('main window is ready-to-show');

View file

@ -32,6 +32,7 @@ export function AvatarLightbox({
i18n={i18n} i18n={i18n}
isViewOnce isViewOnce
media={[]} media={[]}
playbackDisabled={false}
saveAttachment={noop} saveAttachment={noop}
toggleForwardMessagesModal={noop} toggleForwardMessagesModal={noop}
onMediaPlaybackStart={noop} onMediaPlaybackStart={noop}

View file

@ -66,6 +66,7 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
media, media,
saveAttachment: action('saveAttachment'), saveAttachment: action('saveAttachment'),
selectedIndex, selectedIndex,
playbackDisabled: false,
toggleForwardMessagesModal: action('toggleForwardMessagesModal'), toggleForwardMessagesModal: action('toggleForwardMessagesModal'),
onMediaPlaybackStart: noop, onMediaPlaybackStart: noop,
onPrevAttachment: () => { onPrevAttachment: () => {

View file

@ -36,6 +36,7 @@ export type PropsType = {
i18n: LocalizerType; i18n: LocalizerType;
isViewOnce?: boolean; isViewOnce?: boolean;
media: ReadonlyArray<ReadonlyDeep<MediaItemType>>; media: ReadonlyArray<ReadonlyDeep<MediaItemType>>;
playbackDisabled: boolean;
saveAttachment: SaveAttachmentActionCreatorType; saveAttachment: SaveAttachmentActionCreatorType;
selectedIndex: number; selectedIndex: number;
toggleForwardMessagesModal: (messageIds: ReadonlyArray<string>) => unknown; toggleForwardMessagesModal: (messageIds: ReadonlyArray<string>) => unknown;
@ -82,6 +83,7 @@ export function Lightbox({
saveAttachment, saveAttachment,
selectedIndex, selectedIndex,
toggleForwardMessagesModal, toggleForwardMessagesModal,
playbackDisabled,
onMediaPlaybackStart, onMediaPlaybackStart,
onNextAttachment, onNextAttachment,
onPrevAttachment, onPrevAttachment,
@ -250,6 +252,16 @@ export function Lightbox({
} }
}, [videoElement, onMediaPlaybackStart]); }, [videoElement, onMediaPlaybackStart]);
useEffect(() => {
if (!videoElement || videoElement.paused) {
return;
}
if (playbackDisabled) {
videoElement.pause();
}
}, [playbackDisabled, videoElement]);
useEffect(() => { useEffect(() => {
const div = document.createElement('div'); const div = document.createElement('div');
document.body.appendChild(div); document.body.appendChild(div);

View file

@ -49,11 +49,14 @@ export type LightboxStateType =
hasPrevMessage: boolean; hasPrevMessage: boolean;
hasNextMessage: boolean; hasNextMessage: boolean;
selectedIndex: number | undefined; selectedIndex: number | undefined;
playbackDisabled: boolean;
}; };
const CLOSE_LIGHTBOX = 'lightbox/CLOSE'; const CLOSE_LIGHTBOX = 'lightbox/CLOSE';
const SHOW_LIGHTBOX = 'lightbox/SHOW'; const SHOW_LIGHTBOX = 'lightbox/SHOW';
const SET_SELECTED_LIGHTBOX_INDEX = 'lightbox/SET_SELECTED_LIGHTBOX_INDEX'; const SET_SELECTED_LIGHTBOX_INDEX = 'lightbox/SET_SELECTED_LIGHTBOX_INDEX';
const SET_LIGHTBOX_PLAYBACK_DISABLED =
'lightbox/SET_LIGHTBOX_PLAYBACK_DISABLED';
type CloseLightboxActionType = ReadonlyDeep<{ type CloseLightboxActionType = ReadonlyDeep<{
type: typeof CLOSE_LIGHTBOX; type: typeof CLOSE_LIGHTBOX;
@ -71,6 +74,11 @@ type ShowLightboxActionType = {
}; };
}; };
type SetLightboxPlaybackDisabledActionType = ReadonlyDeep<{
type: typeof SET_LIGHTBOX_PLAYBACK_DISABLED;
payload: boolean;
}>;
type SetSelectedLightboxIndexActionType = ReadonlyDeep<{ type SetSelectedLightboxIndexActionType = ReadonlyDeep<{
type: typeof SET_SELECTED_LIGHTBOX_INDEX; type: typeof SET_SELECTED_LIGHTBOX_INDEX;
payload: number; payload: number;
@ -83,7 +91,8 @@ type LightboxActionType =
| MessageDeletedActionType | MessageDeletedActionType
| MessageExpiredActionType | MessageExpiredActionType
| ShowLightboxActionType | ShowLightboxActionType
| SetSelectedLightboxIndexActionType; | SetSelectedLightboxIndexActionType
| SetLightboxPlaybackDisabledActionType;
function closeLightbox(): ThunkAction< function closeLightbox(): ThunkAction<
void, void,
@ -115,6 +124,28 @@ function closeLightbox(): ThunkAction<
}; };
} }
function setPlaybackDisabled(
playbackDisabled: boolean
): ThunkAction<
void,
RootStateType,
unknown,
SetLightboxPlaybackDisabledActionType
> {
return (dispatch, getState) => {
const { lightbox } = getState();
if (!lightbox.isShowingLightbox) {
return;
}
dispatch({
type: SET_LIGHTBOX_PLAYBACK_DISABLED,
payload: playbackDisabled,
});
};
}
function showLightboxWithMedia( function showLightboxWithMedia(
selectedIndex: number | undefined, selectedIndex: number | undefined,
media: ReadonlyArray<ReadonlyDeep<MediaItemType>> media: ReadonlyArray<ReadonlyDeep<MediaItemType>>
@ -340,6 +371,7 @@ function showLightbox(opts: {
older.length > 0 && filterValidAttachments(older[0]).length > 0, older.length > 0 && filterValidAttachments(older[0]).length > 0,
hasNextMessage: hasNextMessage:
newer.length > 0 && filterValidAttachments(newer[0]).length > 0, newer.length > 0 && filterValidAttachments(newer[0]).length > 0,
playbackDisabled: false,
}, },
}); });
}; };
@ -481,6 +513,7 @@ export const actions = {
showLightboxForPrevMessage, showLightboxForPrevMessage,
showLightboxForNextMessage, showLightboxForNextMessage,
setSelectedLightboxIndex, setSelectedLightboxIndex,
setPlaybackDisabled,
}; };
export const useLightboxActions = (): BoundActionCreatorsMapObject< export const useLightboxActions = (): BoundActionCreatorsMapObject<
@ -505,6 +538,7 @@ export function reducer(
return { return {
...action.payload, ...action.payload,
isShowingLightbox: true, isShowingLightbox: true,
playbackDisabled: false,
}; };
} }
@ -522,6 +556,17 @@ export function reducer(
}; };
} }
if (action.type === SET_LIGHTBOX_PLAYBACK_DISABLED) {
if (!state.isShowingLightbox) {
return state;
}
return {
...state,
playbackDisabled: action.payload,
};
}
if ( if (
action.type === MESSAGE_CHANGED || action.type === MESSAGE_CHANGED ||
action.type === MESSAGE_DELETED || action.type === MESSAGE_DELETED ||

View file

@ -46,3 +46,8 @@ export const getHasNextMessage = createSelector(
getLightboxState, getLightboxState,
(state): boolean => state.isShowingLightbox && state.hasNextMessage (state): boolean => state.isShowingLightbox && state.hasNextMessage
); );
export const getPlaybackDisabled = createSelector(
getLightboxState,
(state): boolean => state.isShowingLightbox && state.playbackDisabled
);

View file

@ -21,6 +21,7 @@ import {
getMedia, getMedia,
getHasPrevMessage, getHasPrevMessage,
getHasNextMessage, getHasNextMessage,
getPlaybackDisabled,
getSelectedIndex, getSelectedIndex,
shouldShowLightbox, shouldShowLightbox,
} from '../selectors/lightbox'; } from '../selectors/lightbox';
@ -50,6 +51,7 @@ export function SmartLightbox(): JSX.Element | null {
const hasPrevMessage = useSelector<StateType, boolean>(getHasPrevMessage); const hasPrevMessage = useSelector<StateType, boolean>(getHasPrevMessage);
const hasNextMessage = useSelector<StateType, boolean>(getHasNextMessage); const hasNextMessage = useSelector<StateType, boolean>(getHasNextMessage);
const selectedIndex = useSelector<StateType, number>(getSelectedIndex); const selectedIndex = useSelector<StateType, number>(getSelectedIndex);
const playbackDisabled = useSelector<StateType, boolean>(getPlaybackDisabled);
const onPrevAttachment = useCallback(() => { const onPrevAttachment = useCallback(() => {
if (selectedIndex <= 0) { if (selectedIndex <= 0) {
@ -93,6 +95,7 @@ export function SmartLightbox(): JSX.Element | null {
i18n={i18n} i18n={i18n}
isViewOnce={isViewOnce} isViewOnce={isViewOnce}
media={media} media={media}
playbackDisabled={playbackDisabled}
saveAttachment={saveAttachment} saveAttachment={saveAttachment}
selectedIndex={selectedIndex || 0} selectedIndex={selectedIndex || 0}
toggleForwardMessagesModal={toggleForwardMessagesModal} toggleForwardMessagesModal={toggleForwardMessagesModal}

View file

@ -119,6 +119,7 @@ export type IPCEventsCallbacksType = {
removeDarkOverlay: () => void; removeDarkOverlay: () => void;
resetAllChatColors: () => void; resetAllChatColors: () => void;
resetDefaultChatColor: () => void; resetDefaultChatColor: () => void;
setMediaPlaybackDisabled: (playbackDisabled: boolean) => void;
showConversationViaNotification: (data: NotificationClickData) => void; showConversationViaNotification: (data: NotificationClickData) => void;
showConversationViaSignalDotMe: ( showConversationViaSignalDotMe: (
kind: string, kind: string,
@ -640,6 +641,13 @@ export function createIPCEvents(
getMediaPermissions: window.IPC.getMediaPermissions, getMediaPermissions: window.IPC.getMediaPermissions,
getMediaCameraPermissions: window.IPC.getMediaCameraPermissions, getMediaCameraPermissions: window.IPC.getMediaCameraPermissions,
setMediaPlaybackDisabled: (playbackDisabled: boolean) => {
window.reduxActions.lightbox.setPlaybackDisabled(playbackDisabled);
if (playbackDisabled) {
window.reduxActions.audioPlayer.pauseVoiceNotePlayer();
}
},
...overrideEvents, ...overrideEvents,
}; };
} }

View file

@ -239,6 +239,16 @@ ipc.on('power-channel:lock-screen', () => {
window.Whisper.events.trigger('powerMonitorLockScreen'); window.Whisper.events.trigger('powerMonitorLockScreen');
}); });
ipc.on(
'set-media-playback-disabled',
(_event: unknown, playbackDisabled: unknown) => {
const { setMediaPlaybackDisabled } = window.Events || {};
if (setMediaPlaybackDisabled) {
setMediaPlaybackDisabled(Boolean(playbackDisabled));
}
}
);
ipc.on('window:set-window-stats', (_event, stats) => { ipc.on('window:set-window-stats', (_event, stats) => {
if (!window.reduxActions) { if (!window.reduxActions) {
return; return;