From 05f6feaca205c950448827138e175b348970b2c3 Mon Sep 17 00:00:00 2001 From: "diamondburned (Forefront)" Date: Fri, 19 Jun 2020 23:55:39 -0700 Subject: [PATCH] Added a persistent config file for preferences --- internal/ui/config/config.go | 14 +++- internal/ui/config/file.go | 67 +++++++++++++++++++ internal/ui/config/preferences/preferences.go | 11 ++- main.go | 7 ++ 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 internal/ui/config/file.go diff --git a/internal/ui/config/config.go b/internal/ui/config/config.go index b38ebaf..25702ea 100644 --- a/internal/ui/config/config.go +++ b/internal/ui/config/config.go @@ -1,7 +1,11 @@ // Package config provides the repository for configuration and preferences. package config -import "sort" +import ( + "sort" +) + +const ConfigFile = "config.json" // List of config sections. type Section uint8 @@ -41,3 +45,11 @@ func AppearanceAdd(name string, value EntryValue) { }) sortSection(Appearance) } + +func Save() error { + return MarshalToFile(ConfigFile, Sections) +} + +func Restore() error { + return UnmarshalFromFile(ConfigFile, &Sections) +} diff --git a/internal/ui/config/file.go b/internal/ui/config/file.go new file mode 100644 index 0000000..25bdd6c --- /dev/null +++ b/internal/ui/config/file.go @@ -0,0 +1,67 @@ +package config + +import ( + "encoding/json" + "log" + "os" + "path/filepath" + + "github.com/pkg/errors" +) + +var DirPath string + +func init() { + // Load the config dir: + d, err := os.UserConfigDir() + if err != nil { + log.Fatalln("Failed to get config dir:", err) + } + + // Fill Path: + DirPath = filepath.Join(d, "cchat-gtk") + + // Ensure it exists: + if err := os.Mkdir(DirPath, 0755|os.ModeDir); err != nil && !os.IsExist(err) { + log.Fatalln("Failed to make config dir:", err) + } +} + +func MarshalToFile(file string, from interface{}) error { + file = filepath.Join(DirPath, file) + + f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_SYNC|os.O_TRUNC, 0644) + if err != nil { + return errors.Wrap(err, "Failed to open file") + } + defer f.Close() + + enc := json.NewEncoder(f) + enc.SetIndent("", "\t") + + if err := enc.Encode(from); err != nil { + return errors.Wrap(err, "Failed to marshal given struct") + } + + return nil +} + +func UnmarshalFromFile(file string, to interface{}) error { + file = filepath.Join(DirPath, file) + + f, err := os.OpenFile(file, os.O_RDONLY, 0644) + if err != nil { + // Ignore does not exist error, leave struct as it is. + if os.IsNotExist(err) { + return nil + } + return err + } + defer f.Close() + + if err := json.NewDecoder(f).Decode(to); err != nil { + return errors.Wrap(err, "Failed to unmarshal to given struct") + } + + return nil +} diff --git a/internal/ui/config/preferences/preferences.go b/internal/ui/config/preferences/preferences.go index c3f59da..292a922 100644 --- a/internal/ui/config/preferences/preferences.go +++ b/internal/ui/config/preferences/preferences.go @@ -2,8 +2,10 @@ package preferences import ( "github.com/diamondburned/cchat-gtk/internal/gts" + "github.com/diamondburned/cchat-gtk/internal/log" "github.com/diamondburned/cchat-gtk/internal/ui/config" "github.com/gotk3/gotk3/gtk" + "github.com/pkg/errors" ) type Dialog struct { @@ -79,5 +81,12 @@ func NewPreferenceDialog() *Dialog { } func SpawnPreferenceDialog() { - NewPreferenceDialog().Show() + p := NewPreferenceDialog() + p.Connect("destroy", func() { + // On close, save the settings. + if err := config.Save(); err != nil { + log.Error(errors.Wrap(err, "Failed to save settings")) + } + }) + p.Show() } diff --git a/main.go b/main.go index 0bd62f7..0d7a6b5 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,9 @@ import ( "github.com/diamondburned/cchat-gtk/internal/gts" "github.com/diamondburned/cchat-gtk/internal/log" "github.com/diamondburned/cchat-gtk/internal/ui" + "github.com/diamondburned/cchat-gtk/internal/ui/config" "github.com/diamondburned/cchat/services" + "github.com/pkg/errors" _ "github.com/diamondburned/cchat-discord" _ "github.com/diamondburned/cchat-mock" @@ -29,6 +31,11 @@ func main() { app.AddService(srvc) } + // Restore the configs. + if err := config.Restore(); err != nil { + log.Error(errors.Wrap(err, "Failed to restore config")) + } + return app })