Skip to content

Show remaining time on a task on the tray #4156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion electron/electronAPI.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ export interface ElectronAPI {

backupAppData(appData: AppDataComplete): void;

updateCurrentTask(task: Task | null);
updateCurrentTask(
task: Task | null,
isPomodoroEnabled: boolean,
currentPomodoroSessionTime: number,
);

exec(command: string): void;
}
115 changes: 64 additions & 51 deletions electron/indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,34 +71,43 @@ function initListeners(): void {
}
});

ipcMain.on(IPC.CURRENT_TASK_UPDATED, (ev, currentTask) => {
const mainWin = getWin();
getSettings(mainWin, (settings: GlobalConfigState) => {
const isTrayShowCurrentTask = settings.misc.isTrayShowCurrentTask;

const msg =
isTrayShowCurrentTask && currentTask ? createIndicatorStr(currentTask) : '';

if (tray) {
// tray handling
if (currentTask && currentTask.title) {
tray.setTitle(msg);
if (!IS_MAC) {
// NOTE apparently this has no effect for gnome
tray.setToolTip(msg);
ipcMain.on(
IPC.CURRENT_TASK_UPDATED,
(ev, currentTask, isPomodoroEnabled, currentPomodoroSessionTime) => {
const mainWin = getWin();
getSettings(mainWin, (settings: GlobalConfigState) => {
const isTrayShowCurrentTask = settings.misc.isTrayShowCurrentTask;

const msg =
isTrayShowCurrentTask && currentTask
? createIndicatorMessage(
currentTask,
isPomodoroEnabled,
currentPomodoroSessionTime,
)
: '';

if (tray) {
// tray handling
if (currentTask && currentTask.title) {
tray.setTitle(msg);
if (!IS_MAC) {
// NOTE apparently this has no effect for gnome
tray.setToolTip(msg);
}
} else {
tray.setTitle('');
if (!IS_MAC) {
// NOTE apparently this has no effect for gnome
tray.setToolTip(msg);
}
const suf = shouldUseDarkColors ? '-d.png' : '-l.png';
setTrayIcon(tray, DIR + `stopped${suf}`);
}
} else {
tray.setTitle('');
if (!IS_MAC) {
// NOTE apparently this has no effect for gnome
tray.setToolTip(msg);
}
const suf = shouldUseDarkColors ? '-d.png' : '-l.png';
setTrayIcon(tray, DIR + `stopped${suf}`);
}
}
});
});
});
},
);

// ipcMain.on(IPC.POMODORO_UPDATE, (ev, params) => {
// const isOnBreak = params.isOnBreak;
Expand All @@ -111,28 +120,30 @@ function initListeners(): void {
}

// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
function createIndicatorStr(task: TaskCopy): string {
function createIndicatorMessage(
task: TaskCopy,
isPomodoroEnabled: boolean,
currentPomodoroSessionTime: number,
): string {
if (task && task.title) {
let title = task.title;
// let timeStr = '';
// let msg;
let timeStr = '';
if (title.length > 40) {
title = title.substring(0, 37) + '...';
}
return title;

// if (task.timeSpent) {
// const timeSpentAsMinutes = Math.round(task.timeSpent / 60 / 1000);
// timeStr += timeSpentAsMinutes.toString();
// }
// const timeEstimateAsMin = Math.round(task.timeEstimate / 60 / 1000);
//
// if (task.timeEstimate && timeEstimateAsMin > 0) {
// timeStr += '/' + timeEstimateAsMin;
// }
//
// msg = title + ' | ' + timeStr + 'm ';
// return msg;

if (task.timeEstimate) {
const restOfTime = Math.max(task.timeEstimate - task.timeSpent, 0);
timeStr = getCountdownMessage(restOfTime);
} else if (task.timeSpent) {
timeStr = getCountdownMessage(task.timeSpent);
}

if (isPomodoroEnabled) {
timeStr = getCountdownMessage(currentPomodoroSessionTime);
}

return `${title} ${timeStr}`;
}

// NOTE: we need to make sure that this is always a string
Expand All @@ -142,14 +153,8 @@ function createIndicatorStr(task: TaskCopy): string {
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
function createContextMenu(showApp: () => void, quitApp: () => void): Menu {
return Menu.buildFromTemplate([
{
label: 'Show App',
click: showApp,
},
{
label: 'Quit',
click: quitApp,
},
{ label: 'Show App', click: showApp },
{ label: 'Quit', click: quitApp },
]);
}

Expand Down Expand Up @@ -180,3 +185,11 @@ function isWindows11(): boolean {

return isWin11;
}

// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
function getCountdownMessage(countdownMs: number): string {
const totalSeconds = Math.floor(countdownMs / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}
3 changes: 2 additions & 1 deletion electron/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ const ea: ElectronAPI = {

backupAppData: (appData) => _send('BACKUP', appData),

updateCurrentTask: (task) => _send('CURRENT_TASK_UPDATED', task),
updateCurrentTask: (task, isPomodoroEnabled, currentPomodoroSessionTime) =>
_send('CURRENT_TASK_UPDATED', task, isPomodoroEnabled, currentPomodoroSessionTime),

exec: (command: string) => _send('EXEC', command),
};
Expand Down
16 changes: 13 additions & 3 deletions src/app/features/tasks/store/task-electron.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { selectCurrentTask } from './task.selectors';
import { IS_ELECTRON } from '../../../app.constants';
import { GlobalConfigService } from '../../config/global-config.service';
import { selectIsFocusOverlayShown } from '../../focus-mode/store/focus-mode.selectors';
import { PomodoroService } from '../../pomodoro/pomodoro.service';

// TODO send message to electron when current task changes here

Expand All @@ -15,15 +16,24 @@ export class TaskElectronEffects {
private _actions$ = inject(Actions);
private _store$ = inject<Store<any>>(Store);
private _configService = inject(GlobalConfigService);
private _pomodoroService = inject(PomodoroService);

taskChangeElectron$: any = createEffect(
() =>
this._actions$.pipe(
ofType(setCurrentTask, unsetCurrentTask, addTimeSpent),
withLatestFrom(this._store$.pipe(select(selectCurrentTask))),
tap(([action, current]) => {
withLatestFrom(
this._store$.pipe(select(selectCurrentTask)),
this._pomodoroService.isEnabled$,
this._pomodoroService.currentSessionTime$,
),
tap(([action, current, isPomodoroEnabled, currentPomodoroSessionTime]) => {
if (IS_ELECTRON) {
window.ea.updateCurrentTask(current);
window.ea.updateCurrentTask(
current,
isPomodoroEnabled,
currentPomodoroSessionTime,
);
}
}),
),
Expand Down
Loading