Disconnect UI from main Gomuks struct. Fixes #21
This commit is contained in:
		@@ -29,6 +29,8 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var writer io.Writer
 | 
					var writer io.Writer
 | 
				
			||||||
 | 
					var RecoverPrettyPanic bool
 | 
				
			||||||
 | 
					var OnRecover func()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
@@ -59,6 +61,22 @@ func PrintStack() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Recover recovers a panic, runs the OnRecover handler and either re-panics or
 | 
				
			||||||
 | 
					// shows an user-friendly message about the panic depending on whether or not
 | 
				
			||||||
 | 
					// the pretty panic mode is enabled.
 | 
				
			||||||
 | 
					func Recover() {
 | 
				
			||||||
 | 
						if p := recover(); p != nil {
 | 
				
			||||||
 | 
							if OnRecover != nil {
 | 
				
			||||||
 | 
								OnRecover()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if RecoverPrettyPanic {
 | 
				
			||||||
 | 
								PrettyPanic(p)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								panic(p)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Oops = ` __________
 | 
					const Oops = ` __________
 | 
				
			||||||
< Oh noes! >
 | 
					< Oh noes! >
 | 
				
			||||||
 ‾‾‾\‾‾‾‾‾‾
 | 
					 ‾‾‾\‾‾‾‾‾‾
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										69
									
								
								gomuks.go
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								gomuks.go
									
									
									
									
									
								
							@@ -17,7 +17,6 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -26,44 +25,36 @@ import (
 | 
				
			|||||||
	"maunium.net/go/gomuks/debug"
 | 
						"maunium.net/go/gomuks/debug"
 | 
				
			||||||
	"maunium.net/go/gomuks/interface"
 | 
						"maunium.net/go/gomuks/interface"
 | 
				
			||||||
	"maunium.net/go/gomuks/matrix"
 | 
						"maunium.net/go/gomuks/matrix"
 | 
				
			||||||
	"maunium.net/go/gomuks/ui"
 | 
					 | 
				
			||||||
	"maunium.net/go/tview"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gomuks is the wrapper for everything.
 | 
					// Gomuks is the wrapper for everything.
 | 
				
			||||||
type Gomuks struct {
 | 
					type Gomuks struct {
 | 
				
			||||||
	app       *tview.Application
 | 
						ui     ifc.GomuksUI
 | 
				
			||||||
	ui        *ui.GomuksUI
 | 
						matrix *matrix.Container
 | 
				
			||||||
	matrix    *matrix.Container
 | 
						config *config.Config
 | 
				
			||||||
	debugMode bool
 | 
						stop   chan bool
 | 
				
			||||||
	config    *config.Config
 | 
					 | 
				
			||||||
	stop      chan bool
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewGomuks creates a new Gomuks instance with everything initialized,
 | 
					// NewGomuks creates a new Gomuks instance with everything initialized,
 | 
				
			||||||
// but does not start it.
 | 
					// but does not start it.
 | 
				
			||||||
func NewGomuks(enableDebug bool) *Gomuks {
 | 
					func NewGomuks(uiProvider ifc.UIProvider) *Gomuks {
 | 
				
			||||||
	configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks")
 | 
						configDir := filepath.Join(os.Getenv("HOME"), ".config/gomuks")
 | 
				
			||||||
	gmx := &Gomuks{
 | 
						gmx := &Gomuks{
 | 
				
			||||||
		app:       tview.NewApplication(),
 | 
							stop: make(chan bool, 1),
 | 
				
			||||||
		stop:      make(chan bool, 1),
 | 
					 | 
				
			||||||
		debugMode: enableDebug,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gmx.config = config.NewConfig(configDir)
 | 
						gmx.config = config.NewConfig(configDir)
 | 
				
			||||||
	gmx.ui = ui.NewGomuksUI(gmx)
 | 
						gmx.ui = uiProvider(gmx)
 | 
				
			||||||
	gmx.matrix = matrix.NewContainer(gmx)
 | 
						gmx.matrix = matrix.NewContainer(gmx)
 | 
				
			||||||
 | 
						gmx.ui.Init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						debug.OnRecover = gmx.ui.Finish
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gmx.config.Load()
 | 
						gmx.config.Load()
 | 
				
			||||||
	if len(gmx.config.UserID) > 0 {
 | 
						if len(gmx.config.UserID) > 0 {
 | 
				
			||||||
		_ = gmx.config.LoadSession(gmx.config.UserID)
 | 
							_ = gmx.config.LoadSession(gmx.config.UserID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_ = gmx.matrix.InitClient()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	main := gmx.ui.InitViews()
 | 
					 | 
				
			||||||
	gmx.app.SetRoot(main, true)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return gmx
 | 
						return gmx
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,7 +71,7 @@ func (gmx *Gomuks) Save() {
 | 
				
			|||||||
// StartAutosave calls Save() every minute until it receives a stop signal
 | 
					// StartAutosave calls Save() every minute until it receives a stop signal
 | 
				
			||||||
// on the Gomuks.stop channel.
 | 
					// on the Gomuks.stop channel.
 | 
				
			||||||
func (gmx *Gomuks) StartAutosave() {
 | 
					func (gmx *Gomuks) StartAutosave() {
 | 
				
			||||||
	defer gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
	ticker := time.NewTicker(time.Minute)
 | 
						ticker := time.NewTicker(time.Minute)
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
@@ -100,36 +91,21 @@ func (gmx *Gomuks) Stop() {
 | 
				
			|||||||
	debug.Print("Disconnecting from Matrix...")
 | 
						debug.Print("Disconnecting from Matrix...")
 | 
				
			||||||
	gmx.matrix.Stop()
 | 
						gmx.matrix.Stop()
 | 
				
			||||||
	debug.Print("Cleaning up UI...")
 | 
						debug.Print("Cleaning up UI...")
 | 
				
			||||||
	gmx.app.Stop()
 | 
						gmx.ui.Stop()
 | 
				
			||||||
	gmx.stop <- true
 | 
						gmx.stop <- true
 | 
				
			||||||
	gmx.Save()
 | 
						gmx.Save()
 | 
				
			||||||
	os.Exit(0)
 | 
						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() {
 | 
					 | 
				
			||||||
	if p := recover(); p != nil {
 | 
					 | 
				
			||||||
		if gmx.App().GetScreen() != nil {
 | 
					 | 
				
			||||||
			gmx.App().GetScreen().Fini()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if gmx.debugMode {
 | 
					 | 
				
			||||||
			panic(p)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			debug.PrettyPanic(p)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Start opens a goroutine for the autosave loop and starts the tview app.
 | 
					// 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
 | 
					// If the tview app returns an error, it will be passed into panic(), which
 | 
				
			||||||
// will be recovered as specified in Recover().
 | 
					// will be recovered as specified in Recover().
 | 
				
			||||||
func (gmx *Gomuks) Start() {
 | 
					func (gmx *Gomuks) Start() {
 | 
				
			||||||
	defer gmx.Recover()
 | 
						_ = gmx.matrix.InitClient()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go gmx.StartAutosave()
 | 
						go gmx.StartAutosave()
 | 
				
			||||||
	if err := gmx.app.Run(); err != nil {
 | 
						if err := gmx.ui.Start(); err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -139,11 +115,6 @@ func (gmx *Gomuks) Matrix() ifc.MatrixContainer {
 | 
				
			|||||||
	return gmx.matrix
 | 
						return gmx.matrix
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// App returns the tview Application instance.
 | 
					 | 
				
			||||||
func (gmx *Gomuks) App() *tview.Application {
 | 
					 | 
				
			||||||
	return gmx.app
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Config returns the Gomuks config instance.
 | 
					// Config returns the Gomuks config instance.
 | 
				
			||||||
func (gmx *Gomuks) Config() *config.Config {
 | 
					func (gmx *Gomuks) Config() *config.Config {
 | 
				
			||||||
	return gmx.config
 | 
						return gmx.config
 | 
				
			||||||
@@ -153,13 +124,3 @@ func (gmx *Gomuks) Config() *config.Config {
 | 
				
			|||||||
func (gmx *Gomuks) UI() ifc.GomuksUI {
 | 
					func (gmx *Gomuks) UI() ifc.GomuksUI {
 | 
				
			||||||
	return gmx.ui
 | 
						return gmx.ui
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	enableDebug := len(os.Getenv("DEBUG")) > 0
 | 
					 | 
				
			||||||
	NewGomuks(enableDebug).Start()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// We use os.Exit() everywhere, so exiting by returning from Start() shouldn't happen.
 | 
					 | 
				
			||||||
	time.Sleep(5 * time.Second)
 | 
					 | 
				
			||||||
	fmt.Println("Unexpected exit by return from Gomuks#Start().")
 | 
					 | 
				
			||||||
	os.Exit(2)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,17 +18,14 @@ package ifc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"maunium.net/go/gomuks/config"
 | 
						"maunium.net/go/gomuks/config"
 | 
				
			||||||
	"maunium.net/go/tview"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gomuks is the wrapper for everything.
 | 
					// Gomuks is the wrapper for everything.
 | 
				
			||||||
type Gomuks interface {
 | 
					type Gomuks interface {
 | 
				
			||||||
	Matrix() MatrixContainer
 | 
						Matrix() MatrixContainer
 | 
				
			||||||
	App() *tview.Application
 | 
					 | 
				
			||||||
	UI() GomuksUI
 | 
						UI() GomuksUI
 | 
				
			||||||
	Config() *config.Config
 | 
						Config() *config.Config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Start()
 | 
						Start()
 | 
				
			||||||
	Stop()
 | 
						Stop()
 | 
				
			||||||
	Recover()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,11 +33,18 @@ const (
 | 
				
			|||||||
	ViewMain  View = "main"
 | 
						ViewMain  View = "main"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UIProvider func(gmx Gomuks) GomuksUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type GomuksUI interface {
 | 
					type GomuksUI interface {
 | 
				
			||||||
	Render()
 | 
						Render()
 | 
				
			||||||
	SetView(name View)
 | 
						SetView(name View)
 | 
				
			||||||
	MainView() MainView
 | 
						MainView() MainView
 | 
				
			||||||
	LoginView() LoginView
 | 
						LoginView() LoginView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Init()
 | 
				
			||||||
 | 
						Start() error
 | 
				
			||||||
 | 
						Stop()
 | 
				
			||||||
 | 
						Finish()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MainView interface {
 | 
					type MainView interface {
 | 
				
			||||||
@@ -50,8 +57,7 @@ type MainView interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	SetTyping(roomID string, users []string)
 | 
						SetTyping(roomID string, users []string)
 | 
				
			||||||
	ParseEvent(roomView RoomView, evt *gomatrix.Event) Message
 | 
						ParseEvent(roomView RoomView, evt *gomatrix.Event) Message
 | 
				
			||||||
	//ProcessMessageEvent(roomView RoomView, evt *gomatrix.Event) Message
 | 
					
 | 
				
			||||||
	//ProcessMembershipEvent(roomView RoomView, evt *gomatrix.Event) Message
 | 
					 | 
				
			||||||
	NotifyMessage(room *rooms.Room, message Message, should pushrules.PushActionArrayShould)
 | 
						NotifyMessage(room *rooms.Room, message Message, should pushrules.PushActionArrayShould)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,7 +75,7 @@ const (
 | 
				
			|||||||
type RoomView interface {
 | 
					type RoomView interface {
 | 
				
			||||||
	MxRoom() *rooms.Room
 | 
						MxRoom() *rooms.Room
 | 
				
			||||||
	SaveHistory(dir string) error
 | 
						SaveHistory(dir string) error
 | 
				
			||||||
	LoadHistory(gmx Gomuks, dir string) (int, error)
 | 
						LoadHistory(matrix MatrixContainer, dir string) (int, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SetStatus(status string)
 | 
						SetStatus(status string)
 | 
				
			||||||
	SetTyping(users []string)
 | 
						SetTyping(users []string)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					// gomuks - A terminal Matrix client written in Go.
 | 
				
			||||||
 | 
					// Copyright (C) 2018 Tulir Asokan
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"maunium.net/go/gomuks/debug"
 | 
				
			||||||
 | 
						"maunium.net/go/gomuks/interface"
 | 
				
			||||||
 | 
						"maunium.net/go/gomuks/ui"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var MainUIProvider ifc.UIProvider = ui.NewGomuksUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						defer debug.Recover()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enableDebug := len(os.Getenv("DEBUG")) > 0
 | 
				
			||||||
 | 
						debug.RecoverPrettyPanic = !enableDebug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gmx := NewGomuks(MainUIProvider)
 | 
				
			||||||
 | 
						gmx.Start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We use os.Exit() everywhere, so exiting by returning from Start() shouldn't happen.
 | 
				
			||||||
 | 
						time.Sleep(5 * time.Second)
 | 
				
			||||||
 | 
						fmt.Println("Unexpected exit by return from gmx.Start().")
 | 
				
			||||||
 | 
						os.Exit(2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -196,7 +196,7 @@ func (c *Container) OnLogin() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Start moves the UI to the main view, calls OnLogin() and runs the syncer forever until stopped with Stop()
 | 
					// Start moves the UI to the main view, calls OnLogin() and runs the syncer forever until stopped with Stop()
 | 
				
			||||||
func (c *Container) Start() {
 | 
					func (c *Container) Start() {
 | 
				
			||||||
	defer c.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.ui.SetView(ifc.ViewMain)
 | 
						c.ui.SetView(ifc.ViewMain)
 | 
				
			||||||
	c.OnLogin()
 | 
						c.OnLogin()
 | 
				
			||||||
@@ -317,7 +317,7 @@ func (c *Container) HandleTyping(evt *gomatrix.Event) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendMessage sends a message with the given text to the given room.
 | 
					// SendMessage sends a message with the given text to the given room.
 | 
				
			||||||
func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) {
 | 
					func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) {
 | 
				
			||||||
	defer c.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
	c.SendTyping(roomID, false)
 | 
						c.SendTyping(roomID, false)
 | 
				
			||||||
	resp, err := c.client.SendMessageEvent(roomID, "m.room.message",
 | 
						resp, err := c.client.SendMessageEvent(roomID, "m.room.message",
 | 
				
			||||||
		gomatrix.TextMessage{MsgType: msgtype, Body: text})
 | 
							gomatrix.TextMessage{MsgType: msgtype, Body: text})
 | 
				
			||||||
@@ -328,7 +328,7 @@ func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, error) {
 | 
					func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, error) {
 | 
				
			||||||
	defer c.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	html := string(blackfriday.Run([]byte(text)))
 | 
						html := string(blackfriday.Run([]byte(text)))
 | 
				
			||||||
	if html == text {
 | 
						if html == text {
 | 
				
			||||||
@@ -351,7 +351,7 @@ func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, e
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendTyping sets whether or not the user is typing in the given room.
 | 
					// SendTyping sets whether or not the user is typing in the given room.
 | 
				
			||||||
func (c *Container) SendTyping(roomID string, typing bool) {
 | 
					func (c *Container) SendTyping(roomID string, typing bool) {
 | 
				
			||||||
	defer c.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
	ts := time.Now().Unix()
 | 
						ts := time.Now().Unix()
 | 
				
			||||||
	if c.typing > ts && typing {
 | 
						if c.typing > ts && typing {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,7 +95,7 @@ func (view *MessageView) SaveHistory(path string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *MessageView) LoadHistory(gmx ifc.Gomuks, path string) (int, error) {
 | 
					func (view *MessageView) LoadHistory(matrix ifc.MatrixContainer, path string) (int, error) {
 | 
				
			||||||
	file, err := os.OpenFile(path, os.O_RDONLY, 0600)
 | 
						file, err := os.OpenFile(path, os.O_RDONLY, 0600)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if os.IsNotExist(err) {
 | 
							if os.IsNotExist(err) {
 | 
				
			||||||
@@ -119,7 +119,7 @@ func (view *MessageView) LoadHistory(gmx ifc.Gomuks, path string) (int, error) {
 | 
				
			|||||||
		if message != nil {
 | 
							if message != nil {
 | 
				
			||||||
			view.messages[index-indexOffset] = message
 | 
								view.messages[index-indexOffset] = message
 | 
				
			||||||
			view.updateWidestSender(message.Sender())
 | 
								view.updateWidestSender(message.Sender())
 | 
				
			||||||
			message.RegisterGomuks(gmx)
 | 
								message.RegisterMatrix(matrix)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			indexOffset++
 | 
								indexOffset++
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@ func newBaseMessage(id, sender, displayname, msgtype string, timestamp time.Time
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *BaseMessage) RegisterGomuks(gmx ifc.Gomuks) {}
 | 
					func (msg *BaseMessage) RegisterMatrix(matrix ifc.MatrixContainer) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Sender gets the string that should be displayed as the sender of this message.
 | 
					// Sender gets the string that should be displayed as the sender of this message.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,27 +41,26 @@ type ImageMessage struct {
 | 
				
			|||||||
	FileID     string
 | 
						FileID     string
 | 
				
			||||||
	data       []byte
 | 
						data       []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gmx ifc.Gomuks
 | 
						matrix ifc.MatrixContainer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewImageMessage creates a new ImageMessage object with the provided values and the default state.
 | 
					// NewImageMessage creates a new ImageMessage object with the provided values and the default state.
 | 
				
			||||||
func NewImageMessage(gmx ifc.Gomuks, id, sender, displayname, msgtype, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
 | 
					func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname, msgtype, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
 | 
				
			||||||
	return &ImageMessage{
 | 
						return &ImageMessage{
 | 
				
			||||||
		newBaseMessage(id, sender, displayname, msgtype, timestamp),
 | 
							newBaseMessage(id, sender, displayname, msgtype, timestamp),
 | 
				
			||||||
		homeserver,
 | 
							homeserver,
 | 
				
			||||||
		fileID,
 | 
							fileID,
 | 
				
			||||||
		data,
 | 
							data,
 | 
				
			||||||
		gmx,
 | 
							matrix,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *ImageMessage) RegisterGomuks(gmx ifc.Gomuks) {
 | 
					func (msg *ImageMessage) RegisterMatrix(matrix ifc.MatrixContainer) {
 | 
				
			||||||
	msg.gmx = gmx
 | 
						msg.matrix = matrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	debug.Print(len(msg.data), msg.data)
 | 
					 | 
				
			||||||
	if len(msg.data) == 0 {
 | 
						if len(msg.data) == 0 {
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			defer gmx.Recover()
 | 
								defer debug.Recover()
 | 
				
			||||||
			msg.updateData()
 | 
								msg.updateData()
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -73,7 +72,7 @@ func (msg *ImageMessage) NotificationContent() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (msg *ImageMessage) updateData() {
 | 
					func (msg *ImageMessage) updateData() {
 | 
				
			||||||
	debug.Print("Loading image:", msg.Homeserver, msg.FileID)
 | 
						debug.Print("Loading image:", msg.Homeserver, msg.FileID)
 | 
				
			||||||
	data, _, _, err := msg.gmx.Matrix().Download(fmt.Sprintf("mxc://%s/%s", msg.Homeserver, msg.FileID))
 | 
						data, _, _, err := msg.matrix.Download(fmt.Sprintf("mxc://%s/%s", msg.Homeserver, msg.FileID))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		debug.Print("Failed to download image %s/%s: %v", msg.Homeserver, msg.FileID, err)
 | 
							debug.Print("Failed to download image %s/%s: %v", msg.Homeserver, msg.FileID, err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -82,7 +81,7 @@ func (msg *ImageMessage) updateData() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *ImageMessage) Path() string {
 | 
					func (msg *ImageMessage) Path() string {
 | 
				
			||||||
	return msg.gmx.Matrix().GetCachePath(msg.Homeserver, msg.FileID)
 | 
						return msg.matrix.GetCachePath(msg.Homeserver, msg.FileID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CalculateBuffer generates the internal buffer for this message that consists
 | 
					// CalculateBuffer generates the internal buffer for this message that consists
 | 
				
			||||||
@@ -108,4 +107,3 @@ func (msg *ImageMessage) CalculateBuffer(width int) {
 | 
				
			|||||||
func (msg *ImageMessage) RecalculateBuffer() {
 | 
					func (msg *ImageMessage) RecalculateBuffer() {
 | 
				
			||||||
	msg.CalculateBuffer(msg.prevBufferWidth)
 | 
						msg.CalculateBuffer(msg.prevBufferWidth)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,7 @@ type UIMessage interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	SenderID() string
 | 
						SenderID() string
 | 
				
			||||||
	RealSender() string
 | 
						RealSender() string
 | 
				
			||||||
	RegisterGomuks(gmx ifc.Gomuks)
 | 
						RegisterMatrix(matrix ifc.MatrixContainer)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DateFormat = "January _2, 2006"
 | 
					const DateFormat = "January _2, 2006"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,10 +30,10 @@ import (
 | 
				
			|||||||
	"maunium.net/go/tcell"
 | 
						"maunium.net/go/tcell"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseEvent(gmx ifc.Gomuks, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage {
 | 
					func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage {
 | 
				
			||||||
	switch evt.Type {
 | 
						switch evt.Type {
 | 
				
			||||||
	case "m.room.message":
 | 
						case "m.room.message":
 | 
				
			||||||
		return ParseMessage(gmx, room, evt)
 | 
							return ParseMessage(matrix, room, evt)
 | 
				
			||||||
	case "m.room.member":
 | 
						case "m.room.member":
 | 
				
			||||||
		return ParseMembershipEvent(room, evt)
 | 
							return ParseMembershipEvent(room, evt)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -48,7 +48,7 @@ func unixToTime(unix int64) time.Time {
 | 
				
			|||||||
	return timestamp
 | 
						return timestamp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseMessage(gmx ifc.Gomuks, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage {
 | 
					func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage {
 | 
				
			||||||
	displayname := evt.Sender
 | 
						displayname := evt.Sender
 | 
				
			||||||
	member := room.GetMember(evt.Sender)
 | 
						member := room.GetMember(evt.Sender)
 | 
				
			||||||
	if member != nil {
 | 
						if member != nil {
 | 
				
			||||||
@@ -68,11 +68,11 @@ func ParseMessage(gmx ifc.Gomuks, room *rooms.Room, evt *gomatrix.Event) message
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	case "m.image":
 | 
						case "m.image":
 | 
				
			||||||
		url, _ := evt.Content["url"].(string)
 | 
							url, _ := evt.Content["url"].(string)
 | 
				
			||||||
		data, hs, id, err := gmx.Matrix().Download(url)
 | 
							data, hs, id, err := matrix.Download(url)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			debug.Printf("Failed to download %s: %v", url, err)
 | 
								debug.Printf("Failed to download %s: %v", url, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return messages.NewImageMessage(gmx, evt.ID, evt.Sender, displayname, msgtype, hs, id, data, ts)
 | 
							return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, msgtype, hs, id, data, ts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,8 +81,8 @@ func (view *RoomView) SaveHistory(dir string) error {
 | 
				
			|||||||
	return view.MessageView().SaveHistory(view.logPath(dir))
 | 
						return view.MessageView().SaveHistory(view.logPath(dir))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *RoomView) LoadHistory(gmx ifc.Gomuks, dir string) (int, error) {
 | 
					func (view *RoomView) LoadHistory(matrix ifc.MatrixContainer, dir string) (int, error) {
 | 
				
			||||||
	return view.MessageView().LoadHistory(gmx, view.logPath(dir))
 | 
						return view.MessageView().LoadHistory(matrix, view.logPath(dir))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *RoomView) SetTabCompleteFunc(fn func(room *RoomView, text string, cursorOffset int) string) *RoomView {
 | 
					func (view *RoomView) SetTabCompleteFunc(fn func(room *RoomView, text string, cursorOffset int) string) *RoomView {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								ui/ui.go
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								ui/ui.go
									
									
									
									
									
								
							@@ -36,14 +36,32 @@ func init() {
 | 
				
			|||||||
	tview.Styles.ContrastBackgroundColor = tcell.ColorDarkGreen
 | 
						tview.Styles.ContrastBackgroundColor = tcell.ColorDarkGreen
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewGomuksUI(gmx ifc.Gomuks) (ui *GomuksUI) {
 | 
					func NewGomuksUI(gmx ifc.Gomuks) ifc.GomuksUI {
 | 
				
			||||||
	ui = &GomuksUI{
 | 
						ui := &GomuksUI{
 | 
				
			||||||
		gmx:   gmx,
 | 
							gmx:   gmx,
 | 
				
			||||||
		app:   gmx.App(),
 | 
							app:   tview.NewApplication(),
 | 
				
			||||||
		views: tview.NewPages(),
 | 
							views: tview.NewPages(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ui.views.SetChangedFunc(ui.Render)
 | 
						ui.views.SetChangedFunc(ui.Render)
 | 
				
			||||||
	return
 | 
						return ui
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ui *GomuksUI) Init() {
 | 
				
			||||||
 | 
						ui.app.SetRoot(ui.InitViews(), true)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ui *GomuksUI) Start() error {
 | 
				
			||||||
 | 
						return ui.app.Run()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ui *GomuksUI) Stop() {
 | 
				
			||||||
 | 
						ui.app.Stop()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ui *GomuksUI) Finish() {
 | 
				
			||||||
 | 
						if ui.app.GetScreen() != nil {
 | 
				
			||||||
 | 
							ui.app.GetScreen().Fini()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ui *GomuksUI) Render() {
 | 
					func (ui *GomuksUI) Render() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,7 +143,7 @@ func (view *MainView) SendMessage(roomView *RoomView, text string) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *MainView) sendTempMessage(roomView *RoomView, tempMessage ifc.Message, text string) {
 | 
					func (view *MainView) sendTempMessage(roomView *RoomView, tempMessage ifc.Message, text string) {
 | 
				
			||||||
	defer view.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
	eventID, err := view.matrix.SendMarkdownMessage(roomView.Room.ID, tempMessage.Type(), text)
 | 
						eventID, err := view.matrix.SendMarkdownMessage(roomView.Room.ID, tempMessage.Type(), text)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		tempMessage.SetState(ifc.MessageStateFailed)
 | 
							tempMessage.SetState(ifc.MessageStateFailed)
 | 
				
			||||||
@@ -154,7 +154,7 @@ func (view *MainView) sendTempMessage(roomView *RoomView, tempMessage ifc.Messag
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *MainView) HandleCommand(roomView *RoomView, command string, args []string) {
 | 
					func (view *MainView) HandleCommand(roomView *RoomView, command string, args []string) {
 | 
				
			||||||
	defer view.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
	debug.Print("Handling command", command, args)
 | 
						debug.Print("Handling command", command, args)
 | 
				
			||||||
	switch command {
 | 
						switch command {
 | 
				
			||||||
	case "/me":
 | 
						case "/me":
 | 
				
			||||||
@@ -286,7 +286,7 @@ func (view *MainView) SwitchRoom(roomIndex int) {
 | 
				
			|||||||
		roomView.Room.MarkRead()
 | 
							roomView.Room.MarkRead()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	view.roomList.SetSelected(roomView.Room)
 | 
						view.roomList.SetSelected(roomView.Room)
 | 
				
			||||||
	view.gmx.App().SetFocus(view)
 | 
						view.parent.app.SetFocus(view)
 | 
				
			||||||
	view.parent.Render()
 | 
						view.parent.Render()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -321,7 +321,7 @@ func (view *MainView) addRoom(index int, room string) {
 | 
				
			|||||||
		view.roomView.AddPage(room, roomView, true, false)
 | 
							view.roomView.AddPage(room, roomView, true, false)
 | 
				
			||||||
		roomView.UpdateUserList()
 | 
							roomView.UpdateUserList()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		count, err := roomView.LoadHistory(view.gmx, view.config.HistoryDir)
 | 
							count, err := roomView.LoadHistory(view.matrix, view.config.HistoryDir)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			debug.Printf("Failed to load history of %s: %v", roomView.Room.GetTitle(), err)
 | 
								debug.Printf("Failed to load history of %s: %v", roomView.Room.GetTitle(), err)
 | 
				
			||||||
		} else if count <= 0 {
 | 
							} else if count <= 0 {
 | 
				
			||||||
@@ -424,7 +424,7 @@ func (view *MainView) NotifyMessage(room *rooms.Room, message ifc.Message, shoul
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *MainView) LoadHistory(room string, initial bool) {
 | 
					func (view *MainView) LoadHistory(room string, initial bool) {
 | 
				
			||||||
	defer view.gmx.Recover()
 | 
						defer debug.Recover()
 | 
				
			||||||
	roomView := view.rooms[room]
 | 
						roomView := view.rooms[room]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	batch := roomView.Room.PrevBatch
 | 
						batch := roomView.Room.PrevBatch
 | 
				
			||||||
@@ -472,5 +472,5 @@ func (view *MainView) LoadHistory(room string, initial bool) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *MainView) ParseEvent(roomView ifc.RoomView, evt *gomatrix.Event) ifc.Message {
 | 
					func (view *MainView) ParseEvent(roomView ifc.RoomView, evt *gomatrix.Event) ifc.Message {
 | 
				
			||||||
	return parser.ParseEvent(view.gmx, roomView.MxRoom(), evt)
 | 
						return parser.ParseEvent(view.matrix, roomView.MxRoom(), evt)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,6 @@ import (
 | 
				
			|||||||
	"hash/fnv"
 | 
						"hash/fnv"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"maunium.net/go/gomuks/debug"
 | 
					 | 
				
			||||||
	"maunium.net/go/tcell"
 | 
						"maunium.net/go/tcell"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,7 +51,6 @@ func init() {
 | 
				
			|||||||
//  <-- = red
 | 
					//  <-- = red
 | 
				
			||||||
//  --- = yellow
 | 
					//  --- = yellow
 | 
				
			||||||
func GetHashColorName(s string) string {
 | 
					func GetHashColorName(s string) string {
 | 
				
			||||||
	debug.Print("Getting color for", s)
 | 
					 | 
				
			||||||
	switch s {
 | 
						switch s {
 | 
				
			||||||
	case "-->":
 | 
						case "-->":
 | 
				
			||||||
		return "green"
 | 
							return "green"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user