Unbreak more things
This commit is contained in:
		@@ -108,6 +108,7 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
 | 
			
		||||
			"rainbow":         cmdRainbow,
 | 
			
		||||
			"invite":          cmdInvite,
 | 
			
		||||
			"hprof":           cmdHeapProfile,
 | 
			
		||||
			"cprof":           cmdCPUProfile,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,11 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	dbg "runtime/debug"
 | 
			
		||||
	"runtime/pprof"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode"
 | 
			
		||||
 | 
			
		||||
	"github.com/lucasb-eyer/go-colorful"
 | 
			
		||||
@@ -71,17 +74,58 @@ var rainbow = GradientTable{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdHeapProfile(cmd *Command) {
 | 
			
		||||
	dbg.FreeOSMemory()
 | 
			
		||||
	runtime.GC()
 | 
			
		||||
	memProfile, err := os.Create("gomuks.prof")
 | 
			
		||||
	memProfile, err := os.Create("gomuks.heap.prof")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		debug.Print(err)
 | 
			
		||||
		debug.Print("Failed to open gomuks.heap.prof:", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer memProfile.Close()
 | 
			
		||||
	defer func() {
 | 
			
		||||
		err := memProfile.Close()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			debug.Print("Failed to close gomuks.heap.prof:", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	if err := pprof.WriteHeapProfile(memProfile); err != nil {
 | 
			
		||||
		debug.Print(err)
 | 
			
		||||
		debug.Print("Heap profile error:", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdCPUProfile(cmd *Command) {
 | 
			
		||||
	if len(cmd.Args) == 0 {
 | 
			
		||||
		cmd.Reply("Usage: /cprof <seconds>")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	dur, err := strconv.Atoi(cmd.Args[0])
 | 
			
		||||
	if err != nil || dur < 0 {
 | 
			
		||||
		cmd.Reply("Usage: /cprof <seconds>")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cpuProfile, err := os.Create("gomuks.cpu.prof")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		debug.Print("Failed to open gomuks.cpu.prof:", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	err = pprof.StartCPUProfile(cpuProfile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		_ = cpuProfile.Close()
 | 
			
		||||
		debug.Print("CPU profile error:", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cmd.Reply("Started CPU profiling for %d seconds", dur)
 | 
			
		||||
	go func() {
 | 
			
		||||
		time.Sleep(time.Duration(dur) * time.Second)
 | 
			
		||||
		pprof.StopCPUProfile()
 | 
			
		||||
		cmd.Reply("CPU profiling finished.")
 | 
			
		||||
 | 
			
		||||
		err := cpuProfile.Close()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			debug.Print("Failed to close gomuks.cpu.prof:", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO this command definitely belongs in a plugin once we have a plugin system.
 | 
			
		||||
func cmdRainbow(cmd *Command) {
 | 
			
		||||
	text := strings.Join(cmd.Args, " ")
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,23 @@ func NewMessageView(parent *RoomView) *MessageView {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *MessageView) Unload() {
 | 
			
		||||
	debug.Print("Unloading message view", view.parent.Room.ID)
 | 
			
		||||
	view.messagesLock.Lock()
 | 
			
		||||
	view.msgBufferLock.Lock()
 | 
			
		||||
	view.messageIDLock.Lock()
 | 
			
		||||
	view.messageIDs = make(map[string]*messages.UIMessage)
 | 
			
		||||
	view.msgBuffer = make([]*messages.UIMessage, 0)
 | 
			
		||||
	view.messages = make([]*messages.UIMessage, 0)
 | 
			
		||||
	view.initialHistoryLoaded = false
 | 
			
		||||
	view.ScrollOffset = 0
 | 
			
		||||
	view._widestSender = 5
 | 
			
		||||
	view.prevMsgCount = -1
 | 
			
		||||
	view.messagesLock.Unlock()
 | 
			
		||||
	view.msgBufferLock.Unlock()
 | 
			
		||||
	view.messageIDLock.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *MessageView) updateWidestSender(sender string) {
 | 
			
		||||
	if len(sender) > int(view._widestSender) {
 | 
			
		||||
		if len(sender) > view.MaxSenderWidth {
 | 
			
		||||
 
 | 
			
		||||
@@ -423,8 +423,10 @@ func (list *RoomList) OnMouseEvent(event mauview.MouseEvent) bool {
 | 
			
		||||
	switch event.Buttons() {
 | 
			
		||||
	case tcell.WheelUp:
 | 
			
		||||
		list.AddScrollOffset(-WheelScrollOffsetDiff)
 | 
			
		||||
		return true
 | 
			
		||||
	case tcell.WheelDown:
 | 
			
		||||
		list.AddScrollOffset(WheelScrollOffsetDiff)
 | 
			
		||||
		return true
 | 
			
		||||
	case tcell.Button1:
 | 
			
		||||
		x, y := event.Position()
 | 
			
		||||
		return list.clickRoom(y, x, event.Modifiers() == tcell.ModCtrl)
 | 
			
		||||
@@ -486,7 +488,8 @@ func (list *RoomList) clickRoom(line, column int, mod bool) bool {
 | 
			
		||||
				if trl.maxShown < 10 {
 | 
			
		||||
					trl.maxShown = 10
 | 
			
		||||
				}
 | 
			
		||||
				break
 | 
			
		||||
				list.RUnlock()
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Tag footer
 | 
			
		||||
 
 | 
			
		||||
@@ -93,6 +93,17 @@ func NewRoomView(parent *MainView, room *rooms.Room) *RoomView {
 | 
			
		||||
		config: parent.config,
 | 
			
		||||
	}
 | 
			
		||||
	view.content = NewMessageView(view)
 | 
			
		||||
	view.Room.SetOnUnload(func() bool {
 | 
			
		||||
		if view.parent.currentRoom == view {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		view.content.Unload()
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	view.Room.SetOnLoad(func() bool {
 | 
			
		||||
		view.loadTyping()
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	view.input.
 | 
			
		||||
		SetBackgroundColor(tcell.ColorDefault).
 | 
			
		||||
@@ -270,14 +281,20 @@ func (view *RoomView) SetCompletions(completions []string) {
 | 
			
		||||
	view.completions.time = time.Now()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) SetTyping(users []string) {
 | 
			
		||||
	for index, user := range users {
 | 
			
		||||
func (view *RoomView) loadTyping() {
 | 
			
		||||
	for index, user := range view.typing {
 | 
			
		||||
		member := view.Room.GetMember(user)
 | 
			
		||||
		if member != nil {
 | 
			
		||||
			users[index] = member.Displayname
 | 
			
		||||
			view.typing[index] = member.Displayname
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) SetTyping(users []string) {
 | 
			
		||||
	view.typing = users
 | 
			
		||||
	if view.Room.Loaded() {
 | 
			
		||||
		view.loadTyping()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type completion struct {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user