Fix user list
This commit is contained in:
		
							
								
								
									
										99
									
								
								ui/member-list.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								ui/member-list.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
// gomuks - A terminal Matrix client written in Go.
 | 
			
		||||
// Copyright (C) 2019 Tulir Asokan
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
// the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package ui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/mattn/go-runewidth"
 | 
			
		||||
 | 
			
		||||
	"maunium.net/go/gomuks/debug"
 | 
			
		||||
	"maunium.net/go/gomuks/ui/widget"
 | 
			
		||||
	"maunium.net/go/mautrix"
 | 
			
		||||
	"maunium.net/go/mauview"
 | 
			
		||||
	"maunium.net/go/tcell"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MemberList struct {
 | 
			
		||||
	list roomMemberList
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMemberList() *MemberList {
 | 
			
		||||
	return &MemberList{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type memberListItem struct {
 | 
			
		||||
	mautrix.Member
 | 
			
		||||
	PowerLevel int
 | 
			
		||||
	UserID     string
 | 
			
		||||
	Color      tcell.Color
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type roomMemberList []*memberListItem
 | 
			
		||||
 | 
			
		||||
func (rml roomMemberList) Len() int {
 | 
			
		||||
	return len(rml)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rml roomMemberList) lessMembership(i, j int) bool {
 | 
			
		||||
	return rml[j].Membership == "invite" && rml[i].Membership == "join"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rml roomMemberList) Less(i, j int) bool {
 | 
			
		||||
	return rml.lessMembership(i, j) ||
 | 
			
		||||
		rml[i].PowerLevel > rml[j].PowerLevel ||
 | 
			
		||||
		strings.Compare(rml[i].Displayname, rml[j].Displayname) < 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rml roomMemberList) Swap(i, j int) {
 | 
			
		||||
	rml[i], rml[j] = rml[j], rml[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ml *MemberList) Update(data map[string]*mautrix.Member, levels *mautrix.PowerLevels) *MemberList {
 | 
			
		||||
	ml.list = make(roomMemberList, len(data))
 | 
			
		||||
	i := 0
 | 
			
		||||
	debug.Print(levels)
 | 
			
		||||
	for userID, member := range data {
 | 
			
		||||
		ml.list[i] = &memberListItem{
 | 
			
		||||
			Member:     *member,
 | 
			
		||||
			UserID:     userID,
 | 
			
		||||
			PowerLevel: levels.GetUserLevel(userID),
 | 
			
		||||
			Color:      widget.GetHashColor(userID),
 | 
			
		||||
		}
 | 
			
		||||
		i++
 | 
			
		||||
	}
 | 
			
		||||
	sort.Sort(ml.list)
 | 
			
		||||
	return ml
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ml *MemberList) Draw(screen mauview.Screen) {
 | 
			
		||||
	width, _ := screen.Size()
 | 
			
		||||
	for y, member := range ml.list {
 | 
			
		||||
		if member.Membership == "invite" {
 | 
			
		||||
			widget.WriteLineSimpleColor(screen, member.Displayname, 1, y, member.Color)
 | 
			
		||||
			screen.SetCell(0, y, tcell.StyleDefault, '(')
 | 
			
		||||
			if sw := runewidth.StringWidth(member.Displayname); sw < width {
 | 
			
		||||
				screen.SetCell(sw+1, y, tcell.StyleDefault, ')')
 | 
			
		||||
			} else {
 | 
			
		||||
				screen.SetCell(width-1, y, tcell.StyleDefault, ')')
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			widget.WriteLineSimpleColor(screen, member.Displayname, 0, y, member.Color)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -45,7 +45,7 @@ type RoomView struct {
 | 
			
		||||
	topic    *mauview.TextView
 | 
			
		||||
	content  *MessageView
 | 
			
		||||
	status   *mauview.TextField
 | 
			
		||||
	userList *mauview.TextView
 | 
			
		||||
	userList *MemberList
 | 
			
		||||
	ulBorder *widget.Border
 | 
			
		||||
	input    *mauview.InputArea
 | 
			
		||||
	Room     *rooms.Room
 | 
			
		||||
@@ -75,7 +75,7 @@ func NewRoomView(parent *MainView, room *rooms.Room) *RoomView {
 | 
			
		||||
	view := &RoomView{
 | 
			
		||||
		topic:    mauview.NewTextView(),
 | 
			
		||||
		status:   mauview.NewTextField(),
 | 
			
		||||
		userList: mauview.NewTextView(),
 | 
			
		||||
		userList: NewMemberList(),
 | 
			
		||||
		ulBorder: widget.NewBorder(),
 | 
			
		||||
		input:    mauview.NewInputArea(),
 | 
			
		||||
		Room:     room,
 | 
			
		||||
@@ -105,10 +105,6 @@ func NewRoomView(parent *MainView, room *rooms.Room) *RoomView {
 | 
			
		||||
 | 
			
		||||
	view.status.SetBackgroundColor(tcell.ColorDimGray)
 | 
			
		||||
 | 
			
		||||
	view.userList.
 | 
			
		||||
		SetDynamicColors(true).
 | 
			
		||||
		SetWrap(false)
 | 
			
		||||
 | 
			
		||||
	return view
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -418,22 +414,11 @@ func (view *RoomView) MxRoom() *rooms.Room {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) UpdateUserList() {
 | 
			
		||||
	var joined strings.Builder
 | 
			
		||||
	var invited strings.Builder
 | 
			
		||||
	for userID, user := range view.Room.GetMembers() {
 | 
			
		||||
		if user.Membership == "join" {
 | 
			
		||||
			joined.WriteString(widget.AddColor(user.Displayname, widget.GetHashColorName(userID)))
 | 
			
		||||
			joined.WriteRune('\n')
 | 
			
		||||
		} else if user.Membership == "invite" {
 | 
			
		||||
			invited.WriteString(widget.AddColor(user.Displayname, widget.GetHashColorName(userID)))
 | 
			
		||||
			invited.WriteRune('\n')
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	view.userList.Clear()
 | 
			
		||||
	fmt.Fprintf(view.userList, "%s\n", joined.String())
 | 
			
		||||
	if invited.Len() > 0 {
 | 
			
		||||
		fmt.Fprintf(view.userList, "\nInvited:\n%s", invited.String())
 | 
			
		||||
	pls := &mautrix.PowerLevels{}
 | 
			
		||||
	if plEvent := view.Room.GetStateEvent(mautrix.StatePowerLevels, ""); plEvent != nil {
 | 
			
		||||
		pls = plEvent.Content.GetPowerLevels()
 | 
			
		||||
	}
 | 
			
		||||
	view.userList.Update(view.Room.GetMembers(), pls)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) AddServiceMessage(text string) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user