2025-08-30 12:15:55 +01:00
// See the LICENSE file to see your liberties and restrictions.
package main
import (
2025-08-30 16:28:42 +01:00
"time"
2025-08-30 12:15:55 +01:00
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
func main ( ) {
var timer time . Duration
var ticking bool = false
2025-08-30 16:28:42 +01:00
var status string = "WORK TIME"
// TODO: GET DEFAULT WORK AND BREAK TIMES FROM FILESYSTEM
var defaultWorkTime string = "25m"
var defaultBreakTime string = "5m"
2025-08-30 12:15:55 +01:00
a := app . New ( )
2025-08-30 16:28:42 +01:00
w := a . NewWindow ( status )
2025-08-30 12:15:55 +01:00
w . SetFixedSize ( true )
w . Resize ( fyne . NewSize ( 400 , 50 ) )
workEntry := widget . NewEntry ( )
2025-08-30 16:28:42 +01:00
workEntry . SetText ( defaultWorkTime )
2025-08-30 12:15:55 +01:00
workEntry . TextStyle . Monospace = true
workEntry . Refresh ( )
breakEntry := widget . NewEntry ( )
2025-08-30 16:28:42 +01:00
breakEntry . SetText ( defaultBreakTime )
2025-08-30 12:15:55 +01:00
breakEntry . TextStyle . Monospace = true
2025-08-30 16:28:42 +01:00
2025-08-30 12:15:55 +01:00
breakEntry . Refresh ( )
var beginButton * widget . Button
beginButton = widget . NewButtonWithIcon ( "Start" , theme . Icon ( theme . IconNameMediaPlay ) , func ( ) {
go func ( ) {
if ! ticking {
ticking = true
2025-08-30 16:28:42 +01:00
var duration time . Duration
var err error
if status == "WORK TIME" {
duration , err = time . ParseDuration ( workEntry . Text )
} else {
duration , err = time . ParseDuration ( breakEntry . Text )
}
2025-08-30 12:15:55 +01:00
if err != nil {
neww := fyne . CurrentApp ( ) . NewWindow ( "Error" )
neww . Resize ( fyne . NewSize ( 500 , 500 ) )
fyne . Do ( func ( ) {
neww . Show ( )
} )
err_dialog := dialog . NewError ( err , neww )
err_dialog . SetOnClosed ( func ( ) {
neww . Close ( )
} )
err_dialog . Show ( )
ticking = false
return
}
beginButton . Icon = theme . Icon ( theme . IconNameMediaPause )
fyne . Do ( func ( ) {
beginButton . SetText ( "Stop" )
} )
beginButton . Importance = widget . LowImportance
fyne . Do ( func ( ) {
beginButton . Refresh ( )
} )
timer = duration
timeStarted := time . Now ( )
for ticking {
cur := time . Since ( timeStarted )
2025-08-30 16:28:42 +01:00
if status == "WORK TIME" {
workEntry . Disable ( )
workEntry . SetText ( ( cur . Round ( time . Second ) - timer . Round ( time . Second ) ) . Abs ( ) . String ( ) )
} else {
breakEntry . Disable ( )
breakEntry . SetText ( ( cur . Round ( time . Second ) - timer . Round ( time . Second ) ) . Abs ( ) . String ( ) )
}
2025-08-30 12:15:55 +01:00
if cur >= timer {
2025-08-30 16:28:42 +01:00
if status == "WORK TIME" {
status = "BREAK TIME"
workEntry . SetText ( defaultWorkTime )
workEntry . Enable ( )
timer , err = time . ParseDuration ( breakEntry . Text )
if err != nil {
panic ( err )
}
timer = timer + cur
w . SetTitle ( status )
} else {
status = "WORK TIME"
breakEntry . SetText ( defaultBreakTime )
breakEntry . Enable ( )
timer , err = time . ParseDuration ( workEntry . Text )
if err != nil {
panic ( err )
}
timer = timer + cur
w . SetTitle ( status )
}
2025-08-30 12:15:55 +01:00
} else {
time . Sleep ( time . Second * 1 )
}
}
} else {
ticking = false
workEntry . Enable ( )
2025-08-30 16:28:42 +01:00
breakEntry . Enable ( )
2025-08-30 12:15:55 +01:00
beginButton . Icon = theme . Icon ( theme . IconNameMediaPlay )
fyne . Do ( func ( ) {
beginButton . SetText ( "Start" )
} )
beginButton . Importance = widget . HighImportance
fyne . Do ( func ( ) {
beginButton . Refresh ( )
} )
}
} ( )
} )
beginButton . Importance = widget . HighImportance
2025-08-30 16:28:42 +01:00
w . SetContent ( container . NewGridWithColumns ( 3 , workEntry , breakEntry , container . NewVBox ( beginButton , widget . NewButtonWithIcon ( "Skip" , theme . Icon ( theme . IconNameMediaSkipNext ) , func ( ) {
if status == "WORK TIME" {
status = "BREAK TIME"
} else {
status = "WORK TIME"
}
w . SetTitle ( status )
} ) ) ) )
2025-08-30 12:15:55 +01:00
menu := fyne . NewMainMenu ( fyne . NewMenu ( "root" ) , fyne . NewMenu ( "help" , fyne . NewMenuItem ( "valid time arguments" , func ( ) {
neww := fyne . CurrentApp ( ) . NewWindow ( "Help" )
neww . Resize ( fyne . NewSize ( 500 , 500 ) )
fyne . Do ( func ( ) {
neww . Show ( )
} )
help_dialog := dialog . NewInformation ( "Help" , "Here are some valid time arguments:\n3ns (3 nanoseconds)\n3s (3 seconds)\n2m (2 minutes)\n2m3s (2 minutes and 3 seconds)\n2h1m1s (2 hours 1 minute and 1 second)" , neww )
help_dialog . SetOnClosed ( func ( ) {
neww . Close ( )
} )
help_dialog . Show ( )
} ) ) )
w . SetMainMenu ( menu )
w . ShowAndRun ( )
}