Documentation and refactoring

This commit is contained in:
Tulir Asokan 2018-03-23 14:44:36 +02:00
parent 7cc55ade30
commit 03e9a0d5ac
9 changed files with 58 additions and 27 deletions

View File

@ -22,7 +22,6 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/config" "maunium.net/go/gomuks/config"
"maunium.net/go/gomuks/interface" "maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/matrix" "maunium.net/go/gomuks/matrix"
@ -31,6 +30,7 @@ import (
"maunium.net/go/tview" "maunium.net/go/tview"
) )
// Gomuks is the wrapper for everything.
type Gomuks struct { type Gomuks struct {
app *tview.Application app *tview.Application
ui *ui.GomuksUI ui *ui.GomuksUI
@ -41,6 +41,8 @@ type Gomuks struct {
stop chan bool stop chan bool
} }
// NewGomuks creates a new Gomuks instance with everything initialized,
// but does not start it.
func NewGomuks(enableDebug bool) *Gomuks { func NewGomuks(enableDebug bool) *Gomuks {
configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks") configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks")
gmx := &Gomuks{ gmx := &Gomuks{
@ -76,16 +78,7 @@ func NewGomuks(enableDebug bool) *Gomuks {
return gmx return gmx
} }
func (gmx *Gomuks) Stop() { // Save saves the active session and message history.
gmx.debug.Print("Disconnecting from Matrix...")
gmx.matrix.Stop()
gmx.debug.Print("Cleaning up UI...")
gmx.app.Stop()
gmx.stop <- true
gmx.Save()
os.Exit(0)
}
func (gmx *Gomuks) Save() { func (gmx *Gomuks) Save() {
if gmx.config.Session != nil { if gmx.config.Session != nil {
gmx.debug.Print("Saving session...") gmx.debug.Print("Saving session...")
@ -95,6 +88,8 @@ func (gmx *Gomuks) Save() {
gmx.ui.MainView().SaveAllHistory() gmx.ui.MainView().SaveAllHistory()
} }
// StartAutosave calls Save() every minute until it receives a stop signal
// on the Gomuks.stop channel.
func (gmx *Gomuks) StartAutosave() { func (gmx *Gomuks) StartAutosave() {
defer gmx.Recover() defer gmx.Recover()
ticker := time.NewTicker(time.Minute) ticker := time.NewTicker(time.Minute)
@ -110,6 +105,21 @@ func (gmx *Gomuks) StartAutosave() {
} }
} }
// Stop stops the Matrix syncer, the tview app and the autosave goroutine,
// then saves everything and calls os.Exit(0).
func (gmx *Gomuks) Stop() {
gmx.debug.Print("Disconnecting from Matrix...")
gmx.matrix.Stop()
gmx.debug.Print("Cleaning up UI...")
gmx.app.Stop()
gmx.stop <- true
gmx.Save()
os.Exit(0)
}
// Recover recovers a panic, closes the tcell screen and either re-panics or
// shows an user-friendly message about the panic depending on whether or not
// the debug mode is enabled.
func (gmx *Gomuks) Recover() { func (gmx *Gomuks) Recover() {
if p := recover(); p != nil { if p := recover(); p != nil {
if gmx.App().GetScreen() != nil { if gmx.App().GetScreen() != nil {
@ -123,6 +133,10 @@ func (gmx *Gomuks) Recover() {
} }
} }
// Start opens a goroutine for the autosave loop and starts the tview app.
//
// If the tview app returns an error, it will be passed into panic(), which
// will be recovered as specified in Recover().
func (gmx *Gomuks) Start() { func (gmx *Gomuks) Start() {
defer gmx.Recover() defer gmx.Recover()
go gmx.StartAutosave() go gmx.StartAutosave()
@ -131,22 +145,22 @@ func (gmx *Gomuks) Start() {
} }
} }
func (gmx *Gomuks) Matrix() *gomatrix.Client { // Matrix returns the MatrixContainer instance.
return gmx.matrix.Client() func (gmx *Gomuks) Matrix() ifc.MatrixContainer {
}
func (gmx *Gomuks) MatrixContainer() ifc.MatrixContainer {
return gmx.matrix return gmx.matrix
} }
// App returns the tview Application instance.
func (gmx *Gomuks) App() *tview.Application { func (gmx *Gomuks) App() *tview.Application {
return gmx.app return gmx.app
} }
// Config returns the Gomuks config instance.
func (gmx *Gomuks) Config() *config.Config { func (gmx *Gomuks) Config() *config.Config {
return gmx.config return gmx.config
} }
// UI returns the Gomuks UI instance.
func (gmx *Gomuks) UI() ifc.GomuksUI { func (gmx *Gomuks) UI() ifc.GomuksUI {
return gmx.ui return gmx.ui
} }

View File

@ -17,14 +17,13 @@
package ifc package ifc
import ( import (
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/config" "maunium.net/go/gomuks/config"
"maunium.net/go/tview" "maunium.net/go/tview"
) )
// Gomuks is the wrapper for everything.
type Gomuks interface { type Gomuks interface {
Matrix() *gomatrix.Client Matrix() MatrixContainer
MatrixContainer() MatrixContainer
App() *tview.Application App() *tview.Application
UI() GomuksUI UI() GomuksUI
Config() *config.Config Config() *config.Config

View File

@ -263,9 +263,10 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
if membership == prevMembership { if membership == prevMembership {
return return
} }
if membership == "join" { switch membership {
case "join":
c.ui.MainView().AddRoom(evt.RoomID) c.ui.MainView().AddRoom(evt.RoomID)
} else if membership == "leave" { case "leave":
c.ui.MainView().RemoveRoom(evt.RoomID) c.ui.MainView().RemoveRoom(evt.RoomID)
} }
} }

View File

@ -39,6 +39,14 @@ type rawPushRuleset struct {
Underride PushRuleArray `json:"underride"` Underride PushRuleArray `json:"underride"`
} }
// UnmarshalJSON parses JSON into this PushRuleset.
//
// For override, sender and underride push rule arrays, the type is added
// to each PushRule and the array is used as-is.
//
// For room and sender push rule arrays, the type is added to each PushRule
// and the array is converted to a map with the rule ID as the key and the
// PushRule as the value.
func (rs *PushRuleset) UnmarshalJSON(raw []byte) (err error) { func (rs *PushRuleset) UnmarshalJSON(raw []byte) (err error) {
data := rawPushRuleset{} data := rawPushRuleset{}
err = json.Unmarshal(raw, &data) err = json.Unmarshal(raw, &data)
@ -54,6 +62,7 @@ func (rs *PushRuleset) UnmarshalJSON(raw []byte) (err error) {
return return
} }
// MarshalJSON is the reverse of UnmarshalJSON()
func (rs *PushRuleset) MarshalJSON() ([]byte, error) { func (rs *PushRuleset) MarshalJSON() ([]byte, error) {
data := rawPushRuleset{ data := rawPushRuleset{
Override: rs.Override, Override: rs.Override,

View File

@ -20,6 +20,7 @@ import (
"maunium.net/go/gomatrix" "maunium.net/go/gomatrix"
) )
// Membership is an enum specifying the membership state of a room member.
type Membership string type Membership string
// The allowed membership states as specified in spec section 10.5.5. // The allowed membership states as specified in spec section 10.5.5.

View File

@ -34,17 +34,22 @@ type Room struct {
SessionUserID string SessionUserID string
// MXID -> Member cache calculated from membership events. // MXID -> Member cache calculated from membership events.
memberCache map[string]*Member memberCache map[string]*Member
// The first non-SessionUserID member in the room. Calculated at the same time as memberCache. // The first non-SessionUserID member in the room. Calculated at
// the same time as memberCache.
firstMemberCache string firstMemberCache string
// The name of the room. Calculated from the state event name, canonical_alias or alias or the member cache. // The name of the room. Calculated from the state event name,
// canonical_alias or alias or the member cache.
nameCache string nameCache string
// The topic of the room. Directly fetched from the m.room.topic state event. // The topic of the room. Directly fetched from the m.room.topic state event.
topicCache string topicCache string
// fetchHistoryLock is used to make sure multiple goroutines don't fetch history for this room at the same time. // fetchHistoryLock is used to make sure multiple goroutines don't fetch
// history for this room at the same time.
fetchHistoryLock *sync.Mutex fetchHistoryLock *sync.Mutex
} }
// LockHistory locks the history fetching mutex.
// If the mutex is nil, it will be created.
func (room *Room) LockHistory() { func (room *Room) LockHistory() {
if room.fetchHistoryLock == nil { if room.fetchHistoryLock == nil {
room.fetchHistoryLock = &sync.Mutex{} room.fetchHistoryLock = &sync.Mutex{}
@ -52,6 +57,8 @@ func (room *Room) LockHistory() {
room.fetchHistoryLock.Lock() room.fetchHistoryLock.Lock()
} }
// UnlockHistory unlocks the history fetching mutex.
// If the mutex is nil, this does nothing.
func (room *Room) UnlockHistory() { func (room *Room) UnlockHistory() {
if room.fetchHistoryLock != nil { if room.fetchHistoryLock != nil {
room.fetchHistoryLock.Unlock() room.fetchHistoryLock.Unlock()

View File

@ -49,7 +49,7 @@ func (s *GomuksSyncer) ProcessResponse(res *gomatrix.RespSync, since string) (er
if len(since) == 0 { if len(since) == 0 {
return return
} }
// gdebug.Print("Processing sync response", since, res) // debug.Print("Processing sync response", since, res)
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {

View File

@ -44,7 +44,7 @@ func (ui *GomuksUI) NewLoginView() tview.Primitive {
username: widget.NewAdvancedInputField(), username: widget.NewAdvancedInputField(),
password: widget.NewAdvancedInputField(), password: widget.NewAdvancedInputField(),
matrix: ui.gmx.MatrixContainer(), matrix: ui.gmx.Matrix(),
config: ui.gmx.Config(), config: ui.gmx.Config(),
parent: ui, parent: ui,
} }

View File

@ -56,7 +56,7 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
roomView: tview.NewPages(), roomView: tview.NewPages(),
rooms: make(map[string]*widget.RoomView), rooms: make(map[string]*widget.RoomView),
matrix: ui.gmx.MatrixContainer(), matrix: ui.gmx.Matrix(),
gmx: ui.gmx, gmx: ui.gmx,
config: ui.gmx.Config(), config: ui.gmx.Config(),
parent: ui, parent: ui,