More code

This commit is contained in:
Tulir Asokan 2018-03-15 00:14:39 +02:00
parent 08f5db1a74
commit deb2c1ac16
4 changed files with 137 additions and 18 deletions

View File

@ -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)

View File

@ -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", "")
}

View File

@ -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) {

View File

@ -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()
}
}