Skip to content
Closed
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
2 changes: 2 additions & 0 deletions app/main/lib/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const defaultSettings: Settings = {
endBreakEnabled: true,
skipBreakEnabled: false,
postponeBreakEnabled: true,
halfFullTrayMinutes: 20,
almostEmptyTrayMinutes: 3,
};

const store = new Store<{
Expand Down
94 changes: 63 additions & 31 deletions app/main/lib/tray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,50 @@ import {
let tray: Tray;
let lastMinsLeft = 0;


/**
* Returns the path to the tray icon based on the status and the remaining minutes.
*
* @param {('disabled' | 'not-in-working-hours' | 'active')} status - The status of the tray icon.
* @param {number} [minsLeft] - The remaining minutes. Only used when the status is 'active'.
* @return {string} The path to the tray icon.
*/
function getTrayIconPath(status: 'disabled' | 'not-in-working-hours' | 'active', minsLeft?: number): string {
const settings = getSettings();

let trayIconFileName = "icon.png";

if (process.platform === "darwin") {
trayIconFileName = "tray-IconTemplate.png";
} else {
switch (status) {
case 'disabled':
trayIconFileName = "icon-disabled.png";
break;
case 'not-in-working-hours':
trayIconFileName = "icon-off-work.png";
break;
case 'active':
if (minsLeft !== undefined) {
if (minsLeft < settings.almostEmptyTrayMinutes) {
trayIconFileName = "icon-almost-empty.png";
} else if (minsLeft < settings.halfFullTrayMinutes) {
trayIconFileName = "icon-half-full.png";
}
}
break;
}
}

return process.env.NODE_ENV === "development"
? path.join("resources", "tray", trayIconFileName)
: path.join(process.resourcesPath, "app", "resources", "tray", trayIconFileName);
}

export function buildTray(): void {
if (!tray) {
let imgPath;
if (process.platform === "darwin") {
imgPath =
process.env.NODE_ENV === "development"
? "resources/tray/tray-IconTemplate.png"
: path.join(
process.resourcesPath,
"app/resources/tray/tray-IconTemplate.png"
);
} else {
imgPath =
process.env.NODE_ENV === "development"
? "resources/tray/icon.png"
: path.join(process.resourcesPath, "app/resources/tray/icon.png");
}
tray = new Tray(imgPath);
const trayIconPath = getTrayIconPath('disabled');
tray = new Tray(trayIconPath);

// On windows, context menu will not show on left click by default
if (process.platform === "win32") {
Expand Down Expand Up @@ -72,27 +98,33 @@ export function buildTray(): void {
const idle = checkIdle();
const minsLeft = breakTime?.diff(moment(), "minutes");

let nextBreak = "";
let toolTip = "";

if (minsLeft !== undefined) {
if (minsLeft > 1) {
nextBreak = `Next break in ${minsLeft} minutes`;
} else if (minsLeft === 1) {
nextBreak = `Next break in 1 minute`;
if (breaksEnabled) {
if (inWorkingHours) {
if (minsLeft !== undefined) {
if (minsLeft > 1) {
toolTip = `Next break in ${minsLeft} minutes`;
} else if (minsLeft === 1) {
toolTip = `Next break in 1 minute`;
} else {
toolTip = `Next break in less than a minute`;
}
tray.setImage(getTrayIconPath('active', minsLeft));
}
} else {
nextBreak = `Next break in less than a minute`;
toolTip = "Outside of working hours";
tray.setImage(getTrayIconPath("not-in-working-hours"))
}
} else {
toolTip = "Disabled";
tray.setImage(getTrayIconPath("disabled"));
}

const contextMenu = Menu.buildFromTemplate([
{
label: nextBreak,
visible: breakTime !== null && inWorkingHours,
enabled: false,
},
{
label: `Outside of working hours`,
visible: !inWorkingHours,
label: toolTip,
visible: breakTime !== null || !inWorkingHours,
enabled: false,
},
{
Expand Down Expand Up @@ -121,8 +153,8 @@ export function buildTray(): void {
{ label: "Quit", click: quit },
]);

// Call this again for Linux because we modified the context menu
tray.setContextMenu(contextMenu);
tray.setToolTip(toolTip);
}

export function initTray(): void {
Expand Down
4 changes: 2 additions & 2 deletions app/main/lib/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export function createSettingsWindow(): void {

settingsWindow = new BrowserWindow({
show: false,
width: 507,
minWidth: 507,
width: 540,
minWidth: 540,
height: process.platform === "win32" ? 740 : 700,
minHeight: process.platform === "win32" ? 740 : 700,
autoHideMenuBar: true,
Expand Down
31 changes: 30 additions & 1 deletion app/renderer/components/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ export default function SettingsEl() {
field: string,
e: React.ChangeEvent<HTMLInputElement>
): void => {
const value = e.target.type === 'number' ? Number(e.target.value) : e.target.value;
setSettingsDraft({
...settingsDraft,
[field]: e.target.value,
[field]: value,
});
};

Expand Down Expand Up @@ -318,6 +319,34 @@ export default function SettingsEl() {
</React.Fragment>
}
/>
<Tab
id="tray"
title="Tray"
panel={
<React.Fragment>
<FormGroup label="Show half-full tray icon when">
<InputGroup
type="number"
min={0}
value={settingsDraft.halfFullTrayMinutes.toString()}
onChange={handleTextChange.bind(null, "halfFullTrayMinutes")}
rightElement={<span>minutes remaining</span>}
disabled={!settingsDraft.breaksEnabled}
/>
</FormGroup>
<FormGroup label="Show almost-empty tray icon when">
<InputGroup
type="number"
min={0}
value={settingsDraft.almostEmptyTrayMinutes.toString()}
onChange={handleTextChange.bind(null, "almostEmptyTrayMinutes")}
rightElement={<span>minutes remaining</span>}
disabled={!settingsDraft.breaksEnabled}
/>
</FormGroup>
</React.Fragment>
}
/>
<Tab
id="working-hours"
title="Working Hours"
Expand Down
2 changes: 2 additions & 0 deletions app/types/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ export interface Settings {
endBreakEnabled: boolean;
skipBreakEnabled: boolean;
postponeBreakEnabled: boolean;
halfFullTrayMinutes: number;
almostEmptyTrayMinutes: number;
}
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
"app/renderer/preload.js",
"resources/icon.png",
"resources/tray/icon.png",
"resources/tray/icon-disabled.png",
"resources/tray/icon-off-work.png",
"resources/tray/icon-half-full.png",
"resources/tray/icon-almost-empty.png",
"resources/tray/tray-iconTemplate.png",
"resources/tray/[email protected]",
"resources/tray/[email protected]",
Expand Down
Binary file added resources/tray/icon-almost-empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/tray/icon-disabled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/tray/icon-half-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/tray/icon-off-work.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.