Handle tag events
This commit is contained in:
parent
135fcbf284
commit
2a0145db88
@ -54,6 +54,8 @@ type MainView interface {
|
|||||||
SetRooms(roomIDs []string)
|
SetRooms(roomIDs []string)
|
||||||
SaveAllHistory()
|
SaveAllHistory()
|
||||||
|
|
||||||
|
UpdateTags(room *rooms.Room, newTags []rooms.RoomTag)
|
||||||
|
|
||||||
SetTyping(roomID string, users []string)
|
SetTyping(roomID string, users []string)
|
||||||
ParseEvent(roomView RoomView, evt *gomatrix.Event) Message
|
ParseEvent(roomView RoomView, evt *gomatrix.Event) Message
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ package matrix
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -255,9 +254,23 @@ func (c *Container) HandlePushRules(evt *gomatrix.Event) {
|
|||||||
|
|
||||||
// HandleTag is the event handler for the m.tag account data event.
|
// HandleTag is the event handler for the m.tag account data event.
|
||||||
func (c *Container) HandleTag(evt *gomatrix.Event) {
|
func (c *Container) HandleTag(evt *gomatrix.Event) {
|
||||||
debug.Print("Received updated tags for", evt.RoomID)
|
room := c.config.Session.GetRoom(evt.RoomID)
|
||||||
dat, _ := json.MarshalIndent(&evt.Content, "", " ")
|
|
||||||
debug.Print(string(dat))
|
tags, _ := evt.Content["tags"].(map[string]interface{})
|
||||||
|
newTags := make([]rooms.RoomTag, len(tags))
|
||||||
|
index := 0
|
||||||
|
for tag, infoifc := range tags {
|
||||||
|
info, _ := infoifc.(map[string]interface{})
|
||||||
|
order, _ := info["order"].(float64)
|
||||||
|
newTags[index] = rooms.RoomTag{
|
||||||
|
Tag: tag,
|
||||||
|
Order: order,
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
|
mainView := c.ui.MainView()
|
||||||
|
mainView.UpdateTags(room, newTags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
||||||
|
@ -34,6 +34,14 @@ const (
|
|||||||
MemberRoomName
|
MemberRoomName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RoomTag is a tag given to a specific room.
|
||||||
|
type RoomTag struct {
|
||||||
|
// The name of the tag.
|
||||||
|
Tag string
|
||||||
|
// The order of the tag. Smaller values are ordered higher.
|
||||||
|
Order float64
|
||||||
|
}
|
||||||
|
|
||||||
// Room represents a single Matrix room.
|
// Room represents a single Matrix room.
|
||||||
type Room struct {
|
type Room struct {
|
||||||
*gomatrix.Room
|
*gomatrix.Room
|
||||||
@ -53,7 +61,9 @@ type Room struct {
|
|||||||
// a notificationless message like bot notices.
|
// a notificationless message like bot notices.
|
||||||
HasNewMessages bool
|
HasNewMessages bool
|
||||||
|
|
||||||
Tags []string
|
// List of tags given to this room
|
||||||
|
RawTags []RoomTag
|
||||||
|
// Timestamp of previously received actual message.
|
||||||
LastReceivedMessage time.Time
|
LastReceivedMessage time.Time
|
||||||
|
|
||||||
// MXID -> Member cache calculated from membership events.
|
// MXID -> Member cache calculated from membership events.
|
||||||
@ -102,6 +112,13 @@ func (room *Room) MarkRead() {
|
|||||||
room.HasNewMessages = false
|
room.HasNewMessages = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (room *Room) Tags() []RoomTag {
|
||||||
|
if len(room.RawTags) == 0 {
|
||||||
|
return []RoomTag{{"", 0.5}}
|
||||||
|
}
|
||||||
|
return room.RawTags
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateState updates the room's current state with the given Event. This will clobber events based
|
// UpdateState updates the room's current state with the given Event. This will clobber events based
|
||||||
// on the type/state_key combination.
|
// on the type/state_key combination.
|
||||||
func (room *Room) UpdateState(event *gomatrix.Event) {
|
func (room *Room) UpdateState(event *gomatrix.Event) {
|
||||||
|
384
ui/room-list.go
384
ui/room-list.go
@ -18,7 +18,9 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/gomuks/matrix/rooms"
|
"maunium.net/go/gomuks/matrix/rooms"
|
||||||
@ -27,13 +29,21 @@ import (
|
|||||||
"maunium.net/go/tview"
|
"maunium.net/go/tview"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type roomListItem struct {
|
||||||
|
room *rooms.Room
|
||||||
|
priority float64
|
||||||
|
}
|
||||||
|
|
||||||
type RoomList struct {
|
type RoomList struct {
|
||||||
*tview.Box
|
*tview.Box
|
||||||
|
|
||||||
|
// The list of tags in display order.
|
||||||
|
tags []string
|
||||||
// The list of rooms, in reverse order.
|
// The list of rooms, in reverse order.
|
||||||
items []*rooms.Room
|
items map[string][]*rooms.Room
|
||||||
// The selected room.
|
// The selected room.
|
||||||
selected *rooms.Room
|
selected *rooms.Room
|
||||||
|
selectedTag string
|
||||||
|
|
||||||
// The item main text color.
|
// The item main text color.
|
||||||
mainTextColor tcell.Color
|
mainTextColor tcell.Color
|
||||||
@ -46,7 +56,7 @@ type RoomList struct {
|
|||||||
func NewRoomList() *RoomList {
|
func NewRoomList() *RoomList {
|
||||||
return &RoomList{
|
return &RoomList{
|
||||||
Box: tview.NewBox(),
|
Box: tview.NewBox(),
|
||||||
items: []*rooms.Room{},
|
items: make(map[string][]*rooms.Room),
|
||||||
|
|
||||||
mainTextColor: tcell.ColorWhite,
|
mainTextColor: tcell.ColorWhite,
|
||||||
selectedTextColor: tcell.ColorWhite,
|
selectedTextColor: tcell.ColorWhite,
|
||||||
@ -55,107 +65,248 @@ func NewRoomList() *RoomList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Contains(roomID string) bool {
|
func (list *RoomList) Contains(roomID string) bool {
|
||||||
for _, room := range list.items {
|
for _, roomList := range list.items {
|
||||||
if room.ID == roomID {
|
for _, room := range roomList {
|
||||||
return true
|
if room.ID == roomID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Add(room *rooms.Room) {
|
func (list *RoomList) Add(room *rooms.Room) {
|
||||||
list.items = append(list.items, nil)
|
for _, tag := range room.Tags() {
|
||||||
insertAt := len(list.items) - 1
|
list.AddToTag(tag.Tag, room)
|
||||||
for i := 0; i < len(list.items)-1; i++ {
|
}
|
||||||
if list.items[i].LastReceivedMessage.After(room.LastReceivedMessage) {
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) CheckTag(tag string) {
|
||||||
|
index := list.IndexTag(tag)
|
||||||
|
|
||||||
|
items, ok := list.items[tag]
|
||||||
|
|
||||||
|
if len(items) == 0 {
|
||||||
|
delete(list.items, tag)
|
||||||
|
ok = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok && index == -1 {
|
||||||
|
list.tags = append(list.tags, tag)
|
||||||
|
} else if index != -1 {
|
||||||
|
list.tags = append(list.tags[0:index], list.tags[index+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) AddToTag(tag string, room *rooms.Room) {
|
||||||
|
items, ok := list.items[tag]
|
||||||
|
if !ok {
|
||||||
|
list.items[tag] = []*rooms.Room{room}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add space for new item.
|
||||||
|
items = append(items, nil)
|
||||||
|
// The default insert index is the newly added slot.
|
||||||
|
// That index will be used if all other rooms in the list have the same LastReceivedMessage timestamp.
|
||||||
|
insertAt := len(items) - 1
|
||||||
|
// Find the spot where the new room should be put according to the last received message timestamps.
|
||||||
|
for i := 0; i < len(items)-1; i++ {
|
||||||
|
if items[i].LastReceivedMessage.After(room.LastReceivedMessage) {
|
||||||
insertAt = i
|
insertAt = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := len(list.items) - 1; i > insertAt; i-- {
|
// Move newer rooms forward in the array.
|
||||||
list.items[i] = list.items[i-1]
|
for i := len(items) - 1; i > insertAt; i-- {
|
||||||
|
items[i] = items[i-1]
|
||||||
}
|
}
|
||||||
list.items[insertAt] = room
|
// Insert room.
|
||||||
|
items[insertAt] = room
|
||||||
|
|
||||||
|
list.items[tag] = items
|
||||||
|
list.CheckTag(tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Remove(room *rooms.Room) {
|
func (list *RoomList) Remove(room *rooms.Room) {
|
||||||
index := list.Index(room)
|
for _, tag := range room.Tags() {
|
||||||
if index != -1 {
|
list.RemoveFromTag(tag.Tag, room)
|
||||||
list.items = append(list.items[0:index], list.items[index+1:]...)
|
}
|
||||||
if room == list.selected {
|
}
|
||||||
if index > 0 {
|
|
||||||
list.selected = list.items[index-1]
|
func (list *RoomList) RemoveFromTag(tag string, room *rooms.Room) {
|
||||||
} else if len(list.items) > 0 {
|
items, ok := list.items[tag]
|
||||||
list.selected = list.items[0]
|
if !ok {
|
||||||
} else {
|
return
|
||||||
list.selected = nil
|
}
|
||||||
|
|
||||||
|
index := list.indexInTag(tag, room)
|
||||||
|
if index == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
items = append(items[0:index], items[index+1:]...)
|
||||||
|
|
||||||
|
if len(items) == 0 {
|
||||||
|
delete(list.items, tag)
|
||||||
|
} else {
|
||||||
|
list.items[tag] = items
|
||||||
|
}
|
||||||
|
|
||||||
|
if room == list.selected {
|
||||||
|
// Room is currently selected, move selection to another room.
|
||||||
|
if index > 0 {
|
||||||
|
list.selected = items[index-1]
|
||||||
|
} else if len(items) > 0 {
|
||||||
|
list.selected = items[0]
|
||||||
|
} else if len(list.items) > 0 {
|
||||||
|
for _, tag := range list.tags {
|
||||||
|
moreItems := list.items[tag]
|
||||||
|
if len(moreItems) > 0 {
|
||||||
|
list.selected = moreItems[0]
|
||||||
|
list.selectedTag = tag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
list.selected = nil
|
||||||
|
list.selectedTag = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
list.CheckTag(tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Bump(room *rooms.Room) {
|
func (list *RoomList) Bump(room *rooms.Room) {
|
||||||
|
for _, tag := range room.Tags() {
|
||||||
|
list.bumpInTag(tag.Tag, room)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) bumpInTag(tag string, room *rooms.Room) {
|
||||||
|
items, ok := list.items[tag]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
for i := 0; i < len(list.items)-1; i++ {
|
for i := 0; i < len(items)-1; i++ {
|
||||||
if list.items[i] == room {
|
if items[i] == room {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
if found {
|
if found {
|
||||||
list.items[i] = list.items[i+1]
|
items[i] = items[i+1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list.items[len(list.items)-1] = room
|
if found {
|
||||||
room.LastReceivedMessage = time.Now()
|
items[len(items)-1] = room
|
||||||
|
room.LastReceivedMessage = time.Now()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Clear() {
|
func (list *RoomList) Clear() {
|
||||||
list.items = []*rooms.Room{}
|
list.items = make(map[string][]*rooms.Room)
|
||||||
list.selected = nil
|
list.selected = nil
|
||||||
|
list.selectedTag = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) SetSelected(room *rooms.Room) {
|
func (list *RoomList) SetSelected(tag string, room *rooms.Room) {
|
||||||
list.selected = room
|
list.selected = room
|
||||||
|
list.selectedTag = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) HasSelected() bool {
|
func (list *RoomList) HasSelected() bool {
|
||||||
return list.selected != nil
|
return list.selected != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Selected() *rooms.Room {
|
func (list *RoomList) Selected() (string, *rooms.Room) {
|
||||||
|
return list.selectedTag, list.selected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) SelectedRoom() *rooms.Room {
|
||||||
return list.selected
|
return list.selected
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Previous() *rooms.Room {
|
func (list *RoomList) First() (string, *rooms.Room) {
|
||||||
if len(list.items) == 0 {
|
for _, tag := range list.tags {
|
||||||
return nil
|
items := list.items[tag]
|
||||||
} else if list.selected == nil {
|
if len(items) > 0 {
|
||||||
return list.items[0]
|
return tag, items[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return "", nil
|
||||||
index := list.Index(list.selected)
|
|
||||||
if index == len(list.items)-1 {
|
|
||||||
return list.items[0]
|
|
||||||
}
|
|
||||||
return list.items[index+1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Next() *rooms.Room {
|
func (list *RoomList) Last() (string, *rooms.Room) {
|
||||||
|
for tagIndex := len(list.tags) - 1; tagIndex >= 0; tagIndex-- {
|
||||||
|
tag := list.tags[tagIndex]
|
||||||
|
items := list.items[tag]
|
||||||
|
if len(items) > 0 {
|
||||||
|
return tag, items[len(items)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) IndexTag(tag string) int {
|
||||||
|
for index, entry := range list.tags {
|
||||||
|
if tag == entry {
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) Previous() (string, *rooms.Room) {
|
||||||
if len(list.items) == 0 {
|
if len(list.items) == 0 {
|
||||||
return nil
|
return "", nil
|
||||||
} else if list.selected == nil {
|
} else if list.selected == nil {
|
||||||
return list.items[0]
|
return list.First()
|
||||||
}
|
}
|
||||||
|
|
||||||
index := list.Index(list.selected)
|
items := list.items[list.selectedTag]
|
||||||
|
index := list.indexInTag(list.selectedTag, list.selected)
|
||||||
|
if index == len(items)-1 {
|
||||||
|
tagIndex := list.IndexTag(list.selectedTag)
|
||||||
|
tagIndex++
|
||||||
|
for ; tagIndex < len(list.tags); tagIndex++ {
|
||||||
|
nextTag := list.tags[tagIndex]
|
||||||
|
nextTagItems := list.items[nextTag]
|
||||||
|
if len(nextTagItems) > 0 {
|
||||||
|
return nextTag, nextTagItems[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list.First()
|
||||||
|
}
|
||||||
|
return list.selectedTag, items[index+1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (list *RoomList) Next() (string, *rooms.Room) {
|
||||||
|
if len(list.items) == 0 {
|
||||||
|
return "", nil
|
||||||
|
} else if list.selected == nil {
|
||||||
|
return list.First()
|
||||||
|
}
|
||||||
|
|
||||||
|
items := list.items[list.selectedTag]
|
||||||
|
index := list.indexInTag(list.selectedTag, list.selected)
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
return list.items[len(list.items)-1]
|
tagIndex := list.IndexTag(list.selectedTag)
|
||||||
|
tagIndex--
|
||||||
|
for ; tagIndex >= 0; tagIndex-- {
|
||||||
|
prevTag := list.tags[tagIndex]
|
||||||
|
prevTagItems := list.items[prevTag]
|
||||||
|
if len(prevTagItems) > 0 {
|
||||||
|
return prevTag, prevTagItems[len(prevTagItems)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list.Last()
|
||||||
}
|
}
|
||||||
return list.items[index-1]
|
return list.selectedTag, items[index-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Index(room *rooms.Room) int {
|
func (list *RoomList) indexInTag(tag string, room *rooms.Room) int {
|
||||||
roomIndex := -1
|
roomIndex := -1
|
||||||
for index, entry := range list.items {
|
items := list.items[tag]
|
||||||
|
for index, entry := range items {
|
||||||
if entry == room {
|
if entry == room {
|
||||||
roomIndex = index
|
roomIndex = index
|
||||||
break
|
break
|
||||||
@ -164,11 +315,46 @@ func (list *RoomList) Index(room *rooms.Room) int {
|
|||||||
return roomIndex
|
return roomIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (list *RoomList) Get(n int) *rooms.Room {
|
func (list *RoomList) Get(n int) (string, *rooms.Room) {
|
||||||
if n < 0 || n > len(list.items)-1 {
|
if n < 0 {
|
||||||
return nil
|
return "", nil
|
||||||
|
}
|
||||||
|
for _, tag := range list.tags {
|
||||||
|
// Tag header
|
||||||
|
n--
|
||||||
|
|
||||||
|
items := list.items[tag]
|
||||||
|
if n < 0 {
|
||||||
|
return "", nil
|
||||||
|
} else if n < len(items) {
|
||||||
|
return tag, items[len(items)-1-n]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag items
|
||||||
|
n -= len(items)
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var nsRegex = regexp.MustCompile("^[a-z]\\.[a-z](?:\\.[a-z])*$")
|
||||||
|
|
||||||
|
func (list *RoomList) GetTagDisplayName(tag string) string {
|
||||||
|
switch {
|
||||||
|
case len(tag) == 0:
|
||||||
|
return "Rooms"
|
||||||
|
case tag == "m.favourite":
|
||||||
|
return "Favorites"
|
||||||
|
case tag == "m.lowpriority":
|
||||||
|
return "Low Priority"
|
||||||
|
case strings.HasPrefix(tag, "m."):
|
||||||
|
return strings.Title(strings.Replace(tag[len("m."):], "_", " ", -1))
|
||||||
|
case strings.HasPrefix(tag, "u."):
|
||||||
|
return tag[len("u."):]
|
||||||
|
case !nsRegex.MatchString(tag):
|
||||||
|
return tag
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
return list.items[len(list.items)-1-n]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
@ -179,54 +365,60 @@ func (list *RoomList) Draw(screen tcell.Screen) {
|
|||||||
bottomLimit := y + height
|
bottomLimit := y + height
|
||||||
|
|
||||||
var offset int
|
var offset int
|
||||||
|
/* TODO fix offset
|
||||||
currentItemIndex := list.Index(list.selected)
|
currentItemIndex := list.Index(list.selected)
|
||||||
if currentItemIndex >= height {
|
if currentItemIndex >= height {
|
||||||
offset = currentItemIndex + 1 - height
|
offset = currentItemIndex + 1 - height
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Draw the list items.
|
// Draw the list items.
|
||||||
for i := len(list.items) - 1; i >= 0; i-- {
|
for _, tag := range list.tags {
|
||||||
item := list.items[i]
|
items := list.items[tag]
|
||||||
index := len(list.items) - 1 - i
|
widget.WriteLine(screen, tview.AlignLeft, list.GetTagDisplayName(tag), x, y, width, tcell.StyleDefault.Underline(true).Bold(true))
|
||||||
|
|
||||||
if index < offset {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if y >= bottomLimit {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
text := item.GetTitle()
|
|
||||||
|
|
||||||
lineWidth := width
|
|
||||||
|
|
||||||
style := tcell.StyleDefault.Foreground(list.mainTextColor)
|
|
||||||
if item == list.selected {
|
|
||||||
style = style.Foreground(list.selectedTextColor).Background(list.selectedBackgroundColor)
|
|
||||||
}
|
|
||||||
if item.HasNewMessages {
|
|
||||||
style = style.Bold(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.UnreadMessages > 0 {
|
|
||||||
unreadMessageCount := "99+"
|
|
||||||
if item.UnreadMessages < 100 {
|
|
||||||
unreadMessageCount = strconv.Itoa(item.UnreadMessages)
|
|
||||||
}
|
|
||||||
if item.Highlighted {
|
|
||||||
unreadMessageCount += "!"
|
|
||||||
}
|
|
||||||
unreadMessageCount = fmt.Sprintf("(%s)", unreadMessageCount)
|
|
||||||
widget.WriteLine(screen, tview.AlignRight, unreadMessageCount, x+lineWidth-6, y, 6, style)
|
|
||||||
lineWidth -= len(unreadMessageCount) + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.WriteLine(screen, tview.AlignLeft, text, x, y, lineWidth, style)
|
|
||||||
|
|
||||||
y++
|
y++
|
||||||
if y >= bottomLimit {
|
for i := len(items) - 1; i >= 0; i-- {
|
||||||
break
|
item := items[i]
|
||||||
|
index := len(items) - 1 - i
|
||||||
|
|
||||||
|
if index < offset {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if y >= bottomLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
text := item.GetTitle()
|
||||||
|
|
||||||
|
lineWidth := width
|
||||||
|
|
||||||
|
style := tcell.StyleDefault.Foreground(list.mainTextColor)
|
||||||
|
if tag == list.selectedTag && item == list.selected {
|
||||||
|
style = style.Foreground(list.selectedTextColor).Background(list.selectedBackgroundColor)
|
||||||
|
}
|
||||||
|
if item.HasNewMessages {
|
||||||
|
style = style.Bold(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.UnreadMessages > 0 {
|
||||||
|
unreadMessageCount := "99+"
|
||||||
|
if item.UnreadMessages < 100 {
|
||||||
|
unreadMessageCount = strconv.Itoa(item.UnreadMessages)
|
||||||
|
}
|
||||||
|
if item.Highlighted {
|
||||||
|
unreadMessageCount += "!"
|
||||||
|
}
|
||||||
|
unreadMessageCount = fmt.Sprintf("(%s)", unreadMessageCount)
|
||||||
|
widget.WriteLine(screen, tview.AlignRight, unreadMessageCount, x+lineWidth-6, y, 6, style)
|
||||||
|
lineWidth -= len(unreadMessageCount) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.WriteLine(screen, tview.AlignLeft, text, x, y, lineWidth, style)
|
||||||
|
|
||||||
|
y++
|
||||||
|
if y >= bottomLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) SwitchRoom(room *rooms.Room) {
|
func (view *MainView) SwitchRoom(tag string, room *rooms.Room) {
|
||||||
if room == nil {
|
if room == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -258,13 +258,13 @@ func (view *MainView) SwitchRoom(room *rooms.Room) {
|
|||||||
if roomView.MessageView().ScrollOffset == 0 {
|
if roomView.MessageView().ScrollOffset == 0 {
|
||||||
roomView.Room.MarkRead()
|
roomView.Room.MarkRead()
|
||||||
}
|
}
|
||||||
view.roomList.SetSelected(room)
|
view.roomList.SetSelected(tag, room)
|
||||||
view.parent.app.SetFocus(view)
|
view.parent.app.SetFocus(view)
|
||||||
view.parent.Render()
|
view.parent.Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) Focus(delegate func(p tview.Primitive)) {
|
func (view *MainView) Focus(delegate func(p tview.Primitive)) {
|
||||||
room := view.roomList.Selected()
|
room := view.roomList.SelectedRoom()
|
||||||
if room != nil {
|
if room != nil {
|
||||||
roomView, ok := view.rooms[room.ID]
|
roomView, ok := view.rooms[room.ID]
|
||||||
if ok {
|
if ok {
|
||||||
@ -283,7 +283,6 @@ func (view *MainView) SaveAllHistory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) addRoomPage(room *rooms.Room) {
|
func (view *MainView) addRoomPage(room *rooms.Room) {
|
||||||
|
|
||||||
if !view.roomView.HasPage(room.ID) {
|
if !view.roomView.HasPage(room.ID) {
|
||||||
roomView := NewRoomView(view, room).
|
roomView := NewRoomView(view, room).
|
||||||
SetInputSubmitFunc(view.InputSubmit).
|
SetInputSubmitFunc(view.InputSubmit).
|
||||||
@ -304,7 +303,13 @@ func (view *MainView) addRoomPage(room *rooms.Room) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) GetRoom(roomID string) ifc.RoomView {
|
func (view *MainView) GetRoom(roomID string) ifc.RoomView {
|
||||||
return view.rooms[roomID]
|
room, ok := view.rooms[roomID]
|
||||||
|
if !ok {
|
||||||
|
view.AddRoom(roomID)
|
||||||
|
room, _ := view.rooms[roomID]
|
||||||
|
return room
|
||||||
|
}
|
||||||
|
return room
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) AddRoom(roomID string) {
|
func (view *MainView) AddRoom(roomID string) {
|
||||||
@ -335,14 +340,46 @@ func (view *MainView) SetRooms(roomIDs []string) {
|
|||||||
view.roomList.Clear()
|
view.roomList.Clear()
|
||||||
view.roomView.Clear()
|
view.roomView.Clear()
|
||||||
view.rooms = make(map[string]*RoomView)
|
view.rooms = make(map[string]*RoomView)
|
||||||
for index, roomID := range roomIDs {
|
for _, roomID := range roomIDs {
|
||||||
room := view.matrix.GetRoom(roomID)
|
room := view.matrix.GetRoom(roomID)
|
||||||
view.roomList.Add(room)
|
view.roomList.Add(room)
|
||||||
view.addRoomPage(room)
|
view.addRoomPage(room)
|
||||||
if index == len(roomIDs)-1 {
|
}
|
||||||
view.SwitchRoom(room)
|
view.SwitchRoom(view.roomList.First())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (view *MainView) UpdateTags(room *rooms.Room, newTags []rooms.RoomTag) {
|
||||||
|
if len(newTags) == 0 {
|
||||||
|
for _, tag := range room.RawTags {
|
||||||
|
view.roomList.RemoveFromTag(tag.Tag, room)
|
||||||
|
}
|
||||||
|
view.roomList.AddToTag("", room)
|
||||||
|
} else if len(room.RawTags) == 0 {
|
||||||
|
view.roomList.RemoveFromTag("", room)
|
||||||
|
for _, tag := range newTags {
|
||||||
|
view.roomList.AddToTag(tag.Tag, room)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NewTags:
|
||||||
|
for _, newTag := range newTags {
|
||||||
|
for _, oldTag := range room.RawTags {
|
||||||
|
if newTag.Tag == oldTag.Tag {
|
||||||
|
continue NewTags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.roomList.AddToTag(newTag.Tag, room)
|
||||||
|
}
|
||||||
|
OldTags:
|
||||||
|
for _, oldTag := range room.RawTags {
|
||||||
|
for _, newTag := range newTags {
|
||||||
|
if newTag.Tag == oldTag.Tag {
|
||||||
|
continue OldTags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.roomList.RemoveFromTag(oldTag.Tag, room)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
room.RawTags = newTags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) SetTyping(room string, users []string) {
|
func (view *MainView) SetTyping(room string, users []string) {
|
||||||
@ -362,7 +399,7 @@ func sendNotification(room *rooms.Room, sender, text string, critical, sound boo
|
|||||||
|
|
||||||
func (view *MainView) NotifyMessage(room *rooms.Room, message ifc.Message, should pushrules.PushActionArrayShould) {
|
func (view *MainView) NotifyMessage(room *rooms.Room, message ifc.Message, should pushrules.PushActionArrayShould) {
|
||||||
// Whether or not the room where the message came is the currently shown room.
|
// Whether or not the room where the message came is the currently shown room.
|
||||||
isCurrent := room == view.roomList.Selected()
|
isCurrent := room == view.roomList.SelectedRoom()
|
||||||
// Whether or not the terminal window is focused.
|
// Whether or not the terminal window is focused.
|
||||||
isFocused := view.lastFocusTime.Add(30 * time.Second).Before(time.Now())
|
isFocused := view.lastFocusTime.Add(30 * time.Second).Before(time.Now())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user