aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-05-24 23:26:57 +0300
committerTulir Asokan <tulir@maunium.net>2018-05-24 23:27:12 +0300
commitb76c8d01478bcdeb8e0f0c00ca56f577a425674b (patch)
treea3e9761a05c556730846c5645f8d9afc7c6e052b
parenta4d07e9a81f3bf0018b4f1368d8b4d06992cadba (diff)
Add UI preferences and simplify config save/load (ref #43)
-rw-r--r--config/config.go191
-rw-r--r--interface/matrix.go1
-rw-r--r--interface/ui.go1
-rw-r--r--matrix/matrix.go20
-rw-r--r--matrix/sync.go2
-rw-r--r--ui/message-view.go2
-rw-r--r--ui/ui.go8
-rw-r--r--ui/view-main.go27
8 files changed, 141 insertions, 111 deletions
diff --git a/config/config.go b/config/config.go
index a81b936..873c714 100644
--- a/config/config.go
+++ b/config/config.go
@@ -21,15 +21,27 @@ import (
"os"
"path/filepath"
- "encoding/json"
"gopkg.in/yaml.v2"
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/matrix/pushrules"
"maunium.net/go/gomuks/matrix/rooms"
"strings"
+ "encoding/json"
)
+type AuthCache struct {
+ NextBatch string `yaml:"next_batch"`
+ FilterID string `yaml:"filter_id"`
+ InitialSyncDone bool `yaml:"initial_sync_done"`
+}
+
+type UserPreferences struct {
+ HideUserList bool `yaml:"hide_user_list",json:"hide_user_list"`
+ HideRoomList bool `yaml:"hide_room_list",json:"hide_room_list"`
+ BareMessageView bool `yaml:"bare_message_view",json:"bare_message_view"`
+}
+
// Config contains the main config of gomuks.
type Config struct {
UserID string `yaml:"mxid"`
@@ -42,14 +54,10 @@ type Config struct {
MediaDir string `yaml:"media_dir"`
StateDir string `yaml:"state_dir"`
- AuthCache struct {
- NextBatch string `yaml:"next_batch"`
- FilterID string `yaml:"filter_id"`
- InitialSyncDone bool `yaml:"initial_sync_done"`
- } `yaml:"-"`
-
- Rooms map[string]*rooms.Room `yaml:"-"`
- PushRules *pushrules.PushRuleset `yaml:"-"`
+ Preferences UserPreferences `yaml:"-"`
+ AuthCache AuthCache `yaml:"-"`
+ Rooms map[string]*rooms.Room `yaml:"-"`
+ PushRules *pushrules.PushRuleset `yaml:"-"`
nosave bool
}
@@ -98,29 +106,13 @@ func (config *Config) LoadAll() {
config.Load()
config.LoadAuthCache()
config.LoadPushRules()
+ config.LoadPreferences()
config.LoadRooms()
}
// Load loads the config from config.yaml in the directory given to the config struct.
func (config *Config) Load() {
- os.MkdirAll(config.Dir, 0700)
-
- configPath := filepath.Join(config.Dir, "config.yaml")
- data, err := ioutil.ReadFile(configPath)
- if err != nil {
- if os.IsNotExist(err) {
- config.CreateCacheDirs()
- return
- }
- debug.Print("Failed to read config from", configPath)
- panic(err)
- }
-
- err = yaml.Unmarshal(data, &config)
- if err != nil {
- debug.Print("Failed to parse config at", configPath)
- panic(err)
- }
+ config.load("config", config.Dir, "config.yaml", config)
config.CreateCacheDirs()
}
@@ -128,109 +120,40 @@ func (config *Config) SaveAll() {
config.Save()
config.SaveAuthCache()
config.SavePushRules()
+ config.SavePreferences()
config.SaveRooms()
}
// Save saves this config to config.yaml in the directory given to the config struct.
func (config *Config) Save() {
- if config.nosave {
- return
- }
+ config.save("config", config.Dir, "config.yaml", config)
+}
- os.MkdirAll(config.Dir, 0700)
- data, err := yaml.Marshal(&config)
- if err != nil {
- debug.Print("Failed to marshal config")
- panic(err)
- }
+func (config *Config) LoadPreferences() {
+ config.load("user preferences", config.CacheDir, "preferences.yaml", &config.Preferences)
+}
- path := filepath.Join(config.Dir, "config.yaml")
- err = ioutil.WriteFile(path, data, 0600)
- if err != nil {
- debug.Print("Failed to write config to", path)
- panic(err)
- }
+func (config *Config) SavePreferences() {
+ config.save("user preferences", config.CacheDir, "preferences.yaml", &config.Preferences)
}
func (config *Config) LoadAuthCache() {
- os.MkdirAll(config.Dir, 0700)
-
- configPath := filepath.Join(config.CacheDir, "auth-cache.yaml")
- data, err := ioutil.ReadFile(configPath)
- if err != nil {
- if os.IsNotExist(err) {
- return
- }
- debug.Print("Failed to read auth cache from", configPath)
- panic(err)
- }
-
- err = yaml.Unmarshal(data, &config.AuthCache)
- if err != nil {
- debug.Print("Failed to parse auth cache at", configPath)
- panic(err)
- }
+ config.load("auth cache", config.CacheDir, "auth-cache.yaml", &config.AuthCache)
}
func (config *Config) SaveAuthCache() {
- if config.nosave {
- return
- }
-
- os.MkdirAll(config.CacheDir, 0700)
- data, err := yaml.Marshal(&config.AuthCache)
- if err != nil {
- debug.Print("Failed to marshal auth cache")
- panic(err)
- }
-
- path := filepath.Join(config.CacheDir, "auth-cache.yaml")
- err = ioutil.WriteFile(path, data, 0600)
- if err != nil {
- debug.Print("Failed to write auth cache to", path)
- panic(err)
- }
+ config.save("auth cache", config.CacheDir, "auth-cache.yaml", &config.AuthCache)
}
func (config *Config) LoadPushRules() {
- os.MkdirAll(config.CacheDir, 0700)
-
- pushRulesPath := filepath.Join(config.CacheDir, "pushrules.json")
- data, err := ioutil.ReadFile(pushRulesPath)
- if err != nil {
- if os.IsNotExist(err) {
- return
- }
- debug.Print("Failed to read push rules from", pushRulesPath)
- return
- }
-
- config.PushRules = &pushrules.PushRuleset{}
- err = json.Unmarshal(data, &config.PushRules)
- if err != nil {
- debug.Print("Failed to parse push rules at", pushRulesPath)
- return
- }
+ config.load("push rules", config.CacheDir, "pushrules.json", &config.PushRules)
}
func (config *Config) SavePushRules() {
- if config.nosave || config.PushRules == nil {
- return
- }
-
- os.MkdirAll(config.CacheDir, 0700)
- data, err := json.Marshal(&config.PushRules)
- if err != nil {
- debug.Print("Failed to marshal push rules")
- return
- }
-
- path := filepath.Join(config.CacheDir, "pushrules.json")
- err = ioutil.WriteFile(path, data, 0600)
- if err != nil {
- debug.Print("Failed to write config to", path)
+ if config.PushRules == nil {
return
}
+ config.save("push rules", config.CacheDir, "pushrules.json", &config.PushRules)
}
func (config *Config) LoadRooms() {
@@ -272,6 +195,56 @@ func (config *Config) SaveRooms() {
}
}
+func (config *Config) load(name, dir, file string, target interface{}) {
+ os.MkdirAll(dir, 0700)
+
+ path := filepath.Join(dir, file)
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return
+ }
+ debug.Print("Failed to read", name, "from", path)
+ panic(err)
+ }
+
+ if strings.HasSuffix(file, ".yaml") {
+ err = yaml.Unmarshal(data, target)
+ } else {
+ err = json.Unmarshal(data, target)
+ }
+ if err != nil {
+ debug.Print("Failed to parse", name, "at", path)
+ panic(err)
+ }
+}
+
+func (config *Config) save(name, dir, file string, source interface{}) {
+ if config.nosave {
+ return
+ }
+
+ os.MkdirAll(dir, 0700)
+ var data []byte
+ var err error
+ if strings.HasSuffix(file, ".yaml") {
+ data, err = yaml.Marshal(source)
+ } else {
+ data, err = json.Marshal(source)
+ }
+ if err != nil {
+ debug.Print("Failed to marshal", name)
+ panic(err)
+ }
+
+ path := filepath.Join(dir, file)
+ err = ioutil.WriteFile(path, data, 0600)
+ if err != nil {
+ debug.Print("Failed to write", name, "to", path)
+ panic(err)
+ }
+}
+
func (config *Config) GetUserID() string {
return config.UserID
}
diff --git a/interface/matrix.go b/interface/matrix.go
index 111a2b0..08b3d61 100644
--- a/interface/matrix.go
+++ b/interface/matrix.go
@@ -32,6 +32,7 @@ type MatrixContainer interface {
Login(user, password string) error
Logout()
+ SendPreferencesToMatrix()
SendMessage(roomID, msgtype, message string) (string, error)
SendMarkdownMessage(roomID, msgtype, message string) (string, error)
SendTyping(roomID string, typing bool)
diff --git a/interface/ui.go b/interface/ui.go
index 7e181d8..b106229 100644
--- a/interface/ui.go
+++ b/interface/ui.go
@@ -29,6 +29,7 @@ type UIProvider func(gmx Gomuks) GomuksUI
type GomuksUI interface {
Render()
+ HandleNewPreferences()
OnLogin()
OnLogout()
MainView() MainView
diff --git a/matrix/matrix.go b/matrix/matrix.go
index b11b9ed..556df4e 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -39,6 +39,7 @@ import (
"maunium.net/go/gomuks/matrix/pushrules"
"maunium.net/go/gomuks/matrix/rooms"
"crypto/tls"
+ "encoding/json"
)
// Container is a wrapper for a gomatrix Client and some other stuff.
@@ -188,6 +189,7 @@ func (c *Container) OnLogin() {
c.syncer.OnEventType("m.direct", c.HandleDirectChatInfo)
c.syncer.OnEventType("m.push_rules", c.HandlePushRules)
c.syncer.OnEventType("m.tag", c.HandleTag)
+ c.syncer.OnEventType("net.maunium.gomuks.preferences", c.HandlePreferences)
c.syncer.InitDoneCallback = func() {
c.config.AuthCache.InitialSyncDone = true
c.config.SaveAuthCache()
@@ -235,6 +237,24 @@ func (c *Container) Start() {
}
}
+func (c *Container) HandlePreferences(source EventSource, evt *gomatrix.Event) {
+ orig := c.config.Preferences
+ rt, _ := json.Marshal(&evt.Content)
+ json.Unmarshal(rt, &c.config.Preferences)
+ debug.Print("Updated preferences:", orig, "->", c.config.Preferences)
+ c.ui.HandleNewPreferences()
+}
+
+func (c *Container) SendPreferencesToMatrix() {
+ defer debug.Recover()
+ debug.Print("Sending updated preferences:", c.config.Preferences)
+ u := c.client.BuildURL("user", c.config.UserID, "account_data", "net.maunium.gomuks.preferences")
+ _, err := c.client.MakeRequest("PUT", u, &c.config.Preferences, nil)
+ if err != nil {
+ debug.Print("Failed to update preferences:", err)
+ }
+}
+
// HandleMessage is the event handler for the m.room.message timeline event.
func (c *Container) HandleMessage(source EventSource, evt *gomatrix.Event) {
if source&EventSourceLeave != 0 {
diff --git a/matrix/sync.go b/matrix/sync.go
index 3f6860a..2037fcd 100644
--- a/matrix/sync.go
+++ b/matrix/sync.go
@@ -184,7 +184,7 @@ func (s *GomuksSyncer) GetFilterJSON(userID string) json.RawMessage {
},
},
AccountData: gomatrix.FilterPart{
- Types: []string{"m.push_rules", "m.direct"},
+ Types: []string{"m.push_rules", "m.direct", "net.maunium.gomuks.preferences"},
},
Presence: gomatrix.FilterPart{
Types: []string{},
diff --git a/ui/message-view.go b/ui/message-view.go
index b6b7ee4..de8e412 100644
--- a/ui/message-view.go
+++ b/ui/message-view.go
@@ -491,7 +491,7 @@ func (view *MessageView) Draw(screen tcell.Screen) {
bareMode := view.parent.parent.bareMessages
if bareMode {
- messageX = 0
+ messageX = x
}
indexOffset := view.getIndexOffset(screen, height, messageX)
diff --git a/ui/ui.go b/ui/ui.go
index 5e06d16..c8acede 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -86,6 +86,14 @@ func (ui *GomuksUI) OnLogout() {
ui.app.SetFocus(ui.loginView)
}
+func (ui *GomuksUI) HandleNewPreferences() {
+ prefs := ui.gmx.Config().Preferences
+ ui.mainView.bareMessages = prefs.BareMessageView
+ ui.mainView.hideUserList = prefs.HideUserList
+ ui.mainView.hideRoomList = prefs.HideRoomList
+ ui.Render()
+}
+
func (ui *GomuksUI) SetView(name View) {
ui.views.SwitchToPage(string(name))
}
diff --git a/ui/view-main.go b/ui/view-main.go
index fd9d606..9f4f247 100644
--- a/ui/view-main.go
+++ b/ui/view-main.go
@@ -57,6 +57,7 @@ type MainView struct {
}
func (ui *GomuksUI) NewMainView() tview.Primitive {
+ prefs := ui.gmx.Config().Preferences
mainView := &MainView{
Flex: tview.NewFlex(),
roomList: NewRoomList(),
@@ -67,6 +68,10 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
gmx: ui.gmx,
config: ui.gmx.Config(),
parent: ui,
+
+ hideUserList: prefs.HideUserList,
+ hideRoomList: prefs.HideRoomList,
+ bareMessages: prefs.BareMessageView,
}
mainView.
@@ -185,6 +190,28 @@ func (view *MainView) HandleCommand(roomView *RoomView, command string, args []s
if err == nil {
view.RemoveRoom(roomView.Room)
}
+ case "/uitoggle":
+ if len(args) == 0 {
+ roomView.AddServiceMessage("Usage: /uitoggle <rooms/users/baremessages>")
+ break
+ }
+ switch args[0] {
+ case "rooms":
+ view.hideRoomList = !view.hideRoomList
+ view.config.Preferences.HideRoomList = view.hideRoomList
+ case "users":
+ view.hideUserList = !view.hideUserList
+ view.config.Preferences.HideUserList = view.hideUserList
+ case "baremessages":
+ view.bareMessages = !view.bareMessages
+ view.config.Preferences.BareMessageView = view.bareMessages
+ default:
+ roomView.AddServiceMessage("Usage: /uitoggle <rooms/users/baremessages>")
+ return
+ }
+ view.parent.Render()
+ view.parent.Render()
+ go view.matrix.SendPreferencesToMatrix()
case "/join":
if len(args) == 0 {
roomView.AddServiceMessage("Usage: /join <room>")