aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gomuks.go11
-rw-r--r--matrix.go55
-rw-r--r--session.go7
-rw-r--r--view-main.go82
4 files changed, 137 insertions, 18 deletions
diff --git a/gomuks.go b/gomuks.go
index 6af5997..e87da59 100644
--- a/gomuks.go
+++ b/gomuks.go
@@ -31,6 +31,9 @@ type Gomuks interface {
App() *tview.Application
UI() *GomuksUI
Config() *Config
+
+ Start()
+ Stop()
}
type gomuks struct {
@@ -68,6 +71,14 @@ func NewGomuks(debug bool) *gomuks {
return gmx
}
+func (gmx *gomuks) Stop() {
+ gmx.matrix.Stop()
+ gmx.app.Stop()
+ if gmx.config.Session != nil {
+ gmx.config.Session.Save()
+ }
+}
+
func (gmx *gomuks) Start() {
if err := gmx.app.Run(); err != nil {
panic(err)
diff --git a/matrix.go b/matrix.go
index 17147be..2639af7 100644
--- a/matrix.go
+++ b/matrix.go
@@ -18,6 +18,7 @@ package main
import (
"fmt"
+ "time"
"github.com/matrix-org/gomatrix"
)
@@ -30,6 +31,8 @@ type MatrixContainer struct {
config *Config
running bool
stop chan bool
+
+ typing int64
}
func NewMatrixContainer(gmx Gomuks) *MatrixContainer {
@@ -123,6 +126,7 @@ func (c *MatrixContainer) Start() {
syncer := c.client.Syncer.(*gomatrix.DefaultSyncer)
syncer.OnEventType("m.room.message", c.HandleMessage)
+ syncer.OnEventType("m.typing", c.HandleTyping)
for {
select {
@@ -145,6 +149,57 @@ func (c *MatrixContainer) HandleMessage(evt *gomatrix.Event) {
c.ui.Append(evt.RoomID, evt.Sender, message)
}
+func (c *MatrixContainer) HandleTyping(evt *gomatrix.Event) {
+ users := evt.Content["user_ids"].([]string)
+ c.debug.Print(users, "are typing")
+ c.ui.SetTyping(evt.RoomID, users)
+}
+
func (c *MatrixContainer) SendMessage(roomID, message string) {
+ c.client.UserTyping(roomID, false, 0)
c.client.SendText(roomID, message)
}
+
+func (c *MatrixContainer) SendTyping(roomID string) {
+ time := time.Now().Unix()
+ if c.typing > time {
+ return
+ }
+
+ c.client.UserTyping(roomID, true, 5000)
+ c.typing = time + 5000
+}
+
+func (c *MatrixContainer) GetStateEvent(roomID, eventType, stateKey string) *gomatrix.Event {
+ content := make(map[string]interface{})
+ c.client.StateEvent(roomID, eventType, stateKey, &content)
+ if len(content) == 0 {
+ return nil
+ }
+ return &gomatrix.Event{
+ StateKey: &stateKey,
+ Sender: "",
+ Type: eventType,
+ Timestamp: 0,
+ ID: "",
+ RoomID: roomID,
+ Content: content,
+ }
+}
+
+func (c *MatrixContainer) GetAndUpdateStateEvent(room *gomatrix.Room, eventType, stateKey string) {
+ if room == nil {
+ return
+ }
+ event := c.GetStateEvent(room.ID, eventType, stateKey)
+ if event != nil {
+ room.UpdateState(event)
+ }
+}
+
+func (c *MatrixContainer) UpdateRoomInfo(roomID string) {
+ room := c.client.Store.LoadRoom(roomID)
+ c.GetAndUpdateStateEvent(room, "m.room.name", "")
+ c.GetAndUpdateStateEvent(room, "m.room.canonical_alias", "")
+ c.GetAndUpdateStateEvent(room, "m.room.topic", "")
+}
diff --git a/session.go b/session.go
index 77e4bfa..217ea38 100644
--- a/session.go
+++ b/session.go
@@ -86,7 +86,12 @@ func (s *Session) LoadNextBatch(_ string) string {
}
func (s *Session) LoadRoom(mxid string) *gomatrix.Room {
- return s.Rooms[mxid]
+ room, ok := s.Rooms[mxid]
+ if !ok || room == nil {
+ room := gomatrix.NewRoom(mxid)
+ s.SaveRoom(room)
+ }
+ return room
}
func (s *Session) SaveFilterID(_, filterID string) {
diff --git a/view-main.go b/view-main.go
index d36160e..131e872 100644
--- a/view-main.go
+++ b/view-main.go
@@ -21,32 +21,47 @@ import (
"strings"
"github.com/gdamore/tcell"
+ "github.com/matrix-org/gomatrix"
"maunium.net/go/tview"
)
type RoomView struct {
- *tview.TextView
+ *tview.Grid
+ content *tview.TextView
+ status *tview.TextView
+ name, topic string
}
-func NewRoomView() *RoomView {
+func NewRoomView(name, topic string) *RoomView {
view := &RoomView{
+ tview.NewGrid(),
tview.NewTextView(),
+ tview.NewTextView(),
+ name, topic,
}
+ view.content.SetTitle(topic).SetBorder(true)
+ view.status.SetText("Waiting for status data...")
+ view.SetColumns(0).SetRows(0, 1)
+ view.AddItem(view.content, 0, 0, 1, 1, 0, 0, false)
+ view.AddItem(view.status, 1, 0, 1, 1, 0, 0, false)
return view
}
func (ui *GomuksUI) MakeMainUI() tview.Primitive {
- ui.mainView = tview.NewGrid().SetColumns(40, 0).SetRows(0, 2)
+ ui.mainView = tview.NewGrid().SetColumns(30, 0).SetRows(0, 1)
ui.mainViewRoomList = tview.NewList().ShowSecondaryText(false)
- ui.mainViewRoomList.SetBorderPadding(1, 1, 1, 1)
- ui.mainView.AddItem(ui.mainViewRoomList, 0, 0, 2, 1, 2, 2, false)
+ ui.mainViewRoomList.SetBorder(true).SetTitle("Rooms")
+ ui.mainView.AddItem(ui.mainViewRoomList, 0, 0, 2, 1, 0, 0, false)
ui.mainViewRoomView = tview.NewPages()
ui.mainViewRoomView.SetChangedFunc(ui.Render)
- ui.mainView.AddItem(ui.mainViewRoomView, 0, 1, 1, 1, 2, 2, false)
+ ui.mainView.AddItem(ui.mainViewRoomView, 0, 1, 1, 1, 0, 0, false)
ui.mainViewInput = tview.NewInputField()
+ ui.mainViewInput.SetChangedFunc(func(_ string) {
+ ui.matrix.SendTyping(ui.currentRoom())
+ })
ui.mainViewInput.SetDoneFunc(func(key tcell.Key) {
if key == tcell.KeyEnter {
room, text := ui.currentRoom(), ui.mainViewInput.GetText()
@@ -63,7 +78,7 @@ func (ui *GomuksUI) MakeMainUI() tview.Primitive {
ui.mainViewInput.SetText("")
}
})
- ui.mainView.AddItem(ui.mainViewInput, 1, 1, 1, 1, 2, 2, true)
+ ui.mainView.AddItem(ui.mainViewInput, 1, 1, 1, 1, 0, 0, true)
ui.debug.Print(ui.mainViewInput.SetInputCapture(ui.MainUIKeyHandler))
@@ -73,14 +88,20 @@ func (ui *GomuksUI) MakeMainUI() tview.Primitive {
}
func (ui *GomuksUI) HandleCommand(room, command string, args []string) {
+ ui.debug.Print("Handling command", command, args)
switch command {
- case "quit":
- ui.matrix.Stop()
- ui.app.Stop()
- case "part":
- case "leave":
+ case "/quit":
+ ui.gmx.Stop()
+ case "/clearcache":
+ ui.config.Session.Rooms = make(map[string]*gomatrix.Room)
+ ui.config.Session.NextBatch = ""
+ ui.config.Session.FilterID = ""
+ ui.config.Session.Save()
+ ui.gmx.Stop()
+ case "/part":
+ case "/leave":
ui.matrix.client.LeaveRoom(room)
- case "join":
+ case "/join":
if len(args) == 0 {
ui.Append(room, "*", "Usage: /join <room>")
}
@@ -91,7 +112,6 @@ func (ui *GomuksUI) HandleCommand(room, command string, args []string) {
}
func (ui *GomuksUI) MainUIKeyHandler(key *tcell.EventKey) *tcell.EventKey {
- ui.debug.Print("Main UI keypress:", key.Key(), key.Modifiers())
if key.Modifiers() == tcell.ModCtrl {
if key.Key() == tcell.KeyDown {
ui.SwitchRoom(ui.currentRoomIndex + 1)
@@ -115,11 +135,32 @@ func (ui *GomuksUI) SetRoomList(rooms []string) {
ui.mainViewRoomList.Clear()
for index, room := range rooms {
localRoomIndex := index
- ui.mainViewRoomList.AddItem(room, "", 0, func() {
+
+ ui.matrix.UpdateRoomInfo(room)
+ roomStore := ui.matrix.config.Session.LoadRoom(room)
+
+ name := room
+ topic := ""
+ if roomStore != nil {
+ nameEvt := roomStore.GetStateEvent("m.room.title", "")
+ if nameEvt != nil {
+ name, _ = nameEvt.Content["title"].(string)
+ } else {
+ nameEvt = roomStore.GetStateEvent("m.room.canonical_alias", "")
+ if nameEvt != nil {
+ name, _ = nameEvt.Content["alias"].(string)
+ }
+ }
+ topicEvt := roomStore.GetStateEvent("m.room.topic", "")
+ if topicEvt != nil {
+ topic, _ = topicEvt.Content["topic"].(string)
+ }
+ }
+ ui.mainViewRoomList.AddItem(name, "", 0, func() {
ui.SwitchRoom(localRoomIndex)
})
if !ui.mainViewRoomView.HasPage(room) {
- roomView := NewRoomView()
+ roomView := NewRoomView(name, topic)
ui.mainViewRooms[room] = roomView
ui.mainViewRoomView.AddPage(room, roomView, true, false)
}
@@ -142,10 +183,17 @@ func (ui *GomuksUI) SwitchRoom(roomIndex int) {
ui.mainViewRoomView.SwitchToPage(ui.roomList[ui.currentRoomIndex])
}
+func (ui *GomuksUI) SetTyping(room string, users []string) {
+ roomView, ok := ui.mainViewRooms[room]
+ if ok {
+ roomView.status.SetText("Typing: " + strings.Join(users, ", "))
+ }
+}
+
func (ui *GomuksUI) Append(room, sender, message string) {
roomView, ok := ui.mainViewRooms[room]
if ok {
- fmt.Fprintf(roomView, "<%s> %s\n", sender, message)
+ fmt.Fprintf(roomView.content, "<%s> %s\n", sender, message)
ui.Render()
}
}