Skip to content

Commit

Permalink
feat: Restore previous settings after restarting program (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
sonjek authored Apr 9, 2024
1 parent a737a92 commit c5815ed
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 34 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ module github.com/sonjek/mouse-stay-up
go 1.22

require (
github.com/adrg/xdg v0.4.0
github.com/getlantern/systray v1.2.2
github.com/go-vgo/robotgo v0.110.0
gopkg.in/ini.v1 v1.67.0
)

require (
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down Expand Up @@ -150,6 +152,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -170,6 +173,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
69 changes: 55 additions & 14 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package config

import (
"fmt"

"github.com/sonjek/mouse-stay-up/pkg/config"
)

const (
gitRepo string = "https://github.com/sonjek/mouse-stay-up"
GitRepo string = "https://github.com/sonjek/mouse-stay-up"
appName string = "mouse-stay-up"
configFileName string = "config.conf"

workingHours00_00 = "00:00-00:00"
workingHours08_18 = "08:00-18:00"
Expand All @@ -10,34 +18,67 @@ const (
workingHours10_20 = "10:00-20:00"
)

var workingHours = []string{
workingHours08_18,
workingHours09_19,
workingHours10_19,
workingHours10_20,
workingHours00_00,
}
var (
configFilePath string

workingHours = []string{
workingHours08_18,
workingHours09_19,
workingHours10_19,
workingHours10_20,
workingHours00_00,
}
)

type Config struct {
Enabled bool
GitRepo string
WorkingHoursInterval string
WorkingHours []string
Enabled bool `ini:"enabled"`
WorkingHoursInterval string `ini:"working-hours-interval"`
WorkingHours []string `ini:"working-hours,omitempty"`
}

func init() {
// Create a folder to save the config file if it doesn't exist yet
if err := config.CreateConfigFolder(appName); err != nil {
fmt.Println(err)
}

// Calculate the configuration file path for saving when app parameters change
configFilePath = config.GetConfigFilePath(appName, configFileName)
}

func NewConfig() *Config {
return &Config{
// Define the default Config struct
appConfig := &Config{
Enabled: true,
GitRepo: gitRepo,
WorkingHoursInterval: workingHours10_19,
WorkingHours: workingHours,
}

// Restores the configuration from disk if it exists
isRestored := config.LoadFileToStruct(configFilePath, appConfig)

// Saves the struct to an configuration file if it doesn't exist yet
if !isRestored {
saveConfig(appConfig)
}

return appConfig
}

func (c *Config) ToggleEnableDisable() {
c.Enabled = !c.Enabled

saveConfig(c)
}

func (c *Config) SetWorkingHoursInterval(interval string) {
c.WorkingHoursInterval = interval

saveConfig(c)
}

func saveConfig(appConfig *Config) {
if err := config.SaveStructToFile(configFilePath, appConfig); err != nil {
fmt.Println(err)
}
}
48 changes: 28 additions & 20 deletions internal/tray/tray.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ func loadIcon() ([]byte, error) {
type Tray struct {
mouseController *mouse.Controller
conf *config.Config
mEnable *systray.MenuItem
mDisable *systray.MenuItem
mWorkingHours *systray.MenuItem
workingHoursMenuItems map[string]*systray.MenuItem
}

Expand All @@ -58,25 +61,21 @@ func (t *Tray) onReady() {
systray.SetTooltip("Enable or Disable periodic mouse movements")

// Create menu items for enable/disable mouse movement, change working hours and exit
mEnable := systray.AddMenuItem("Enable", "Enable mouse movement")
mDisable := systray.AddMenuItem("Disable", "Disable mouse movement")
mWorkingHours := systray.AddMenuItem("Working hours", "Select a range of working hours")
t.mEnable = systray.AddMenuItem("Enable", "Enable mouse movement")
t.mDisable = systray.AddMenuItem("Disable", "Disable mouse movement")
t.mWorkingHours = systray.AddMenuItem("Working hours", "Select a range of working hours")
systray.AddSeparator()
mAbout := systray.AddMenuItem("About", "Open GitHub repo")
mQuit := systray.AddMenuItem("Quit", "Quit the application")

// Hide the enable option since it's already enabled by default
if t.conf.Enabled {
mEnable.Hide()
} else {
mDisable.Hide()
}

// Add interval selection submenu items
for _, hours := range t.conf.WorkingHours {
t.addWorkingHoursItems(mWorkingHours, hours)
t.addWorkingHoursItems(t.mWorkingHours, hours)
}

// Adjust visibilities based on the app state
t.applyEnableDisable()

// Set a marker for the default working hours interval
t.workingHoursMenuItems[t.conf.WorkingHoursInterval].Check()

Expand All @@ -85,23 +84,19 @@ func (t *Tray) onReady() {
go func() {
for {
select {
case <-mEnable.ClickedCh:
case <-t.mEnable.ClickedCh:
t.conf.ToggleEnableDisable()
mEnable.Hide()
mDisable.Show()
mWorkingHours.Enable()
t.applyEnableDisable()
go t.mouseController.MoveMouse()
case <-mDisable.ClickedCh:
case <-t.mDisable.ClickedCh:
t.conf.ToggleEnableDisable()
mDisable.Hide()
mEnable.Show()
mWorkingHours.Disable()
t.applyEnableDisable()
case workingHoursInterval := <-workingHoursIntervalClicks:
// When an hours interval item is clicked, update the workingHoursInterval interval and checkmarks
t.conf.SetWorkingHoursInterval(workingHoursInterval)
t.updateNightModeIntervalChecks(t.conf.WorkingHoursInterval)
case <-mAbout.ClickedCh:
if err := utils.OpenWebPage(t.conf.GitRepo); err != nil {
if err := utils.OpenWebPage(config.GitRepo); err != nil {
panic(err)
}
case <-mQuit.ClickedCh:
Expand Down Expand Up @@ -147,5 +142,18 @@ func (t *Tray) updateNightModeIntervalChecks(selectedInterval string) {
}
}

// Adjust visibilities based on the app state
func (t *Tray) applyEnableDisable() {
if t.conf.Enabled {
t.mEnable.Hide()
t.mDisable.Show()
t.mWorkingHours.Enable()
} else {
t.mEnable.Show()
t.mDisable.Hide()
t.mWorkingHours.Disable()
}
}

func (t *Tray) onExit() {
}
70 changes: 70 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package config

import (
"fmt"
"os"

"github.com/adrg/xdg"
"gopkg.in/ini.v1"
)

// Create a folder to save the config file if it doesn't exist yet
func CreateConfigFolder(appName string) error {
// Use xdg to get the config file folder path
configPath, err := xdg.ConfigFile(appName)
if err != nil {
return fmt.Errorf("error getting config file path: %w", err)
}

// Create a home folder if it does not exist
if _, err := os.Stat(configPath); os.IsNotExist(err) {
if err := os.MkdirAll(configPath, os.ModePerm); err != nil {
return fmt.Errorf("error creating config directory: %w", err)
}
}

return nil
}

// Calculate the configuration file path
func GetConfigFilePath(appName, configFileName string) string {
configPath, err := xdg.ConfigFile(appName + "/" + configFileName)
if err != nil {
fmt.Println("Error getting config file path:", err)
return ""
}
return configPath
}

// Saves the struct to an configuration file
func SaveStructToFile(configFilePath string, config any) error {
// Reflect data sources from given struct
cfg := ini.Empty()
if err := ini.ReflectFrom(cfg, config); err != nil {
return fmt.Errorf("error reflecting config struct: %w", err)
}

// Save the configuration file into disk
if err := cfg.SaveTo(configFilePath); err != nil {
return fmt.Errorf("error saving config to file: %w", err)
}

return nil
}

// Restores the configuration file into the struct
func LoadFileToStruct(configFilePath string, config any) bool {
// Try to load the configuration file from disk if it exists
cfg, err := ini.Load(configFilePath)
if err != nil {
return false
}

// Try to map the configuration file from disk into the struct
if err := cfg.MapTo(config); err != nil {
fmt.Printf("error mapping INI to config struct: %s", err.Error())
return false
}

return true
}

0 comments on commit c5815ed

Please sign in to comment.