Misc bugfixes
This commit is contained in:
		
							
								
								
									
										54
									
								
								matrix.go
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								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 {
 | 
			
		||||
@@ -161,9 +163,26 @@ func (c *MatrixContainer) HandleMessage(evt *gomatrix.Event) {
 | 
			
		||||
	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 len(room.State) == 0 {
 | 
			
		||||
		events := c.getState(room.ID)
 | 
			
		||||
		if events != nil {
 | 
			
		||||
			for _, event := range events {
 | 
			
		||||
				room.UpdateState(event)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return room
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								room-view.go
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								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 {
 | 
			
		||||
@@ -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))
 | 
			
		||||
	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))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								view-main.go
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user