Misc bugfixes
This commit is contained in:
parent
e69e494a52
commit
c1bb107fa1
62
matrix.go
62
matrix.go
@ -19,6 +19,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/gomatrix"
|
"maunium.net/go/gomatrix"
|
||||||
@ -130,6 +131,7 @@ func (c *MatrixContainer) Start() {
|
|||||||
|
|
||||||
syncer := c.client.Syncer.(*gomatrix.DefaultSyncer)
|
syncer := c.client.Syncer.(*gomatrix.DefaultSyncer)
|
||||||
syncer.OnEventType("m.room.message", c.HandleMessage)
|
syncer.OnEventType("m.room.message", c.HandleMessage)
|
||||||
|
syncer.OnEventType("m.room.member", c.HandleMembership)
|
||||||
syncer.OnEventType("m.typing", c.HandleTyping)
|
syncer.OnEventType("m.typing", c.HandleTyping)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -155,15 +157,32 @@ func (c *MatrixContainer) HandleMessage(evt *gomatrix.Event) {
|
|||||||
timestampInt64, _ := timestampNumber.Int64()
|
timestampInt64, _ := timestampNumber.Int64()
|
||||||
timestamp := time.Now()
|
timestamp := time.Now()
|
||||||
if timestampInt64 != 0 {
|
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)
|
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) {
|
func (c *MatrixContainer) HandleTyping(evt *gomatrix.Event) {
|
||||||
users := evt.Content["user_ids"].([]interface{})
|
users := evt.Content["user_ids"].([]interface{})
|
||||||
c.debug.Print(users, "are typing")
|
|
||||||
|
|
||||||
strUsers := make([]string, len(users))
|
strUsers := make([]string, len(users))
|
||||||
for i, user := range users {
|
for i, user := range users {
|
||||||
@ -173,11 +192,13 @@ func (c *MatrixContainer) HandleTyping(evt *gomatrix.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *MatrixContainer) SendMessage(roomID, message string) {
|
func (c *MatrixContainer) SendMessage(roomID, message string) {
|
||||||
|
c.gmx.Recover()
|
||||||
c.SendTyping(roomID, false)
|
c.SendTyping(roomID, false)
|
||||||
c.client.SendText(roomID, message)
|
c.client.SendText(roomID, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MatrixContainer) SendTyping(roomID string, typing bool) {
|
func (c *MatrixContainer) SendTyping(roomID string, typing bool) {
|
||||||
|
c.gmx.Recover()
|
||||||
time := time.Now().Unix()
|
time := time.Now().Unix()
|
||||||
if c.typing > time && typing {
|
if c.typing > time && typing {
|
||||||
return
|
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)
|
content := make([]*gomatrix.Event, 0)
|
||||||
err := c.client.StateEvent(roomID, "", "", &content)
|
err := c.client.StateEvent(roomID, "", "", &content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -202,15 +242,15 @@ func (c *MatrixContainer) GetState(roomID string) []*gomatrix.Event {
|
|||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MatrixContainer) UpdateState(roomID string) {
|
func (c *MatrixContainer) GetRoom(roomID string) *gomatrix.Room {
|
||||||
room := c.client.Store.LoadRoom(roomID)
|
room := c.client.Store.LoadRoom(roomID)
|
||||||
if room == nil {
|
if len(room.State) == 0 {
|
||||||
return
|
events := c.getState(room.ID)
|
||||||
}
|
if events != nil {
|
||||||
events := c.GetState(room.ID)
|
for _, event := range events {
|
||||||
if events != nil {
|
room.UpdateState(event)
|
||||||
for _, event := range events {
|
}
|
||||||
room.UpdateState(event)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return room
|
||||||
}
|
}
|
||||||
|
45
room-view.go
45
room-view.go
@ -20,11 +20,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"maunium.net/go/tview"
|
"maunium.net/go/tview"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ type RoomView struct {
|
|||||||
content *tview.TextView
|
content *tview.TextView
|
||||||
status *tview.TextView
|
status *tview.TextView
|
||||||
userList *tview.TextView
|
userList *tview.TextView
|
||||||
users sort.StringSlice
|
room *gomatrix.Room
|
||||||
}
|
}
|
||||||
|
|
||||||
var colorNames []string
|
var colorNames []string
|
||||||
@ -49,16 +49,17 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRoomView(topic string) *RoomView {
|
func NewRoomView(room *gomatrix.Room) *RoomView {
|
||||||
view := &RoomView{
|
view := &RoomView{
|
||||||
Box: tview.NewBox(),
|
Box: tview.NewBox(),
|
||||||
topic: tview.NewTextView(),
|
topic: tview.NewTextView(),
|
||||||
content: tview.NewTextView(),
|
content: tview.NewTextView(),
|
||||||
status: tview.NewTextView(),
|
status: tview.NewTextView(),
|
||||||
userList: tview.NewTextView(),
|
userList: tview.NewTextView(),
|
||||||
|
room: room,
|
||||||
}
|
}
|
||||||
view.topic.
|
view.topic.
|
||||||
SetText(strings.Replace(topic, "\n", " ", -1)).
|
SetText(strings.Replace(room.GetTopic(), "\n", " ", -1)).
|
||||||
SetBackgroundColor(tcell.ColorDarkGreen)
|
SetBackgroundColor(tcell.ColorDarkGreen)
|
||||||
view.status.SetBackgroundColor(tcell.ColorDimGray)
|
view.status.SetBackgroundColor(tcell.ColorDimGray)
|
||||||
view.userList.SetDynamicColors(true)
|
view.userList.SetDynamicColors(true)
|
||||||
@ -86,6 +87,12 @@ func (view *RoomView) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) SetTyping(users []string) {
|
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 {
|
if len(users) == 0 {
|
||||||
view.status.SetText("")
|
view.status.SetText("")
|
||||||
} else if len(users) < 2 {
|
} 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 {
|
func color(s string) string {
|
||||||
h := fnv.New32a()
|
h := fnv.New32a()
|
||||||
h.Write([]byte(s))
|
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)
|
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) {
|
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",
|
fmt.Fprintf(view.content, "[%s] %s: %s\n",
|
||||||
timestamp.Format("15:04:05"), color(sender), escapeColor(message))
|
timestamp.Format("15:04:05"), color(sender), escapeColor(message))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) SetUsers(users []string) {
|
func (view *RoomView) UpdateUserList() {
|
||||||
view.users = sort.StringSlice(users)
|
|
||||||
view.users.Sort()
|
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
for _, user := range view.users {
|
for _, user := range view.room.GetMembers() {
|
||||||
buf.WriteString(color(user))
|
if user.Membership == "join" {
|
||||||
buf.WriteRune('\n')
|
buf.WriteString(color(user.DisplayName))
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
view.userList.SetText(buf.String())
|
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))
|
|
||||||
}
|
|
||||||
|
@ -88,7 +88,7 @@ func (s *Session) LoadNextBatch(_ string) string {
|
|||||||
func (s *Session) LoadRoom(mxid string) *gomatrix.Room {
|
func (s *Session) LoadRoom(mxid string) *gomatrix.Room {
|
||||||
room, ok := s.Rooms[mxid]
|
room, ok := s.Rooms[mxid]
|
||||||
if !ok || room == nil {
|
if !ok || room == nil {
|
||||||
room := gomatrix.NewRoom(mxid)
|
room = gomatrix.NewRoom(mxid)
|
||||||
s.SaveRoom(room)
|
s.SaveRoom(room)
|
||||||
}
|
}
|
||||||
return room
|
return room
|
||||||
|
84
view-main.go
84
view-main.go
@ -85,9 +85,9 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
|
|||||||
|
|
||||||
func (view *MainView) InputChanged(text string) {
|
func (view *MainView) InputChanged(text string) {
|
||||||
if len(text) == 0 {
|
if len(text) == 0 {
|
||||||
view.matrix.SendTyping(view.CurrentRoomID(), false)
|
go view.matrix.SendTyping(view.CurrentRoomID(), false)
|
||||||
} else if text[0] != '/' {
|
} 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)
|
args := strings.SplitN(text, " ", 2)
|
||||||
command := strings.ToLower(args[0])
|
command := strings.ToLower(args[0])
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
view.HandleCommand(room, command, args)
|
go view.HandleCommand(room, command, args)
|
||||||
} else {
|
} else {
|
||||||
view.matrix.SendMessage(room, text)
|
go view.matrix.SendMessage(room, text)
|
||||||
}
|
}
|
||||||
view.input.SetText("")
|
view.input.SetText("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) HandleCommand(room, command string, args []string) {
|
func (view *MainView) HandleCommand(room, command string, args []string) {
|
||||||
|
view.gmx.Recover()
|
||||||
view.debug.Print("Handling command", command, args)
|
view.debug.Print("Handling command", command, args)
|
||||||
switch command {
|
switch command {
|
||||||
case "/quit":
|
case "/quit":
|
||||||
@ -120,6 +121,7 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
|
|||||||
view.config.Session.Save()
|
view.config.Session.Save()
|
||||||
view.gmx.Stop()
|
view.gmx.Stop()
|
||||||
case "/part":
|
case "/part":
|
||||||
|
fallthrough
|
||||||
case "/leave":
|
case "/leave":
|
||||||
view.matrix.client.LeaveRoom(room)
|
view.matrix.client.LeaveRoom(room)
|
||||||
case "/join":
|
case "/join":
|
||||||
@ -127,9 +129,9 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
|
|||||||
view.AddMessage(room, "*", "Usage: /join <room>", time.Now())
|
view.AddMessage(room, "*", "Usage: /join <room>", time.Now())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
mxid := args[0]
|
view.debug.Print(view.matrix.JoinRoom(args[0]))
|
||||||
server := mxid[strings.Index(mxid, ":")+1:]
|
default:
|
||||||
view.matrix.client.JoinRoom(mxid, server, nil)
|
view.AddMessage(room, "*", "Unknown command.", time.Now())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,36 +167,58 @@ func (view *MainView) SwitchRoom(roomIndex int) {
|
|||||||
}
|
}
|
||||||
view.currentRoomIndex = roomIndex % len(view.roomIDs)
|
view.currentRoomIndex = roomIndex % len(view.roomIDs)
|
||||||
view.roomView.SwitchToPage(view.CurrentRoomID())
|
view.roomView.SwitchToPage(view.CurrentRoomID())
|
||||||
|
view.roomList.SetCurrentItem(roomIndex)
|
||||||
view.parent.Render()
|
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) {
|
func (view *MainView) SetRoomList(rooms []string) {
|
||||||
view.roomIDs = rooms
|
view.roomIDs = rooms
|
||||||
view.roomList.Clear()
|
view.roomList.Clear()
|
||||||
|
view.roomView.Clear()
|
||||||
for index, room := range rooms {
|
for index, room := range rooms {
|
||||||
localRoomIndex := index
|
view.addRoom(index, room)
|
||||||
|
|
||||||
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.SwitchRoom(0)
|
view.SwitchRoom(0)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user