@@ -15,6 +15,27 @@ import { createSettingsWindow } from "./windows";
15
15
16
16
let tray : Tray ;
17
17
let lastMinsLeft = 0 ;
18
+ let disableTimeout : NodeJS . Timeout | null = null ;
19
+ let disableEndTime : number | null = null ;
20
+
21
+ function getDisableTimeRemaining ( ) : string {
22
+ if ( ! disableEndTime ) {
23
+ return "" ;
24
+ }
25
+
26
+ const remainingMs = disableEndTime - Date . now ( ) ;
27
+ const remainingMinutes = Math . floor ( remainingMs / 60000 ) ;
28
+ const remainingHours = Math . floor ( remainingMinutes / 60 ) ;
29
+ const remainingDisplayMinutes = remainingMinutes % 60 ;
30
+
31
+ if ( remainingMinutes < 1 ) {
32
+ return "<1m" ;
33
+ } else if ( remainingHours > 0 ) {
34
+ return `${ remainingHours } h ${ remainingDisplayMinutes } m` ;
35
+ } else {
36
+ return `${ remainingMinutes } m` ;
37
+ }
38
+ }
18
39
19
40
export function buildTray ( ) : void {
20
41
if ( ! tray ) {
@@ -47,11 +68,33 @@ export function buildTray(): void {
47
68
const breaksEnabled = settings . breaksEnabled ;
48
69
49
70
const setBreaksEnabled = ( breaksEnabled : boolean ) : void => {
71
+ if ( breaksEnabled && disableTimeout ) {
72
+ clearTimeout ( disableTimeout ) ;
73
+ disableTimeout = null ;
74
+ disableEndTime = null ;
75
+ }
76
+
50
77
settings = getSettings ( ) ;
51
78
setSettings ( { ...settings , breaksEnabled } ) ;
52
79
buildTray ( ) ;
53
80
} ;
54
81
82
+ const disableBreaksFor = ( duration : number ) : void => {
83
+ setBreaksEnabled ( false ) ;
84
+ disableEndTime = Date . now ( ) + duration ;
85
+
86
+ if ( disableTimeout ) {
87
+ clearTimeout ( disableTimeout ) ;
88
+ }
89
+
90
+ disableTimeout = setTimeout ( ( ) => {
91
+ disableEndTime = null ;
92
+ setBreaksEnabled ( true ) ;
93
+ } , duration ) ;
94
+
95
+ buildTray ( ) ;
96
+ } ;
97
+
55
98
const createAboutWindow = ( ) : void => {
56
99
dialog . showMessageBox ( {
57
100
title : "About" ,
@@ -87,7 +130,12 @@ export function buildTray(): void {
87
130
const contextMenu = Menu . buildFromTemplate ( [
88
131
{
89
132
label : nextBreak ,
90
- visible : breakTime !== null && inWorkingHours ,
133
+ visible : breakTime !== null && inWorkingHours && settings . breaksEnabled ,
134
+ enabled : false ,
135
+ } ,
136
+ {
137
+ label : `Disabled for ${ getDisableTimeRemaining ( ) } ` ,
138
+ visible : disableTimeout !== null && ! breaksEnabled ,
91
139
enabled : false ,
92
140
} ,
93
141
{
@@ -102,8 +150,35 @@ export function buildTray(): void {
102
150
} ,
103
151
{ type : "separator" } ,
104
152
{
105
- label : breaksEnabled ? "Disable" : "Enable" ,
106
- click : setBreaksEnabled . bind ( null , ! breaksEnabled ) ,
153
+ label : "Enable" ,
154
+ click : setBreaksEnabled . bind ( null , true ) ,
155
+ visible : ! breaksEnabled ,
156
+ } ,
157
+ {
158
+ label : "Disable..." ,
159
+ submenu : [
160
+ { label : "Indefinitely" , click : setBreaksEnabled . bind ( null , false ) } ,
161
+ { label : "30 minutes" , click : ( ) => disableBreaksFor ( 30 * 60 * 1000 ) } ,
162
+ { label : "1 hour" , click : ( ) => disableBreaksFor ( 60 * 60 * 1000 ) } ,
163
+ { label : "2 hours" , click : ( ) => disableBreaksFor ( 2 * 60 * 60 * 1000 ) } ,
164
+ { label : "4 hours" , click : ( ) => disableBreaksFor ( 4 * 60 * 60 * 1000 ) } ,
165
+ {
166
+ label : "Rest of day" ,
167
+ click : ( ) => {
168
+ const now = new Date ( ) ;
169
+ const endOfDay = new Date (
170
+ now . getFullYear ( ) ,
171
+ now . getMonth ( ) ,
172
+ now . getDate ( ) ,
173
+ 23 ,
174
+ 59 ,
175
+ 59
176
+ ) ;
177
+ disableBreaksFor ( endOfDay . getTime ( ) - now . getTime ( ) ) ;
178
+ } ,
179
+ } ,
180
+ ] ,
181
+ visible : breaksEnabled ,
107
182
} ,
108
183
{
109
184
label : "Start break now" ,
0 commit comments