aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-03-17 15:48:31 +0200
committerTulir Asokan <tulir@maunium.net>2018-03-17 15:48:31 +0200
commitb0ebb4b9a48276289dc51f9c2574e25cad60b867 (patch)
tree96206279e586aa111d0de69ddb36cf02ae09205e
parentba379a1b4a97ee7eb56bed726f1c4edd76f76bb8 (diff)
Refactoring, right-align users and fix join/leave messages
-rw-r--r--matrix.go61
-rw-r--r--message-view.go28
-rw-r--r--room-view.go64
-rw-r--r--session.go4
-rw-r--r--view-main.go27
5 files changed, 130 insertions, 54 deletions
diff --git a/matrix.go b/matrix.go
index f578ac3..4dca289 100644
--- a/matrix.go
+++ b/matrix.go
@@ -121,18 +121,19 @@ func (c *MatrixContainer) UpdateRoomList() {
func (c *MatrixContainer) Start() {
defer c.gmx.Recover()
- c.debug.Print("Starting sync...")
- c.running = true
- c.ui.SetView(ViewMain)
c.client.Store = c.config.Session
- c.UpdateRoomList()
-
- syncer := c.client.Syncer.(*gomatrix.DefaultSyncer)
+ syncer := gomatrix.NewDefaultSyncer(c.config.Session.MXID, c.config.Session)
syncer.OnEventType("m.room.message", c.HandleMessage)
syncer.OnEventType("m.room.member", c.HandleMembership)
syncer.OnEventType("m.typing", c.HandleTyping)
+ c.client.Syncer = syncer
+ c.UpdateRoomList()
+
+ c.debug.Print("Starting sync...")
+ c.running = true
+ c.ui.SetView(ViewMain)
for {
select {
case <-c.stop:
@@ -152,17 +153,23 @@ func (c *MatrixContainer) Start() {
func (c *MatrixContainer) HandleMessage(evt *gomatrix.Event) {
message, _ := evt.Content["body"].(string)
- timestamp := time.Now()
- if evt.Timestamp != 0 {
- timestamp = time.Unix(evt.Timestamp/1000, evt.Timestamp%1000*1000)
+ room := c.ui.MainView().GetRoom(evt.RoomID)
+ if room != nil {
+ room.AddMessage(evt.ID, evt.Sender, message, unixToTime(evt.Timestamp))
}
+}
- c.ui.MainView().AddRealMessage(evt.RoomID, evt.ID, evt.Sender, message, timestamp)
+func unixToTime(unix int64) time.Time {
+ timestamp := time.Now()
+ if unix != 0 {
+ timestamp = time.Unix(unix/1000, unix%1000*1000)
+ }
+ return timestamp
}
func (c *MatrixContainer) HandleMembership(evt *gomatrix.Event) {
+ membership, _ := evt.Content["membership"].(string)
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)
@@ -175,6 +182,34 @@ func (c *MatrixContainer) HandleMembership(evt *gomatrix.Event) {
} else if membership == "leave" {
c.ui.MainView().RemoveRoom(evt.RoomID)
}
+ return
+ }
+ room := c.ui.MainView().GetRoom(evt.RoomID)
+
+ // TODO this shouldn't be necessary
+ room.room.UpdateState(evt)
+
+ if room != nil {
+ var message, sender string
+ if membership == "invite" {
+ sender = "---"
+ message = fmt.Sprintf("%s invited %s.", evt.Sender, *evt.StateKey)
+ } else if membership == "join" {
+ sender = "-->"
+ message = fmt.Sprintf("%s joined the room.", *evt.StateKey)
+ } else if membership == "leave" {
+ sender = "<--"
+ if evt.Sender != *evt.StateKey {
+ reason, _ := evt.Content["reason"].(string)
+ message = fmt.Sprintf("%s kicked %s: %s", evt.Sender, *evt.StateKey, reason)
+ } else {
+ message = fmt.Sprintf("%s left the room.", *evt.StateKey)
+ }
+ } else {
+ return
+ }
+ room.UpdateUserList()
+ room.AddMessage(evt.ID, sender, message, unixToTime(evt.Timestamp))
}
}
@@ -240,8 +275,8 @@ func (c *MatrixContainer) getState(roomID string) []*gomatrix.Event {
}
func (c *MatrixContainer) GetRoom(roomID string) *gomatrix.Room {
- room := c.client.Store.LoadRoom(roomID)
- if len(room.State) == 0 {
+ room := c.config.Session.LoadRoom(roomID)
+ if room != nil && len(room.State) == 0 {
events := c.getState(room.ID)
if events != nil {
for _, event := range events {
diff --git a/message-view.go b/message-view.go
index 633c551..6029f6a 100644
--- a/message-view.go
+++ b/message-view.go
@@ -93,11 +93,9 @@ type MessageView struct {
totalHeight int
messages []*Message
-
- debug DebugPrinter
}
-func NewMessageView(debug DebugPrinter) *MessageView {
+func NewMessageView() *MessageView {
return &MessageView{
Box: tview.NewBox(),
MaxSenderWidth: 20,
@@ -113,8 +111,6 @@ func NewMessageView(debug DebugPrinter) *MessageView {
firstDisplayMessage: -1,
lastDisplayMessage: -1,
totalHeight: -1,
-
- debug: debug,
}
}
@@ -207,6 +203,24 @@ func (view *MessageView) writeLine(screen tcell.Screen, line string, x, y int, c
}
}
+func (view *MessageView) writeLineRight(screen tcell.Screen, line string, x, y, maxWidth int, color tcell.Color) {
+ offsetX := maxWidth - runewidth.StringWidth(line)
+ if offsetX < 0 {
+ offsetX = 0
+ }
+ for _, ch := range line {
+ chWidth := runewidth.RuneWidth(ch)
+ if chWidth == 0 {
+ continue
+ }
+
+ for localOffset := 0; localOffset < chWidth; localOffset++ {
+ screen.SetContent(x+offsetX+localOffset, y, ch, nil, tcell.StyleDefault.Foreground(color))
+ }
+ offsetX += chWidth
+ }
+}
+
const (
TimestampSenderGap = 1
SenderSeparatorGap = 1
@@ -246,7 +260,9 @@ func (view *MessageView) Draw(screen tcell.Screen) {
}
view.writeLine(screen, message.Timestamp, x, senderAtLine, tcell.ColorDefault)
if message.RenderSender || i == view.lastDisplayMessage {
- view.writeLine(screen, message.Sender, x+usernameOffsetX, senderAtLine, message.senderColor)
+ view.writeLineRight(screen, message.Sender,
+ x+usernameOffsetX, senderAtLine,
+ view.widestSender, message.senderColor)
}
for num, line := range message.buffer {
diff --git a/room-view.go b/room-view.go
index 6764e85..4b6feac 100644
--- a/room-view.go
+++ b/room-view.go
@@ -21,6 +21,7 @@ import (
"hash/fnv"
"sort"
"strings"
+ "time"
"github.com/gdamore/tcell"
"maunium.net/go/gomatrix"
@@ -36,7 +37,7 @@ type RoomView struct {
userList *tview.TextView
room *gomatrix.Room
- debug DebugPrinter
+ parent *MainView
}
var colorNames []string
@@ -51,15 +52,15 @@ func init() {
sort.Sort(sort.StringSlice(colorNames))
}
-func NewRoomView(debug DebugPrinter, room *gomatrix.Room) *RoomView {
+func NewRoomView(parent *MainView, room *gomatrix.Room) *RoomView {
view := &RoomView{
Box: tview.NewBox(),
topic: tview.NewTextView(),
- content: NewMessageView(debug),
+ content: NewMessageView(),
status: tview.NewTextView(),
userList: tview.NewTextView(),
room: room,
- debug: debug,
+ parent: parent,
}
view.topic.
SetText(strings.Replace(room.GetTopic(), "\n", " ", -1)).
@@ -108,20 +109,38 @@ func (view *RoomView) SetTyping(users []string) {
}
}
+func (view *RoomView) AutocompleteUser(existingText string) (completions []string) {
+ for _, user := range view.room.GetMembers() {
+ if strings.HasPrefix(user.DisplayName, existingText) {
+ completions = append(completions, user.DisplayName)
+ } else if strings.HasPrefix(user.UserID, existingText) {
+ completions = append(completions, user.UserID)
+ }
+ }
+ return
+}
+
func (view *RoomView) MessageView() *MessageView {
return view.content
}
func getColorName(s string) string {
- h := fnv.New32a()
- h.Write([]byte(s))
- return colorNames[int(h.Sum32())%len(colorNames)]
+ switch s {
+ case "-->":
+ return "green"
+ case "<--":
+ return "red"
+ case "---":
+ return "yellow"
+ default:
+ h := fnv.New32a()
+ h.Write([]byte(s))
+ return colorNames[int(h.Sum32())%len(colorNames)]
+ }
}
func getColor(s string) tcell.Color {
- h := fnv.New32a()
- h.Write([]byte(s))
- return tcell.ColorNames[colorNames[int(h.Sum32())%len(colorNames)]]
+ return tcell.ColorNames[getColorName(s)]
}
func color(s string) string {
@@ -129,12 +148,29 @@ func color(s string) string {
}
func (view *RoomView) UpdateUserList() {
- var buf strings.Builder
+ var joined strings.Builder
+ var invited strings.Builder
for _, user := range view.room.GetMembers() {
if user.Membership == "join" {
- buf.WriteString(color(user.DisplayName))
- buf.WriteRune('\n')
+ joined.WriteString(color(user.DisplayName))
+ joined.WriteRune('\n')
+ } else if user.Membership == "invite" {
+ invited.WriteString(color(user.DisplayName))
+ invited.WriteRune('\n')
}
}
- view.userList.SetText(buf.String())
+ view.userList.Clear()
+ fmt.Fprintf(view.userList, "%s\n", joined.String())
+ if invited.Len() > 0 {
+ fmt.Fprintf(view.userList, "\nInvited:\n%s", invited.String())
+ }
+}
+
+func (view *RoomView) AddMessage(id, sender, message string, timestamp time.Time) {
+ member := view.room.GetMember(sender)
+ if member != nil {
+ sender = member.DisplayName
+ }
+ view.content.AddMessage(id, sender, message, timestamp)
+ view.parent.Render()
}
diff --git a/session.go b/session.go
index 44f0787..b679076 100644
--- a/session.go
+++ b/session.go
@@ -86,8 +86,8 @@ func (s *Session) LoadNextBatch(_ string) string {
}
func (s *Session) LoadRoom(mxid string) *gomatrix.Room {
- room, ok := s.Rooms[mxid]
- if !ok || room == nil {
+ room, _ := s.Rooms[mxid]
+ if room == nil {
room = gomatrix.NewRoom(mxid)
s.SaveRoom(room)
}
diff --git a/view-main.go b/view-main.go
index 219e603..4696afb 100644
--- a/view-main.go
+++ b/view-main.go
@@ -111,15 +111,8 @@ func findWordToTabComplete(text string) string {
return output
}
-func (view *RoomView) AutocompleteUser(existingText string) (completions []string) {
- for _, user := range view.room.GetMembers() {
- if strings.HasPrefix(user.DisplayName, existingText) {
- completions = append(completions, user.DisplayName)
- } else if strings.HasPrefix(user.UserID, existingText) {
- completions = append(completions, user.UserID)
- }
- }
- return
+func (view *MainView) GetRoom(id string) *RoomView {
+ return view.rooms[id]
}
func (view *MainView) InputTabComplete(text string, cursorOffset int) string {
@@ -231,7 +224,7 @@ func (view *MainView) addRoom(index int, room string) {
view.SwitchRoom(index)
})
if !view.roomView.HasPage(room) {
- roomView := NewRoomView(view.debug, roomStore)
+ roomView := NewRoomView(view, roomStore)
view.rooms[room] = roomView
view.roomView.AddPage(room, roomView, true, false)
roomView.UpdateUserList()
@@ -285,17 +278,13 @@ func (view *MainView) SetTyping(room string, users []string) {
}
func (view *MainView) AddMessage(room, message string) {
- view.AddRealMessage(room, "", "*", message, time.Now())
-}
-
-func (view *MainView) AddRealMessage(room, id, sender, message string, timestamp time.Time) {
roomView, ok := view.rooms[room]
if ok {
- member := roomView.room.GetMember(sender)
- if member != nil {
- sender = member.DisplayName
- }
- roomView.content.AddMessage(id, sender, message, timestamp)
+ roomView.content.AddMessage("", "*", message, time.Now())
view.parent.Render()
}
}
+
+func (view *MainView) Render() {
+ view.parent.Render()
+}