Skip to content

Commit

Permalink
#129 Add context menu to tray icon when recording
Browse files Browse the repository at this point in the history
- context menu allows for stopping or pausing/resuming recording
- also added ability to pause recording by holding 'option' key while clicking tray icon
  • Loading branch information
thethomasz committed Aug 29, 2022
1 parent cffa7b9 commit 5471c50
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 9 deletions.
6 changes: 3 additions & 3 deletions main/aperture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export const startRecording = async (options: StartRecordingOptions) => {

console.log(`Started recording after ${startTime}s`);
windowManager.cropper?.setRecording();
setRecordingTray(stopRecording, pauseRecording);
setRecordingTray();
setCropperShortcutAction(stopRecording);
past = Date.now();

Expand Down Expand Up @@ -226,7 +226,7 @@ export const pauseRecording = async () => {

try {
await aperture.pause();
setPausedTray(resumeRecording);
setPausedTray();
track('recording/paused');
console.log(`Paused recording after ${(Date.now() - past) / 1000}s`);
} catch (error) {
Expand All @@ -245,7 +245,7 @@ export const resumeRecording = async () => {

try {
await aperture.resume();
setRecordingTray(stopRecording, pauseRecording);
setRecordingTray();
track('recording/resumed');
console.log(`Resume recording after ${(Date.now() - past) / 1000}s`);
} catch (error) {
Expand Down
39 changes: 39 additions & 0 deletions main/menus/record.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {Menu} from 'electron';
import {MenuItemId, MenuOptions} from './utils';
import {pauseRecording, resumeRecording, stopRecording} from '../aperture';

const getRecordMenuTemplate = async (): Promise<MenuOptions> => [
getStopRecordingMenuItem(),
getPauseRecordingMenuItem()
];

const getPausedMenuTemplate = async (): Promise<MenuOptions> => [
getStopRecordingMenuItem(),
getResumeRecordingMenuItem()
];

const getStopRecordingMenuItem = () => ({
id: MenuItemId.stopRecording,
label: 'Stop Recording',
click: stopRecording
});

const getPauseRecordingMenuItem = () => ({
id: MenuItemId.pauseRecording,
label: 'Pause Recording',
click: pauseRecording
});

const getResumeRecordingMenuItem = () => ({
id: MenuItemId.pauseRecording,
label: 'Resume Recording',
click: resumeRecording
});

export const getRecordMenu = async (isPaused: boolean) => {
if (isPaused) {
return Menu.buildFromTemplate(await getPausedMenuTemplate());
}

return Menu.buildFromTemplate(await getRecordMenuTemplate());
};
4 changes: 3 additions & 1 deletion main/menus/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export enum MenuItemId {
app = 'app',
saveOriginal = 'saveOriginal',
plugins = 'plugins',
audioDevices = 'audioDevices'
audioDevices = 'audioDevices',
stopRecording = 'stopRecording',
pauseRecording = 'pauseRecording'
}

export const getCurrentMenuItem = (id: MenuItemId) => {
Expand Down
35 changes: 30 additions & 5 deletions main/tray.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
'use strict';

import {Tray} from 'electron';
import {KeyboardEvent} from 'electron/main';
import path from 'path';
import {getCogMenu} from './menus/cog';
import {getRecordMenu} from './menus/record';
import {track} from './common/analytics';
import {openFiles} from './utils/open-files';
import {windowManager} from './windows/manager';
import {pauseRecording, resumeRecording, stopRecording} from './aperture';

let tray: Tray;
let trayAnimation: NodeJS.Timeout | undefined;
Expand All @@ -14,6 +17,14 @@ const openContextMenu = async () => {
tray.popUpContextMenu(await getCogMenu());
};

const openRecordingContextMenu = async () => {
tray.popUpContextMenu(await getRecordMenu(false));
};

const openPausedContextMenu = async () => {
tray.popUpContextMenu(await getRecordMenu(true))
}

const openCropperWindow = () => windowManager.cropper?.open();

export const initializeTray = () => {
Expand All @@ -39,29 +50,43 @@ export const resetTray = () => {
}

tray.removeAllListeners('click');
tray.removeAllListeners('right-click');

tray.setImage(path.join(__dirname, '..', 'static', 'menubarDefaultTemplate.png'));
tray.on('click', openCropperWindow);
tray.on('right-click', openContextMenu);
};

export const setRecordingTray = (stopRecording: () => void, pauseRecording: () => void) => {
export const setRecordingTray = () => {
animateIcon();

tray.removeAllListeners('right-click');

// TODO: figure out why this is marked as missing. It's defined properly in the electron.d.ts file
tray.once('click', stopRecording);
tray.once('right-click', pauseRecording);
tray.once('click', onRecordingTrayClick);
tray.on('right-click', openRecordingContextMenu);
};

export const setPausedTray = (resumeRecording: () => void) => {
export const setPausedTray = () => {
if (trayAnimation) {
clearTimeout(trayAnimation);
}

tray.removeAllListeners('right-click');

tray.setImage(path.join(__dirname, '..', 'static', 'menubarDefaultTemplate.png'));
tray.once('right-click', resumeRecording);
tray.once('click', resumeRecording);
tray.on('right-click', openPausedContextMenu);
};

const onRecordingTrayClick = (event: KeyboardEvent) => {
if (event.altKey) {
pauseRecording();
return;
}
stopRecording();
}

const animateIcon = async () => new Promise<void>(resolve => {
const interval = 20;
let i = 0;
Expand Down

0 comments on commit 5471c50

Please sign in to comment.