diff --git a/matrix/room/room.go b/matrix/room/room.go index 264ee3b..c006bd3 100644 --- a/matrix/room/room.go +++ b/matrix/room/room.go @@ -18,6 +18,7 @@ package rooms import ( "fmt" + "sync" "maunium.net/go/gomatrix" ) @@ -28,17 +29,33 @@ type Room struct { // The first batch of events that has been fetched for this room. // Used for fetching additional history. - PrevBatch string + PrevBatch string // The MXID of the user whose session this room was created for. - SessionUserID string + SessionUserID string // MXID -> Member cache calculated from membership events. - memberCache map[string]*Member + memberCache map[string]*Member // The first non-SessionUserID member in the room. Calculated at the same time as memberCache. firstMemberCache string // The name of the room. Calculated from the state event name, canonical_alias or alias or the member cache. - nameCache string + nameCache string // The topic of the room. Directly fetched from the m.room.topic state event. - topicCache string + topicCache string + + // fetchHistoryLock is used to make sure multiple goroutines don't fetch history for this room at the same time. + fetchHistoryLock *sync.Mutex `json:"-"` +} + +func (room *Room) LockHistory() { + if room.fetchHistoryLock == nil { + room.fetchHistoryLock = &sync.Mutex{} + } + room.fetchHistoryLock.Lock() +} + +func (room *Room) UnlockHistory() { + if room.fetchHistoryLock != nil { + room.fetchHistoryLock.Unlock() + } } // UpdateState updates the room's current state with the given Event. This will clobber events based @@ -211,7 +228,8 @@ func (room *Room) GetMember(userID string) *Member { // NewRoom creates a new Room with the given ID func NewRoom(roomID, owner string) *Room { return &Room{ - Room: gomatrix.NewRoom(roomID), - SessionUserID: owner, + Room: gomatrix.NewRoom(roomID), + fetchHistoryLock: &sync.Mutex{}, + SessionUserID: owner, } } diff --git a/ui/view-main.go b/ui/view-main.go index 974ab47..6f3689c 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -226,11 +226,7 @@ func (view *MainView) SwitchRoom(roomIndex int) { return } view.currentRoomIndex = roomIndex % len(view.roomIDs) - if !view.roomView.HasPage(view.CurrentRoomID()) { - debug.Print("Oh noes!", view.CurrentRoomID(), "has no page!") - } else { - view.roomView.SwitchToPage(view.CurrentRoomID()) - } + view.roomView.SwitchToPage(view.CurrentRoomID()) view.roomList.SetCurrentItem(roomIndex) view.gmx.App().SetFocus(view) view.parent.Render() @@ -344,10 +340,10 @@ func (view *MainView) LoadHistory(room string, initial bool) { batch := roomView.Room.PrevBatch lockTime := time.Now().Unix() + 1 - roomView.FetchHistoryLock.Lock() + roomView.Room.LockHistory() roomView.MessageView().LoadingMessages = true defer func() { - roomView.FetchHistoryLock.Unlock() + roomView.Room.UnlockHistory() roomView.MessageView().LoadingMessages = false }() diff --git a/ui/widget/room-view.go b/ui/widget/room-view.go index 69d5b29..a194054 100644 --- a/ui/widget/room-view.go +++ b/ui/widget/room-view.go @@ -19,7 +19,6 @@ package widget import ( "fmt" "strings" - "sync" "time" "github.com/gdamore/tcell" @@ -35,22 +34,21 @@ type RoomView struct { content *MessageView status *tview.TextView userList *tview.TextView + ulBorder *Border input *AdvancedInputField Room *rooms.Room - - FetchHistoryLock *sync.Mutex } func NewRoomView(room *rooms.Room) *RoomView { view := &RoomView{ - Box: tview.NewBox(), - topic: tview.NewTextView(), - content: NewMessageView(), - status: tview.NewTextView(), - userList: tview.NewTextView(), - input: NewAdvancedInputField(), - FetchHistoryLock: &sync.Mutex{}, - Room: room, + Box: tview.NewBox(), + topic: tview.NewTextView(), + content: NewMessageView(), + status: tview.NewTextView(), + userList: tview.NewTextView(), + ulBorder: NewBorder(), + input: NewAdvancedInputField(), + Room: room, } view.input. @@ -124,18 +122,14 @@ func (view *RoomView) Draw(screen tcell.Screen) { view.content.SetRect(x, y+1, width-30, height-3) view.status.SetRect(x, y+height-2, width, 1) view.userList.SetRect(x+width-29, y+1, 29, height-3) + view.ulBorder.SetRect(x+width-30, y+1, 1, height-3) view.input.SetRect(x, y+height-1, width, 1) view.topic.Draw(screen) view.content.Draw(screen) view.status.Draw(screen) view.input.Draw(screen) - - borderX := x + width - 30 - background := tcell.StyleDefault.Background(view.GetBackgroundColor()).Foreground(view.GetBorderColor()) - for borderY := y + 1; borderY < y+height-2; borderY++ { - screen.SetContent(borderX, borderY, tview.GraphicsVertBar, nil, background) - } + view.ulBorder.Draw(screen) view.userList.Draw(screen) }