aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-03-16 16:24:11 +0200
committerTulir Asokan <tulir@maunium.net>2018-03-16 16:24:11 +0200
commitc1bb107fa134dd5b8f126777f024fc693913da9a (patch)
tree5d63d647ca254259f8d8e80140bd439e9c0fd7fe
parente69e494a52962c7dac0d6c2585b1cccadfc82e64 (diff)
Misc bugfixes
-rw-r--r--matrix.go62
-rw-r--r--room-view.go45
-rw-r--r--session.go2
-rw-r--r--view-main.go84
4 files changed, 128 insertions, 65 deletions
diff --git a/matrix.go b/matrix.go
index a9b55b9..5992a60 100644
--- a/matrix.go
+++ b/matrix.go
@@ -19,6 +19,7 @@ package main
import (
"encoding/json"
"fmt"
+ "strings"
"time"
"maunium.net/go/gomatrix"
@@ -130,6 +131,7 @@ func (c *MatrixContainer) Start() {
syncer := c.client.Syncer.(*gomatrix.DefaultSyncer)
syncer.OnEventType("m.room.message", c.HandleMessage)
+ syncer.OnEventType("m.room.member", c.HandleMembership)
syncer.OnEventType("m.typing", c.HandleTyping)
for {
@@ -155,15 +157,32 @@ func (c *MatrixContainer) HandleMessage(evt *gomatrix.Event) {
timestampInt64, _ := timestampNumber.Int64()
timestamp := time.Now()
if timestampInt64 != 0 {
- timestamp = time.Unix(timestampInt64 / 1000, timestampInt64 % 1000 * 1000)
+ timestamp = time.Unix(timestampInt64/1000, timestampInt64%1000*1000)
}
c.ui.MainView().AddMessage(evt.RoomID, evt.Sender, message, timestamp)
}
+func (c *MatrixContainer) HandleMembership(evt *gomatrix.Event) {
+ if evt.StateKey != nil && *evt.StateKey == c.config.Session.MXID {
+ membership, _ := evt.Content["membership"].(string)
+ prevMembership := "leave"
+ if evt.Unsigned.PrevContent != nil {
+ prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
+ }
+ if membership == prevMembership {
+ return
+ }
+ if membership == "join" {
+ c.ui.MainView().AddRoom(evt.RoomID)
+ } else if membership == "leave" {
+ c.ui.MainView().RemoveRoom(evt.RoomID)
+ }
+ }
+}
+
func (c *MatrixContainer) HandleTyping(evt *gomatrix.Event) {
users := evt.Content["user_ids"].([]interface{})
- c.debug.Print(users, "are typing")
strUsers := make([]string, len(users))
for i, user := range users {
@@ -173,11 +192,13 @@ func (c *MatrixContainer) HandleTyping(evt *gomatrix.Event) {
}
func (c *MatrixContainer) SendMessage(roomID, message string) {
+ c.gmx.Recover()
c.SendTyping(roomID, false)
c.client.SendText(roomID, message)
}
func (c *MatrixContainer) SendTyping(roomID string, typing bool) {
+ c.gmx.Recover()
time := time.Now().Unix()
if c.typing > time && typing {
return
@@ -192,7 +213,26 @@ func (c *MatrixContainer) SendTyping(roomID string, typing bool) {
}
}
-func (c *MatrixContainer) GetState(roomID string) []*gomatrix.Event {
+func (c *MatrixContainer) JoinRoom(roomID string) error {
+ if len(roomID) == 0 {
+ return fmt.Errorf("invalid room ID")
+ }
+
+ server := ""
+ if roomID[0] == '!' {
+ server = roomID[strings.Index(roomID, ":")+1:]
+ }
+
+ resp, err := c.client.JoinRoom(roomID, server, nil)
+ if err != nil {
+ return err
+ }
+
+ c.ui.MainView().AddRoom(resp.RoomID)
+ return nil
+}
+
+func (c *MatrixContainer) getState(roomID string) []*gomatrix.Event {
content := make([]*gomatrix.Event, 0)
err := c.client.StateEvent(roomID, "", "", &content)
if err != nil {
@@ -202,15 +242,15 @@ func (c *MatrixContainer) GetState(roomID string) []*gomatrix.Event {
return content
}
-func (c *MatrixContainer) UpdateState(roomID string) {
+func (c *MatrixContainer) GetRoom(roomID string) *gomatrix.Room {
room := c.client.Store.LoadRoom(roomID)
- if room == nil {
- return
- }
- events := c.GetState(room.ID)
- if events != nil {
- for _, event := range events {
- room.UpdateState(event)
+ if len(room.State) == 0 {
+ events := c.getState(room.ID)
+ if events != nil {
+ for _, event := range events {
+ room.UpdateState(event)
+ }
}
}
+ return room
}
diff --git a/room-view.go b/room-view.go
index b9b911e..d5b9ca2 100644
--- a/room-view.go
+++ b/room-view.go
@@ -20,11 +20,11 @@ import (
"fmt"
"hash/fnv"
"regexp"
- "sort"
"strings"
"time"
"github.com/gdamore/tcell"
+ "maunium.net/go/gomatrix"
"maunium.net/go/tview"
)
@@ -35,7 +35,7 @@ type RoomView struct {
content *tview.TextView
status *tview.TextView
userList *tview.TextView
- users sort.StringSlice
+ room *gomatrix.Room
}
var colorNames []string
@@ -49,16 +49,17 @@ func init() {
}
}
-func NewRoomView(topic string) *RoomView {
+func NewRoomView(room *gomatrix.Room) *RoomView {
view := &RoomView{
Box: tview.NewBox(),
topic: tview.NewTextView(),
content: tview.NewTextView(),
status: tview.NewTextView(),
userList: tview.NewTextView(),
+ room: room,
}
view.topic.
- SetText(strings.Replace(topic, "\n", " ", -1)).
+ SetText(strings.Replace(room.GetTopic(), "\n", " ", -1)).
SetBackgroundColor(tcell.ColorDarkGreen)
view.status.SetBackgroundColor(tcell.ColorDimGray)
view.userList.SetDynamicColors(true)
@@ -86,6 +87,12 @@ func (view *RoomView) Draw(screen tcell.Screen) {
}
func (view *RoomView) SetTyping(users []string) {
+ for index, user := range users {
+ member := view.room.GetMember(user)
+ if member != nil {
+ users[index] = member.DisplayName
+ }
+ }
if len(users) == 0 {
view.status.SetText("")
} else if len(users) < 2 {
@@ -102,7 +109,7 @@ var colorPattern = regexp.MustCompile(`\[([a-zA-Z]+|#[0-9a-zA-Z]{6})\]`)
func color(s string) string {
h := fnv.New32a()
h.Write([]byte(s))
- color := colorNames[int(h.Sum32()) % len(colorNames)]
+ color := colorNames[int(h.Sum32())%len(colorNames)]
return fmt.Sprintf("[%s]%s[white]", color, s)
}
@@ -111,29 +118,21 @@ func escapeColor(s string) string {
}
func (view *RoomView) AddMessage(sender, message string, timestamp time.Time) {
+ member := view.room.GetMember(sender)
+ if member != nil {
+ sender = member.DisplayName
+ }
fmt.Fprintf(view.content, "[%s] %s: %s\n",
timestamp.Format("15:04:05"), color(sender), escapeColor(message))
}
-func (view *RoomView) SetUsers(users []string) {
- view.users = sort.StringSlice(users)
- view.users.Sort()
+func (view *RoomView) UpdateUserList() {
var buf strings.Builder
- for _, user := range view.users {
- buf.WriteString(color(user))
- buf.WriteRune('\n')
+ for _, user := range view.room.GetMembers() {
+ if user.Membership == "join" {
+ buf.WriteString(color(user.DisplayName))
+ buf.WriteRune('\n')
+ }
}
view.userList.SetText(buf.String())
}
-
-func (view *RoomView) RemoveUser(user string) {
- i := view.users.Search(user)
- if i >= 0 {
- view.users = append(view.users[:i], view.users[i+1:]...)
- view.userList.SetText(strings.Join(view.users, "\n"))
- }
-}
-
-func (view *RoomView) AddUser(user string) {
- view.SetUsers(append(view.users, user))
-}
diff --git a/session.go b/session.go
index d83d443..44f0787 100644
--- a/session.go
+++ b/session.go
@@ -88,7 +88,7 @@ func (s *Session) LoadNextBatch(_ string) string {
func (s *Session) LoadRoom(mxid string) *gomatrix.Room {
room, ok := s.Rooms[mxid]
if !ok || room == nil {
- room := gomatrix.NewRoom(mxid)
+ room = gomatrix.NewRoom(mxid)
s.SaveRoom(room)
}
return room
diff --git a/view-main.go b/view-main.go
index 3c536c9..58fbd80 100644
--- a/view-main.go
+++ b/view-main.go
@@ -85,9 +85,9 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
func (view *MainView) InputChanged(text string) {
if len(text) == 0 {
- view.matrix.SendTyping(view.CurrentRoomID(), false)
+ go view.matrix.SendTyping(view.CurrentRoomID(), false)
} else if text[0] != '/' {
- view.matrix.SendTyping(view.CurrentRoomID(), true)
+ go view.matrix.SendTyping(view.CurrentRoomID(), true)
}
}
@@ -100,15 +100,16 @@ func (view *MainView) InputDone(key tcell.Key) {
args := strings.SplitN(text, " ", 2)
command := strings.ToLower(args[0])
args = args[1:]
- view.HandleCommand(room, command, args)
+ go view.HandleCommand(room, command, args)
} else {
- view.matrix.SendMessage(room, text)
+ go view.matrix.SendMessage(room, text)
}
view.input.SetText("")
}
}
func (view *MainView) HandleCommand(room, command string, args []string) {
+ view.gmx.Recover()
view.debug.Print("Handling command", command, args)
switch command {
case "/quit":
@@ -120,6 +121,7 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
view.config.Session.Save()
view.gmx.Stop()
case "/part":
+ fallthrough
case "/leave":
view.matrix.client.LeaveRoom(room)
case "/join":
@@ -127,9 +129,9 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
view.AddMessage(room, "*", "Usage: /join <room>", time.Now())
break
}
- mxid := args[0]
- server := mxid[strings.Index(mxid, ":")+1:]
- view.matrix.client.JoinRoom(mxid, server, nil)
+ view.debug.Print(view.matrix.JoinRoom(args[0]))
+ default:
+ view.AddMessage(room, "*", "Unknown command.", time.Now())
}
}
@@ -165,36 +167,58 @@ func (view *MainView) SwitchRoom(roomIndex int) {
}
view.currentRoomIndex = roomIndex % len(view.roomIDs)
view.roomView.SwitchToPage(view.CurrentRoomID())
+ view.roomList.SetCurrentItem(roomIndex)
view.parent.Render()
}
+func (view *MainView) addRoom(index int, room string) {
+ roomStore := view.matrix.GetRoom(room)
+
+ view.roomList.AddItem(roomStore.GetTitle(), "", 0, func() {
+ view.SwitchRoom(index)
+ })
+ if !view.roomView.HasPage(room) {
+ roomView := NewRoomView(roomStore)
+ view.rooms[room] = roomView
+ view.roomView.AddPage(room, roomView, true, false)
+ roomView.UpdateUserList()
+ }
+}
+
+func (view *MainView) HasRoom(room string) bool {
+ for _, existingRoom := range view.roomIDs {
+ if existingRoom == room {
+ return true
+ }
+ }
+ return false
+}
+
+func (view *MainView) AddRoom(room string) {
+ if view.HasRoom(room) {
+ return
+ }
+ view.roomIDs = append(view.roomIDs, room)
+ view.addRoom(len(view.roomIDs) - 1, room)
+}
+
+func (view *MainView) RemoveRoom(room string) {
+ if !view.HasRoom(room) {
+ return
+ }
+ view.roomList.RemoveItem(view.currentRoomIndex)
+ if view.CurrentRoomID() == room {
+ view.SwitchRoom(view.currentRoomIndex - 1)
+ }
+ view.roomView.RemovePage(room)
+}
+
func (view *MainView) SetRoomList(rooms []string) {
view.roomIDs = rooms
view.roomList.Clear()
+ view.roomView.Clear()
for index, room := range rooms {
- localRoomIndex := index
-
- view.matrix.UpdateState(room)
- roomStore := view.matrix.config.Session.LoadRoom(room)
-
- name := room
- topic := ""
- var users []string
- if roomStore != nil {
- name = roomStore.GetTitle()
- topic = roomStore.GetTopic()
- users = roomStore.GetMembers()
- }
-
- view.roomList.AddItem(name, "", 0, func() {
- view.SwitchRoom(localRoomIndex)
- })
- if !view.roomView.HasPage(room) {
- roomView := NewRoomView(topic)
- roomView.SetUsers(users)
- view.rooms[room] = roomView
- view.roomView.AddPage(room, roomView, true, false)
- }
+ view.addRoom(index, room)
}
view.SwitchRoom(0)
}