From b94c6e1ec1ead73d8929edb239eedd1ff506ee37 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Wed, 30 Jul 2025 22:33:34 +0200 Subject: [PATCH] refactor: remove old golang files --- cmd/FyneApp.toml | 8 - cmd/Icon.png | Bin 102684 -> 0 bytes cmd/build.sh | 2 - cmd/main.go | 67 ------ go.mod | 52 ---- go.sum | 123 ---------- internal/data/database.go | 156 ------------ internal/data/models.go | 15 -- internal/services/api.go | 78 ------ internal/services/settings.go | 41 ---- internal/services/training.go | 355 ---------------------------- internal/ui/components/navbutton.go | 59 ----- internal/ui/history.go | 204 ---------------- internal/ui/home.go | 92 ------- internal/ui/navbar.go | 43 ---- internal/ui/settings.go | 82 ------- internal/ui/theme/theme.go | 79 ------- internal/ui/training.go | 129 ---------- internal/ui/utils/format.go | 12 - internal/ui/utils/utils.go | 9 - 20 files changed, 1606 deletions(-) delete mode 100644 cmd/FyneApp.toml delete mode 100644 cmd/Icon.png delete mode 100755 cmd/build.sh delete mode 100644 cmd/main.go delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 internal/data/database.go delete mode 100644 internal/data/models.go delete mode 100644 internal/services/api.go delete mode 100644 internal/services/settings.go delete mode 100644 internal/services/training.go delete mode 100644 internal/ui/components/navbutton.go delete mode 100644 internal/ui/history.go delete mode 100644 internal/ui/home.go delete mode 100644 internal/ui/navbar.go delete mode 100644 internal/ui/settings.go delete mode 100644 internal/ui/theme/theme.go delete mode 100644 internal/ui/training.go delete mode 100644 internal/ui/utils/format.go delete mode 100644 internal/ui/utils/utils.go diff --git a/cmd/FyneApp.toml b/cmd/FyneApp.toml deleted file mode 100644 index 160f95e..0000000 --- a/cmd/FyneApp.toml +++ /dev/null @@ -1,8 +0,0 @@ -Website = "https://patanix.de" - -[Details] - Icon = "Icon.png" - Name = "kettlebell_tracker" - ID = "de.patanix.kettlebell_tracker" - Version = "1.0.0" - Build = 9 diff --git a/cmd/Icon.png b/cmd/Icon.png deleted file mode 100644 index 9de0222661d7f76ed53bd5ca4a9499a0f80ae325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102684 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 diff --git a/cmd/build.sh b/cmd/build.sh deleted file mode 100755 index a9b4b72..0000000 --- a/cmd/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -# fyne package -os android -release --tags -ldflags="-s -w" -fyne package -os android/arm64 -release --tags -ldflags="-s -w" -certificate my-release-key.keystore diff --git a/cmd/main.go b/cmd/main.go deleted file mode 100644 index 2fffb8f..0000000 --- a/cmd/main.go +++ /dev/null @@ -1,67 +0,0 @@ -package main - -import ( - "log" - "path/filepath" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/app" - "fyne.io/fyne/v2/container" - "git.patanix.de/git/kettlebell-app/internal/data" - "git.patanix.de/git/kettlebell-app/internal/services" - "git.patanix.de/git/kettlebell-app/internal/ui" - "git.patanix.de/git/kettlebell-app/internal/ui/theme" -) - -func main() { - myApp := app.NewWithID("com.patani.kettlebell-tracker") - myApp.Settings().SetTheme(&theme.KettlebellThemeOneDark{}) - - mainWindow := myApp.NewWindow("Kettlebell Tracker") - - dbDir := myApp.Storage().RootURI().Path() - dbPath := filepath.Join(dbDir, "giant_training.db") - dbService, err := data.NewDatabaseService(dbPath) - if err != nil { - log.Fatalf("Fehler bei der Initialisierung der Datenbank: %v", err) - } - settingsService := services.NewSettingsService(myApp) - apiService := services.NewApiService(myApp.UniqueID()) - trainingService := services.NewTrainingService(dbService, settingsService, apiService) - - contentContainer := container.NewStack() - var navigateTo func(string) - - trainingScreen, startTrainingAction := ui.MakeTrainingScreen(trainingService, settingsService, mainWindow) - - homeScreen := ui.MakeHomeScreen(trainingService, dbService, func() { - startTrainingAction() - navigateTo("training") - }) - - historyScreen := ui.MakeHistoryScreen(dbService, mainWindow) - settingsScreen := ui.MakeSettingsScreen(settingsService, mainWindow) - - screens := map[string]fyne.CanvasObject{ - "home": homeScreen, - "training": trainingScreen, - "history": historyScreen, - "settings": settingsScreen, - } - - for _, s := range screens { - contentContainer.Add(s) - } - - navBar, navigateFunc := ui.MakeNavBar(screens, contentContainer) - navigateTo = navigateFunc - - navigateTo("home") - - mainLayout := container.NewBorder(nil, navBar, nil, nil, contentContainer) - - mainWindow.SetContent(mainLayout) - mainWindow.Resize(fyne.NewSize(360, 740)) - mainWindow.SetMaster() - mainWindow.ShowAndRun() -} diff --git a/go.mod b/go.mod deleted file mode 100644 index 3975480..0000000 --- a/go.mod +++ /dev/null @@ -1,52 +0,0 @@ -module git.patanix.de/git/kettlebell-app - -go 1.24.4 - -require ( - fyne.io/fyne/v2 v2.6.1 - modernc.org/sqlite v1.38.0 -) - -require ( - fyne.io/systray v1.11.0 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/fredbi/uri v1.1.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fyne-io/gl-js v0.1.0 // indirect - github.com/fyne-io/glfw-js v0.2.0 // indirect - github.com/fyne-io/image v0.1.1 // indirect - github.com/fyne-io/oksvg v0.1.0 // indirect - github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect - github.com/go-text/render v0.2.0 // indirect - github.com/go-text/typesetting v0.2.1 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/hack-pad/go-indexeddb v0.3.2 // indirect - github.com/hack-pad/safejs v0.1.0 // indirect - github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 // indirect - github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect - github.com/nicksnyder/go-i18n/v2 v2.5.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/rymdport/portal v0.4.1 // indirect - github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect - github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect - github.com/stretchr/testify v1.10.0 // indirect - github.com/yuin/goldmark v1.7.8 // indirect - golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect - golang.org/x/image v0.24.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.22.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.65.10 // indirect - modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.11.0 // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index f2fb41a..0000000 --- a/go.sum +++ /dev/null @@ -1,123 +0,0 @@ -fyne.io/fyne/v2 v2.6.1 h1:kjPJD4/rBS9m2nHJp+npPSuaK79yj6ObMTuzR6VQ1Is= -fyne.io/fyne/v2 v2.6.1/go.mod h1:YZt7SksjvrSNJCwbWFV32WON3mE1Sr7L41D29qMZ/lU= -fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg= -fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= -github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8= -github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fyne-io/gl-js v0.1.0 h1:8luJzNs0ntEAJo+8x8kfUOXujUlP8gB3QMOxO2mUdpM= -github.com/fyne-io/gl-js v0.1.0/go.mod h1:ZcepK8vmOYLu96JoxbCKJy2ybr+g1pTnaBDdl7c3ajI= -github.com/fyne-io/glfw-js v0.2.0 h1:8GUZtN2aCoTPNqgRDxK5+kn9OURINhBEBc7M4O1KrmM= -github.com/fyne-io/glfw-js v0.2.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk= -github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA= -github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM= -github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw= -github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI= -github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA= -github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc= -github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU= -github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8= -github.com/go-text/typesetting v0.2.1/go.mod h1:mTOxEwasOFpAMBjEQDhdWRckoLLeI/+qrQeBCTGEt6M= -github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0= -github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQbSBI91A= -github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0= -github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8= -github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio= -github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 h1:wMeVzrPO3mfHIWLZtDcSaGAe2I4PW9B/P5nMkRSwCAc= -github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o= -github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M= -github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= -github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk= -github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= -github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rymdport/portal v0.4.1 h1:2dnZhjf5uEaeDjeF/yBIeeRo6pNI2QAKm7kq1w/kbnA= -github.com/rymdport/portal v0.4.1/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4= -github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE= -github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= -github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= -github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= -github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= -golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= -golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s= -modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= -modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= -modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA= -modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= -modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= -modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc= -modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po= -modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= -modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= -modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= -modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= -modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= -modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= -modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI= -modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE= -modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= -modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/internal/data/database.go b/internal/data/database.go deleted file mode 100644 index d4ad757..0000000 --- a/internal/data/database.go +++ /dev/null @@ -1,156 +0,0 @@ -package data - -import ( - "database/sql" - "fmt" - "log" - "time" - - _ "modernc.org/sqlite" -) - -type DatabaseService struct { - DB *sql.DB -} - -func NewDatabaseService(dbPath string) (*DatabaseService, error) { - db, err := sql.Open("sqlite", dbPath) - if err != nil { - return nil, err - } - if err = db.Ping(); err != nil { - return nil, err - } - createTableSQL := ` - CREATE TABLE IF NOT EXISTS training ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - date TEXT NOT NULL, - sets INTEGER, - weightLeft REAL, - weightRight REAL, - repsPerSet INTEGER, - duration INTEGER, - program TEXT, - blockDay INTEGER - );` - _, err = db.Exec(createTableSQL) - if err != nil { - log.Printf("Fehler beim Erstellen der Tabelle: %v", err) - return nil, err - } - log.Println("Datenbank erfolgreich initialisiert.") - return &DatabaseService{DB: db}, nil -} - -func (s *DatabaseService) SaveTraining(session *TrainingSession) error { - dateStr := session.Date.Format(time.RFC3339) - query := ` - INSERT INTO training (id, date, sets, weightLeft, weightRight, repsPerSet, duration, program, blockDay) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(id) DO UPDATE SET - date = excluded.date, - sets = excluded.sets, - weightLeft = excluded.weightLeft, - weightRight = excluded.weightRight, - repsPerSet = excluded.repsPerSet, - duration = excluded.duration, - program = excluded.program, - blockDay = excluded.blockDay; - ` - var id any - if session.ID != 0 { - id = session.ID - } - _, err := s.DB.Exec(query, id, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay) - return err -} - -func (s *DatabaseService) GetHistory() ([]TrainingSession, error) { - query := `SELECT id, date, sets, weightLeft, weightRight, repsPerSet, duration, program, blockDay FROM training ORDER BY date DESC LIMIT 20;` - rows, err := s.DB.Query(query) - if err != nil { - return nil, err - } - defer rows.Close() - var sessions []TrainingSession - for rows.Next() { - var sess TrainingSession - var dateStr string - err := rows.Scan(&sess.ID, &dateStr, &sess.Sets, &sess.WeightLeft, &sess.WeightRight, &sess.RepsPerSet, &sess.Duration, &sess.Program, &sess.BlockDay) - if err != nil { - return nil, err - } - sess.Date, err = time.Parse(time.RFC3339, dateStr) - if err != nil { - return nil, err - } - sessions = append(sessions, sess) - } - return sessions, nil -} - -func (s *DatabaseService) GetLastTraining() (*TrainingSession, error) { - query := `SELECT id, date, sets, weightLeft, weightRight, repsPerSet, duration, program, blockDay FROM training ORDER BY date DESC LIMIT 1;` - row := s.DB.QueryRow(query) - - var session TrainingSession - var dateStr string - err := row.Scan(&session.ID, &dateStr, &session.Sets, &session.WeightLeft, &session.WeightRight, &session.RepsPerSet, &session.Duration, &session.Program, &session.BlockDay) - if err != nil { - if err == sql.ErrNoRows { - return nil, nil - } - return nil, err - } - - session.Date, err = time.Parse(time.RFC3339, dateStr) - if err != nil { - return nil, err - } - - return &session, nil -} - -func (s *DatabaseService) GetTrainingCount() (int, error) { - var count int - query := "SELECT COUNT(*) FROM training;" - err := s.DB.QueryRow(query).Scan(&count) - if err != nil { - if err == sql.ErrNoRows { - return 0, nil - } - return 0, err - } - return count, nil -} - -func (s *DatabaseService) DeleteTraining(id int64) error { - query := "DELETE FROM training WHERE id = ?;" - _, err := s.DB.Exec(query, id) - return err -} - -func (s *DatabaseService) UpdateTraining(session *TrainingSession) error { - dateStr := session.Date.Format(time.RFC3339) - query := ` - UPDATE training - SET date = ?, sets = ?, weightLeft = ?, weightRight = ?, repsPerSet = ?, duration = ?, program = ?, blockDay = ? - WHERE id = ?; - ` - res, err := s.DB.Exec(query, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay, session.ID) - if err != nil { - log.Printf("UpdateTraining Fehler: %v", err) - return err - } - rowsAffected, err := res.RowsAffected() - if err != nil { - log.Printf("UpdateTraining RowsAffected Fehler: %v", err) - return err - } - if rowsAffected == 0 { - log.Printf("UpdateTraining: Kein Datensatz mit ID %d gefunden", session.ID) - return fmt.Errorf("kein Datensatz mit ID %d gefunden", session.ID) - } - log.Printf("UpdateTraining erfolgreich für ID %d", session.ID) - return nil -} diff --git a/internal/data/models.go b/internal/data/models.go deleted file mode 100644 index 17baa75..0000000 --- a/internal/data/models.go +++ /dev/null @@ -1,15 +0,0 @@ -package data - -import "time" - -type TrainingSession struct { - ID int64 `db:"id"` - Date time.Time `db:"date"` - Sets int64 `db:"sets"` - WeightLeft float64 `db:"weightLeft"` - WeightRight float64 `db:"weightRight"` - RepsPerSet int64 `db:"repsPerSet"` - Duration int64 `db:"duration"` - Program string `db:"program"` - BlockDay int64 `db:"blockDay"` -} diff --git a/internal/services/api.go b/internal/services/api.go deleted file mode 100644 index 9c7afad..0000000 --- a/internal/services/api.go +++ /dev/null @@ -1,78 +0,0 @@ -package services - -import ( - "bytes" - "encoding/json" - "log" - "net/http" - "time" - - "git.patanix.de/git/kettlebell-app/internal/data" -) - -type TrainingPayload struct { - Reps int `json:"reps"` - Rest float64 `json:"rest"` - Sets int `json:"sets"` - UUID string `json:"uuid"` -} - -type ApiService struct { - client *http.Client - endpoint string - uuid string -} - -func NewApiService(appUUID string) *ApiService { - return &ApiService{ - client: &http.Client{ - Timeout: 5 * time.Second, - }, - endpoint: "http://192.168.178.43:8080/trainings/", - uuid: appUUID, - } -} - -func (s *ApiService) SendTrainingData(session *data.TrainingSession) { - var rest float64 - if session.Sets > 0 { - rest = float64(session.Duration) / float64(session.Sets) - } - - payload := TrainingPayload{ - Reps: int(session.RepsPerSet), - Rest: rest, - Sets: int(session.Sets), - UUID: s.uuid, - } - - jsonData, err := json.Marshal(payload) - if err != nil { - log.Printf("API Fehler: Konnte Payload nicht in JSON umwandeln: %v", err) - return - } - - req, err := http.NewRequest("POST", s.endpoint, bytes.NewBuffer(jsonData)) - if err != nil { - log.Printf("API Fehler: Konnte Request nicht erstellen: %v", err) - return - } - req.Header.Set("Content-Type", "application/json") - - log.Printf("Sende Training an Backend: %s", string(jsonData)) - resp, err := s.client.Do(req) - if err != nil { - log.Printf("API Fehler: Fehler beim Senden des Trainings: %v", err) - return - } - defer resp.Body.Close() - - if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusCreated { - log.Println("Training erfolgreich an Backend gesendet.") - } else { - log.Printf("API Fehler: Unerwarteter Statuscode: %s", resp.Status) - // Optional: Den Body der Antwort lesen, um mehr Details zu erhalten. - // body, _ := io.ReadAll(resp.Body) - // log.Printf("Antwort-Body: %s", string(body)) - } -} diff --git a/internal/services/settings.go b/internal/services/settings.go deleted file mode 100644 index a00e55b..0000000 --- a/internal/services/settings.go +++ /dev/null @@ -1,41 +0,0 @@ -package services - -import ( - "fyne.io/fyne/v2" -) - -type Settings struct { - TrainingTimeMinutes int - WeightLeft float64 - WeightRight float64 - GoalSets int - InitialProgram string -} - -type SettingsService struct { - prefs fyne.Preferences -} - -func NewSettingsService(app fyne.App) *SettingsService { - return &SettingsService{ - prefs: app.Preferences(), - } -} - -func (s *SettingsService) LoadSettings() *Settings { - return &Settings{ - TrainingTimeMinutes: s.prefs.IntWithFallback("trainingTimeMinutes", 20), - WeightLeft: s.prefs.FloatWithFallback("weightLeft", 16.0), - WeightRight: s.prefs.FloatWithFallback("weightRight", 16.0), - GoalSets: s.prefs.IntWithFallback("goalSets", 5), - InitialProgram: s.prefs.StringWithFallback("initialProgram", "giant_1.0"), - } -} - -func (s *SettingsService) SaveSettings(settings *Settings) { - s.prefs.SetInt("trainingTimeMinutes", settings.TrainingTimeMinutes) - s.prefs.SetFloat("weightLeft", settings.WeightLeft) - s.prefs.SetFloat("weightRight", settings.WeightRight) - s.prefs.SetInt("goalSets", settings.GoalSets) - s.prefs.SetString("initialProgram", settings.InitialProgram) -} diff --git a/internal/services/training.go b/internal/services/training.go deleted file mode 100644 index db5ad67..0000000 --- a/internal/services/training.go +++ /dev/null @@ -1,355 +0,0 @@ -// package services -// -// import ( -// -// "log" -// "time" -// -// "git.patanix.de/git/kettlebell-app/internal/data" -// -// ) -// -// // TrainingState hält den aktuellen Zustand einer laufenden Trainingseinheit. -// -// type TrainingState struct { -// IsTrainingRunning bool -// RemainingSeconds int -// InitialDurationSeconds int -// SetsDone int -// GoalSets int -// RepsPerSet int -// SetTimes []time.Time -// Progress float64 -// SecondsSinceLastSet int -// LastSetTimestamp *time.Time -// CurrentProgram string -// CurrentBlockDay int -// CurrentReps int -// TotalTrainingDays int -// } -// -// func NewTrainingState() *TrainingState { -// return &TrainingState{ -// IsTrainingRunning: false, -// RemainingSeconds: 0, -// InitialDurationSeconds: 0, -// SetsDone: 0, -// GoalSets: 5, -// RepsPerSet: 5, -// Progress: 0.0, -// SecondsSinceLastSet: 0, -// LastSetTimestamp: nil, -// CurrentProgram: "giant_1.0", -// CurrentBlockDay: 1, -// CurrentReps: 5, -// TotalTrainingDays: 0, -// SetTimes: []time.Time{}, -// } -// } -// -// type TrainingService struct { -// State *TrainingState -// dbService *data.DatabaseService -// settingsService *SettingsService -// } -// -// func NewTrainingService(db *data.DatabaseService, settings *SettingsService) *TrainingService { -// initialState := NewTrainingState() -// trainingCount, err := db.GetTrainingCount() -// if err != nil { -// log.Printf("Fehler beim Abrufen der Trainingsanzahl, setze auf 0: %v", err) -// initialState.TotalTrainingDays = 0 -// } else { -// initialState.TotalTrainingDays = trainingCount -// } -// return &TrainingService{ -// State: initialState, -// dbService: db, -// settingsService: settings, -// } -// } -// -// func (s *TrainingService) updateProgram() { -// st := s.State -// newTotalDays := st.TotalTrainingDays + 1 -// newProgram := st.CurrentProgram -// newDay := (st.CurrentBlockDay % 3) + 1 -// newReps := st.CurrentReps -// -// if newTotalDays > 0 && newTotalDays%12 == 0 { -// switch st.CurrentProgram { -// case "giant_1.0": -// newProgram = "ksk_1.0" -// case "giant_1.1": -// newProgram = "ksk_1.1" -// case "giant_1.2": -// newProgram = "ksk_1.2" -// case "ksk_1.0": -// newProgram = "giant_1.1" -// case "ksk_1.1": -// newProgram = "giant_1.2" -// case "ksk_1.2": -// newProgram = "giant_1.0" -// default: -// newProgram = "giant_1.0" -// } -// newDay = 1 -// } -// -// repsMap := map[string][]int{ -// "giant_1.0": {5, 6, 4}, -// "giant_1.1": {6, 8, 7}, -// "giant_1.2": {7, 9, 8}, -// "ksk_1.0": {5, 6, 4}, -// "ksk_1.1": {6, 8, 7}, -// "ksk_1.2": {7, 9, 8}, -// } -// -// if reps, ok := repsMap[newProgram]; ok && len(reps) >= newDay { -// newReps = reps[newDay-1] -// } else { -// newReps = 5 -// } -// -// st.CurrentProgram = newProgram -// st.CurrentBlockDay = newDay -// st.CurrentReps = newReps -// st.TotalTrainingDays = newTotalDays -// } -// -// func (s *TrainingService) StartTraining(minutes, goal int) { -// s.updateProgram() -// duration := minutes * 60 -// s.State = &TrainingState{ -// IsTrainingRunning: true, -// InitialDurationSeconds: duration, -// RemainingSeconds: duration, -// GoalSets: goal, -// RepsPerSet: s.State.CurrentReps, -// CurrentProgram: s.State.CurrentProgram, -// CurrentBlockDay: s.State.CurrentBlockDay, -// TotalTrainingDays: s.State.TotalTrainingDays, -// SetTimes: []time.Time{}, -// } -// } -// -// func (s *TrainingService) Tick() { -// if s.State.RemainingSeconds > 0 { -// s.State.RemainingSeconds-- -// } -// } -// -// func (s *TrainingService) TickLastSetTimer() { -// if s.State.IsTrainingRunning && s.State.LastSetTimestamp != nil { -// s.State.SecondsSinceLastSet = int(time.Since(*s.State.LastSetTimestamp).Seconds()) -// } -// } -// -// func (s *TrainingService) CompleteSet() { -// st := s.State -// st.SetsDone++ -// now := time.Now() -// st.SetTimes = append(st.SetTimes, now) -// if st.GoalSets > 0 { -// st.Progress = min(float64(st.SetsDone)/float64(st.GoalSets), 1.0) -// } -// st.LastSetTimestamp = &now -// st.SecondsSinceLastSet = 0 -// } -// -// func (s *TrainingService) FinishTraining(session *data.TrainingSession) error { -// session.Program = s.State.CurrentProgram -// session.BlockDay = int64(s.State.CurrentBlockDay) -// -// err := s.dbService.SaveTraining(session) -// if err != nil { -// return err -// } -// -// // Platzhalter für den API-Aufruf (aus api_service.dart) -// s.sendToBackend(session) -// -// s.ResetTraining() -// return nil -// } -// -// func (s *TrainingService) ResetTraining() { -// // Diesen Teil nochmals pruefen -// s.State = NewTrainingState() -// trainingCount, err := s.dbService.GetTrainingCount() -// if err != nil { -// log.Print("Unable to get training count") -// } -// s.State.CurrentBlockDay = trainingCount -// // Hier müsste man TotalTrainingDays wieder korrekt laden. -// } -// -// // sendToBackend ist ein Platzhalter für deinen API-Aufruf. -// -// func (s *TrainingService) sendToBackend(session *data.TrainingSession) { -// // Hier würde die Logik aus deinem `api_service.dart` hinkommen. -// // z.B. ein HTTP POST Request mit den Trainingsdaten. -// // Da der Service nicht existiert, loggen wir es nur. -// log.Println("Sende Trainingsdaten an das Backend (Platzhalter)...") -// // rest := float64(session.Duration) / float64(session.Sets) -// // log.Printf("Reps: %d, Rest: %.2f, Sets: %d", session.RepsPerSet, rest, session.Sets) -// } -package services - -import ( - "log" - "time" - - "git.patanix.de/git/kettlebell-app/internal/data" -) - -type TrainingState struct { - IsTrainingRunning bool - RemainingSeconds int - InitialDurationSeconds int - SetsDone int - GoalSets int - RepsPerSet int - SetTimes []time.Time - Progress float64 - SecondsSinceLastSet int - LastSetTimestamp *time.Time - CurrentProgram string - CurrentBlockDay int - CurrentReps int - TotalTrainingDays int -} - -func calculateStateByDayCount(totalDays int) (program string, blockDay, reps int) { - program = "clean_1.0" - blockDay = 1 - reps = 5 - - if totalDays > 0 { - cycleIndex := (totalDays / 12) % 6 - - programs := []string{"clean_1.0", "snatch_1.0", "clean_1.1", "snatch_1.1", "clean_1.2", "snatch_1.2"} - program = programs[cycleIndex] - - blockDay = (totalDays % 3) + 1 - } - - repsMap := map[string][]int{ - "clean_1.0": {5, 6, 4}, - "clean_1.1": {6, 8, 7}, - "clean_1.2": {7, 9, 8}, - "snatch_1.0": {5, 6, 4}, - "snatch_1.1": {6, 8, 7}, - "snatch_1.2": {7, 9, 8}, - } - - if r, ok := repsMap[program]; ok && len(r) >= blockDay { - reps = r[blockDay-1] - } - - return -} - -func NewTrainingState(db *data.DatabaseService) *TrainingState { - trainingCount, err := db.GetTrainingCount() - if err != nil { - log.Printf("Fehler beim Abrufen der Trainingsanzahl, setze auf 0: %v", err) - trainingCount = 0 - } - - program, blockDay, reps := calculateStateByDayCount(trainingCount) - - return &TrainingState{ - IsTrainingRunning: false, - TotalTrainingDays: trainingCount, - CurrentProgram: program, - CurrentBlockDay: blockDay, - CurrentReps: reps, - SetTimes: []time.Time{}, - GoalSets: 5, - RepsPerSet: reps, - } -} - -type TrainingService struct { - State *TrainingState - dbService *data.DatabaseService - settingsService *SettingsService - apiService *ApiService -} - -func NewTrainingService(db *data.DatabaseService, settings *SettingsService, api *ApiService) *TrainingService { - return &TrainingService{ - State: NewTrainingState(db), - dbService: db, - settingsService: settings, - apiService: api, - } -} - -func (s *TrainingService) StartTraining(minutes, goal int) { - program, blockDay, reps := calculateStateByDayCount(s.State.TotalTrainingDays) - - st := s.State - st.IsTrainingRunning = true - st.InitialDurationSeconds = minutes * 60 - st.RemainingSeconds = st.InitialDurationSeconds - st.GoalSets = goal - st.CurrentProgram = program - st.CurrentBlockDay = blockDay - st.CurrentReps = reps - st.RepsPerSet = reps - - st.SetsDone = 0 - st.Progress = 0.0 - st.SetTimes = []time.Time{} - st.LastSetTimestamp = nil -} - -func (s *TrainingService) Tick() { - if s.State.RemainingSeconds > 0 { - s.State.RemainingSeconds-- - } -} - -func (s *TrainingService) TickLastSetTimer() { - if s.State.IsTrainingRunning && s.State.LastSetTimestamp != nil { - s.State.SecondsSinceLastSet = int(time.Since(*s.State.LastSetTimestamp).Seconds()) - } -} - -func (s *TrainingService) CompleteSet() { - st := s.State - st.SetsDone++ - now := time.Now() - st.SetTimes = append(st.SetTimes, now) - if st.GoalSets > 0 { - st.Progress = min(float64(st.SetsDone)/float64(st.GoalSets), 1.0) - } - st.LastSetTimestamp = &now - st.SecondsSinceLastSet = 0 -} - -func (s *TrainingService) FinishTraining(session *data.TrainingSession) error { - session.Program = s.State.CurrentProgram - session.BlockDay = int64(s.State.CurrentBlockDay) - - err := s.dbService.SaveTraining(session) - if err != nil { - return err - } - - go s.apiService.SendTrainingData(session) - - s.ResetTraining() - return nil -} - -func (s *TrainingService) ResetTraining() { - s.State = NewTrainingState(s.dbService) -} - -// sendToBackend ist ein Platzhalter für deinen API-Aufruf. -func (s *TrainingService) sendToBackend(session *data.TrainingSession) { - log.Println("Sende Trainingsdaten an das Backend (Platzhalter)...") -} diff --git a/internal/ui/components/navbutton.go b/internal/ui/components/navbutton.go deleted file mode 100644 index 7e03c81..0000000 --- a/internal/ui/components/navbutton.go +++ /dev/null @@ -1,59 +0,0 @@ -package components - -import ( - "image/color" - - "git.patanix.de/git/kettlebell-app/internal/ui/theme" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/widget" -) - -type NavButton struct { - widget.BaseWidget - icon *canvas.Image - label *canvas.Text - onTapped func() - isActive bool - container *fyne.Container -} - -func NewNavButton(label string, iconRes fyne.Resource, active bool, tapped func()) *NavButton { - icon := canvas.NewImageFromResource(iconRes) - icon.FillMode = canvas.ImageFillContain - icon.SetMinSize(fyne.NewSize(28, 28)) - - text := canvas.NewText(label, color.White) - text.TextSize = 12 - text.Alignment = fyne.TextAlignCenter - - button := &NavButton{ - icon: icon, - label: text, - onTapped: tapped, - } - button.ExtendBaseWidget(button) - button.container = container.NewVBox(icon, text) - button.SetActive(active) - return button -} - -func (b *NavButton) CreateRenderer() fyne.WidgetRenderer { - return widget.NewSimpleRenderer(b.container) -} - -func (b *NavButton) Tapped(*fyne.PointEvent) { - b.onTapped() -} - -func (b *NavButton) SetActive(active bool) { - b.isActive = active - if b.isActive { - b.label.Color = theme.OneDarkGreen - } else { - b.label.Color = theme.OneDarkText - } - b.Refresh() -} diff --git a/internal/ui/history.go b/internal/ui/history.go deleted file mode 100644 index 3c25520..0000000 --- a/internal/ui/history.go +++ /dev/null @@ -1,204 +0,0 @@ -package ui - -import ( - "fmt" - "log" - "strconv" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/dialog" - "fyne.io/fyne/v2/theme" - "fyne.io/fyne/v2/widget" - "git.patanix.de/git/kettlebell-app/internal/data" - "git.patanix.de/git/kettlebell-app/internal/ui/utils" -) - -func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.CanvasObject { - var history []data.TrainingSession - - placeholder := widget.NewLabel("Noch keine Trainingsdaten vorhanden.") - - var showDetailDialog func(session *data.TrainingSession, id int) - var refreshData func() - - list := widget.NewList( - func() int { return len(history) }, - func() fyne.CanvasObject { - return container.NewGridWithColumns(4, - widget.NewLabel(""), - widget.NewLabel(""), - widget.NewLabel(""), - widget.NewLabel(""), - ) - }, - func(i widget.ListItemID, o fyne.CanvasObject) { - session := history[i] - row := o.(*fyne.Container) - row.Objects[0].(*widget.Label).SetText(session.Date.Format("02.01.2006")) - row.Objects[1].(*widget.Label).SetText(fmt.Sprintf("%d", session.Sets)) - row.Objects[2].(*widget.Label).SetText(utils.FormatDuration(session.Duration)) - row.Objects[3].(*widget.Label).SetText(fmt.Sprintf("%d", session.RepsPerSet)) - }, - ) - - list.OnSelected = func(id widget.ListItemID) { - session := &history[id] - showDetailDialog(session, id) - list.Unselect(id) - } - - showDetailDialog = func(session *data.TrainingSession, id int) { - setsEntry := widget.NewEntry() - setsEntry.SetText(fmt.Sprintf("%d", session.Sets)) - - durationEntry := widget.NewEntry() - durationEntry.SetText(fmt.Sprintf("%d", session.Duration)) - - repsEntry := widget.NewEntry() - repsEntry.SetText(fmt.Sprintf("%d", session.RepsPerSet)) - - weightLeftEntry := widget.NewEntry() - weightLeftEntry.SetText(fmt.Sprintf("%.1f", session.WeightLeft)) - - weightRightEntry := widget.NewEntry() - weightRightEntry.SetText(fmt.Sprintf("%.1f", session.WeightRight)) - - info := container.NewVBox( - widget.NewLabel(fmt.Sprintf("Datum: %s", session.Date.Format("02.01.2006 15:04"))), - widget.NewLabel(fmt.Sprintf("Programm: %s", session.Program)), - widget.NewLabel(fmt.Sprintf("Block-Tag: %d", session.BlockDay)), - ) - - form := widget.NewForm( - &widget.FormItem{Text: "Sätze", Widget: setsEntry}, - &widget.FormItem{Text: "Dauer (Sekunden)", Widget: durationEntry}, - &widget.FormItem{Text: "Reps/Satz", Widget: repsEntry}, - &widget.FormItem{Text: "Gewicht links (kg)", Widget: weightLeftEntry}, - &widget.FormItem{Text: "Gewicht rechts (kg)", Widget: weightRightEntry}, - ) - - // Lokale Dialog-Referenz deklarieren - var detailDialog dialog.Dialog - - saveBtn := widget.NewButtonWithIcon("Speichern", theme.ConfirmIcon(), func() { - sets, err := strconv.Atoi(setsEntry.Text) - if err != nil { - dialog.ShowError(fmt.Errorf("Ungültige Sätze-Zahl"), parent) - return - } - duration, err := strconv.Atoi(durationEntry.Text) - if err != nil { - dialog.ShowError(fmt.Errorf("Ungültige Dauer"), parent) - return - } - reps, err := strconv.Atoi(repsEntry.Text) - if err != nil { - dialog.ShowError(fmt.Errorf("Ungültige Wiederholungszahl"), parent) - return - } - weightLeft, err := strconv.ParseFloat(weightLeftEntry.Text, 64) - if err != nil { - dialog.ShowError(fmt.Errorf("Ungültiges Gewicht links"), parent) - return - } - weightRight, err := strconv.ParseFloat(weightRightEntry.Text, 64) - if err != nil { - dialog.ShowError(fmt.Errorf("Ungültiges Gewicht rechts"), parent) - return - } - - session.Sets = int64(sets) - session.Duration = int64(duration) - session.RepsPerSet = int64(reps) - session.WeightLeft = weightLeft - session.WeightRight = weightRight - - if err := db.UpdateTraining(session); err != nil { - dialog.ShowError(err, parent) - return - } - dialog.ShowInformation("Erfolg", "Trainingseintrag aktualisiert.", parent) - refreshData() - detailDialog.Hide() - }) - - deleteBtn := widget.NewButtonWithIcon("Löschen", theme.DeleteIcon(), func() { - dialog.ShowConfirm("Eintrag löschen", "Möchtest du diesen Eintrag wirklich löschen?", func(ok bool) { - if ok { - err := db.DeleteTraining(session.ID) - if err != nil { - dialog.ShowError(err, parent) - return - } - refreshData() - detailDialog.Hide() - } - }, parent) - }) - - cancelBtn := widget.NewButton("Abbrechen", func() { - detailDialog.Hide() - }) - - btns := container.NewHBox(saveBtn, deleteBtn, cancelBtn) - - content := container.NewVBox( - info, - form, - btns, - ) - - detailDialog = dialog.NewCustom("Training bearbeiten/löschen", "Schließen", content, parent) - detailDialog.Show() - } - - refreshData = func() { - var err error - history, err = db.GetHistory() - if err != nil { - log.Printf("Fehler beim Laden der Historie: %v", err) - dialog.ShowError(err, parent) - return - } - if len(history) == 0 { - placeholder.Show() - list.Hide() - } else { - placeholder.Hide() - list.Show() - } - list.Refresh() - } - - header := container.NewGridWithColumns(4, - widget.NewLabelWithStyle("Datum", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}), - widget.NewLabelWithStyle("Sätze", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}), - widget.NewLabelWithStyle("Dauer", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}), - widget.NewLabelWithStyle("Reps/Satz", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}), - ) - - toolbar := widget.NewToolbar(widget.NewToolbarAction(theme.ViewRefreshIcon(), refreshData)) - // content := container.NewVBox(header, container.NewStack(list, container.NewCenter(placeholder))) - // layout := container.NewBorder(toolbar, nil, nil, nil, content) - - content := container.NewBorder( - header, - nil, - nil, - nil, - container.NewVScroll(list), - ) - - layout := container.NewBorder( - toolbar, - nil, - nil, - nil, - content, - ) - if layout.Visible() { - refreshData() - } - return layout -} diff --git a/internal/ui/home.go b/internal/ui/home.go deleted file mode 100644 index 19dedf8..0000000 --- a/internal/ui/home.go +++ /dev/null @@ -1,92 +0,0 @@ -package ui - -import ( - "fmt" - "log" - "time" - - "git.patanix.de/git/kettlebell-app/internal/data" - "git.patanix.de/git/kettlebell-app/internal/services" - - "git.patanix.de/git/kettlebell-app/internal/ui/theme" - "git.patanix.de/git/kettlebell-app/internal/ui/utils" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/widget" -) - -func MakeHomeScreen(ts *services.TrainingService, db *data.DatabaseService, onStart func()) fyne.CanvasObject { - headerTitle := canvas.NewText("Kettlebell Workout Tracker", theme.OneDarkText) - headerTitle.TextSize = 28 - headerTitle.TextStyle.Bold = true - - header := container.NewCenter( - widget.NewSeparator(), - headerTitle, - ) - - state := ts.State - startButton := widget.NewButton("Training starten", onStart) - startButton.Importance = widget.HighImportance - - nextTrainingCard := widget.NewCard( - "Nächstes Training", - fmt.Sprintf("%s - Tag %d", state.CurrentProgram, state.CurrentBlockDay), - container.NewVBox( - widget.NewLabel(fmt.Sprintf("Ziel: %d Wiederholungen pro Satz", state.CurrentReps)), - startButton, - ), - ) - centerContent := container.NewCenter(nextTrainingCard) - - setsValue := widget.NewLabelWithStyle("–", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}) - durationValue := widget.NewLabelWithStyle("–", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}) - weightValue := widget.NewLabelWithStyle("–", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}) - - statsCard := widget.NewCard("Letzte Leistung", "", container.NewGridWithColumns(3, - container.NewVBox(widget.NewLabel("Sätze"), setsValue), - container.NewVBox(widget.NewLabel("Dauer"), durationValue), - container.NewVBox(widget.NewLabel("Gewicht"), weightValue), - )) - - loadLastPerformance := func() { - lastSession, err := db.GetLastTraining() - if err != nil { - log.Printf("Fehler beim Laden der letzten Session: %v", err) - return - } - if lastSession != nil { - setsValue.SetText(fmt.Sprintf("%d", lastSession.Sets)) - durationValue.SetText(utils.FormatDuration(lastSession.Duration)) - weightValue.SetText(fmt.Sprintf("%.1fkg", lastSession.WeightLeft)) - trainedToday := false - trainedToday = EqualDate(lastSession.Date, time.Now()) - if trainedToday { - startButton.Disabled() - } - } - } - - borderLayout := container.NewBorder( - header, - statsCard, - nil, - nil, - centerContent, - ) - - paddedLayout := container.NewPadded(borderLayout) - if paddedLayout.Visible() { - loadLastPerformance() - } - - return paddedLayout -} - -func EqualDate(date1, date2 time.Time) bool { - y1, m1, d1 := date1.Date() - y2, m2, d2 := date2.Date() - return y1 == y2 && m1 == m2 && d1 == d2 -} diff --git a/internal/ui/navbar.go b/internal/ui/navbar.go deleted file mode 100644 index c367107..0000000 --- a/internal/ui/navbar.go +++ /dev/null @@ -1,43 +0,0 @@ -package ui - -import ( - "git.patanix.de/git/kettlebell-app/internal/ui/components" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/theme" -) - -func MakeNavBar(screens map[string]fyne.CanvasObject, content *fyne.Container) (fyne.CanvasObject, func(string)) { - buttons := make(map[string]*components.NavButton) - - navigateTo := func(name string) { - for key, screen := range screens { - screen.Hide() - if key == name { - screen.Show() - } - } - for key, button := range buttons { - button.SetActive(false) - if key == name { - button.SetActive(true) - } - } - content.Refresh() - } - - buttons["home"] = components.NewNavButton("Home", theme.HomeIcon(), false, func() { navigateTo("home") }) - buttons["training"] = components.NewNavButton("Training", theme.MediaPlayIcon(), false, func() { navigateTo("training") }) - buttons["history"] = components.NewNavButton("Historie", theme.ListIcon(), false, func() { navigateTo("history") }) - buttons["settings"] = components.NewNavButton("Einstellungen", theme.SettingsIcon(), false, func() { navigateTo("settings") }) - - navContainer := container.NewGridWithColumns(4, - buttons["home"], - buttons["training"], - buttons["history"], - buttons["settings"], - ) - - return navContainer, navigateTo -} diff --git a/internal/ui/settings.go b/internal/ui/settings.go deleted file mode 100644 index 9f240d8..0000000 --- a/internal/ui/settings.go +++ /dev/null @@ -1,82 +0,0 @@ -package ui - -import ( - "fmt" - "strconv" - - "git.patanix.de/git/kettlebell-app/internal/services" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/widget" -) - -func MakeSettingsScreen(settingsService *services.SettingsService, parent fyne.Window) fyne.CanvasObject { - var timeEntry, setsEntry, weightLeftEntry, weightRightEntry *widget.Entry - - loadData := func() { - currentSettings := settingsService.LoadSettings() - timeEntry.SetText(fmt.Sprintf("%d", currentSettings.TrainingTimeMinutes)) - setsEntry.SetText(fmt.Sprintf("%d", currentSettings.GoalSets)) - weightLeftEntry.SetText(fmt.Sprintf("%.1f", currentSettings.WeightLeft)) - weightRightEntry.SetText(fmt.Sprintf("%.1f", currentSettings.WeightRight)) - } - - timeEntry = widget.NewEntry() - timeEntry.Validator = func(s string) error { - if _, err := strconv.Atoi(s); err != nil { - return fmt.Errorf("muss eine Zahl sein") - } - return nil - } - - setsEntry = widget.NewEntry() - setsEntry.Validator = timeEntry.Validator - - weightLeftEntry = widget.NewEntry() - weightLeftEntry.Validator = func(s string) error { - if _, err := strconv.ParseFloat(s, 64); err != nil { - return fmt.Errorf("muss eine Zahl sein") - } - return nil - } - weightRightEntry = widget.NewEntry() - weightRightEntry.Validator = weightLeftEntry.Validator - - form := &widget.Form{ - Items: []*widget.FormItem{ - {Text: "Trainingszeit (Minuten)", Widget: timeEntry}, - {Text: "Ziel-Sätze", Widget: setsEntry}, - {Text: "Links (kg)", Widget: weightLeftEntry}, - {Text: "Rechts (kg)", Widget: weightRightEntry}, - }, - OnSubmit: func() { - timeMin, _ := strconv.Atoi(timeEntry.Text) - goal, _ := strconv.Atoi(setsEntry.Text) - weightL, _ := strconv.ParseFloat(weightLeftEntry.Text, 64) - weightR, _ := strconv.ParseFloat(weightRightEntry.Text, 64) - - newSettings := &services.Settings{ - TrainingTimeMinutes: timeMin, - GoalSets: goal, - WeightLeft: weightL, - WeightRight: weightR, - InitialProgram: settingsService.LoadSettings().InitialProgram, - } - settingsService.SaveSettings(newSettings) - fyne.CurrentApp().SendNotification(&fyne.Notification{ - Title: "Gespeichert", - Content: "Die Einstellungen wurden erfolgreich aktualisiert.", - }) - }, - } - - title := widget.NewLabelWithStyle("Einstellungen", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) - layout := container.NewVBox(title, widget.NewSeparator(), form) - paddedLayout := container.NewPadded(layout) - if paddedLayout.Visible() { - loadData() - } - - return paddedLayout -} diff --git a/internal/ui/theme/theme.go b/internal/ui/theme/theme.go deleted file mode 100644 index daf6492..0000000 --- a/internal/ui/theme/theme.go +++ /dev/null @@ -1,79 +0,0 @@ -package theme - -import ( - "image/color" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/theme" -) - -var ( - OneDarkBackground = color.NRGBA{R: 40, G: 44, B: 52, A: 0xff} // #282c34 (helleres Grau) - OneDarkCardBackground = color.NRGBA{R: 30, G: 32, B: 40, A: 0xff} // #1e2028 (dunkler für Cards) - OneDarkText = color.NRGBA{R: 171, G: 178, B: 191, A: 0xff} // #abb2bf (Standard-Text) - OneDarkSubtleText = color.NRGBA{R: 110, G: 115, B: 141, A: 0xff} // #6e738d (deaktiviert, Placeholder) - - OneDarkGreen = color.NRGBA{R: 152, G: 195, B: 121, A: 0xff} // #98c379 - OneDarkRed = color.NRGBA{R: 224, G: 108, B: 117, A: 0xff} // #e06c75 - OneDarkYellow = color.NRGBA{R: 229, G: 192, B: 123, A: 0xff} // #e5c07b -) - -type KettlebellThemeOneDark struct{} - -func (t *KettlebellThemeOneDark) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color { - switch name { - case theme.ColorNameBackground: - return OneDarkBackground - case theme.ColorNameButton: - return OneDarkGreen - case theme.ColorNameDisabledButton: - return OneDarkSubtleText - case theme.ColorNamePrimary: - return OneDarkGreen - case theme.ColorNamePlaceHolder: - return OneDarkSubtleText - case theme.ColorNameHover: - return OneDarkYellow - case theme.ColorNameForeground: - return OneDarkText - case theme.ColorNameDisabled: - return OneDarkSubtleText - case theme.ColorNameError: - return OneDarkRed - case theme.ColorNameInputBackground: - return OneDarkCardBackground - case theme.ColorNameSeparator: - return OneDarkSubtleText - case theme.ColorNameSelection: - return OneDarkYellow - case theme.ColorNameShadow: - return OneDarkCardBackground - case theme.ColorNameFocus: - return OneDarkYellow - default: - return theme.DefaultTheme().Color(name, variant) - } -} - -func (t *KettlebellThemeOneDark) Icon(name fyne.ThemeIconName) fyne.Resource { - return theme.DefaultTheme().Icon(name) -} - -func (t *KettlebellThemeOneDark) Font(style fyne.TextStyle) fyne.Resource { - return theme.DefaultTheme().Font(style) -} - -func (t *KettlebellThemeOneDark) Size(name fyne.ThemeSizeName) float32 { - switch name { - case theme.SizeNamePadding: - return 8 - case theme.SizeNameText: - return 16 - case theme.SizeNameHeadingText: - return 24 - case theme.SizeNameSubHeadingText: - return 20 - default: - return theme.DefaultTheme().Size(name) - } -} diff --git a/internal/ui/training.go b/internal/ui/training.go deleted file mode 100644 index 49bd708..0000000 --- a/internal/ui/training.go +++ /dev/null @@ -1,129 +0,0 @@ -package ui - -import ( - "fmt" - "time" - - "git.patanix.de/git/kettlebell-app/internal/data" - "git.patanix.de/git/kettlebell-app/internal/services" - "git.patanix.de/git/kettlebell-app/internal/ui/theme" - "git.patanix.de/git/kettlebell-app/internal/ui/utils" - - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/widget" -) - -func MakeTrainingScreen(ts *services.TrainingService, ss *services.SettingsService, parent fyne.Window) (fyne.CanvasObject, func()) { - timerLabel := canvas.NewText("00:00", theme.OneDarkText) - timerLabel.TextSize = 60 - timerLabel.TextStyle.Bold = true - timerLabel.Alignment = fyne.TextAlignCenter - - setsLabel := canvas.NewText("0 / 0", theme.OneDarkGreen) - setsLabel.TextSize = 48 - setsLabel.TextStyle.Bold = true - setsLabel.Alignment = fyne.TextAlignCenter - - repsLabel := canvas.NewText("0 Wiederholungen", theme.OneDarkSubtleText) - repsLabel.TextSize = 20 - repsLabel.Alignment = fyne.TextAlignCenter - - var finishButton *widget.Button - - var mainTimer *time.Ticker - - updateUI := func() { - state := ts.State - timerLabel.Text = utils.FormatDuration(int64(state.RemainingSeconds)) - setsLabel.Text = fmt.Sprintf("%d / %d", state.SetsDone, state.GoalSets) - repsLabel.Text = fmt.Sprintf("%d Wiederholungen", state.RepsPerSet) - - if finishButton != nil { - if state.RemainingSeconds <= 0 && state.IsTrainingRunning { - finishButton.Show() - } else { - finishButton.Hide() - } - } - - timerLabel.Refresh() - setsLabel.Refresh() - repsLabel.Refresh() - } - - finishAction := func() { - if ts.State.RemainingSeconds > 0 { - return - } - if mainTimer != nil { - mainTimer.Stop() - mainTimer = nil - } - if !ts.State.IsTrainingRunning { - return - } - session := &data.TrainingSession{ - Date: time.Now(), - Sets: int64(ts.State.SetsDone), - WeightLeft: ss.LoadSettings().WeightLeft, - WeightRight: ss.LoadSettings().WeightRight, - RepsPerSet: int64(ts.State.RepsPerSet), - Duration: int64(ts.State.InitialDurationSeconds - ts.State.RemainingSeconds), - } - ts.FinishTraining(session) - fyne.CurrentApp().SendNotification(&fyne.Notification{Title: "Training gespeichert!", Content: "Gut gemacht!"}) - updateUI() - } - - startAction := func() { - if ts.State.IsTrainingRunning { - return - } - settings := ss.LoadSettings() - ts.StartTraining(settings.TrainingTimeMinutes, settings.GoalSets) - updateUI() - - mainTimer = time.NewTicker(time.Second) - go func() { - for mainTimer != nil { - <-mainTimer.C - if ts.State.RemainingSeconds <= 0 { - finishAction() - return - } - ts.Tick() - updateUI() - } - }() - } - - setAction := func() { - if !ts.State.IsTrainingRunning { - return - } - ts.CompleteSet() - updateUI() - } - - topPart := container.NewVBox(widget.NewLabelWithStyle("Verbleibende Zeit", fyne.TextAlignCenter, fyne.TextStyle{}), timerLabel) - middlePart := container.NewVBox(widget.NewLabelWithStyle("Sätze", fyne.TextAlignCenter, fyne.TextStyle{}), setsLabel, repsLabel) - finishButton = widget.NewButton("Training beenden", finishAction) - finishButton.Hide() // oder: finishButton.Hide() // finishButton.Disable() - setButton := widget.NewButton("Satz abschließen", setAction) - setButton.Importance = widget.HighImportance - setButton.Resize(fyne.NewSize(120, 60)) - - bottomPart := container.NewVBox( - setButton, - finishButton, - ) - - layout := container.NewBorder(topPart, bottomPart, nil, nil, container.NewCenter(middlePart)) - if layout.Visible() { - updateUI() - } - - return layout, startAction -} diff --git a/internal/ui/utils/format.go b/internal/ui/utils/format.go deleted file mode 100644 index 1a03138..0000000 --- a/internal/ui/utils/format.go +++ /dev/null @@ -1,12 +0,0 @@ -package utils - -import "fmt" - -func FormatDuration(totalSeconds int64) string { - if totalSeconds < 0 { - totalSeconds = 0 - } - mins := totalSeconds / 60 - secs := totalSeconds % 60 - return fmt.Sprintf("%02d:%02d", mins, secs) -} diff --git a/internal/ui/utils/utils.go b/internal/ui/utils/utils.go deleted file mode 100644 index 5373c71..0000000 --- a/internal/ui/utils/utils.go +++ /dev/null @@ -1,9 +0,0 @@ -package utils - -import "fmt" - -func formatDuration(totalSeconds int64) string { - mins := totalSeconds / 60 - secs := totalSeconds % 60 - return fmt.Sprintf("%02d:%02d", mins, secs) -}