Fix room list ordering
This commit is contained in:
parent
3c21281ada
commit
9aa33d9b48
@ -152,7 +152,7 @@ func (list *RoomList) AddToTag(tag rooms.RoomTag, room *rooms.Room) {
|
|||||||
defer list.Unlock()
|
defer list.Unlock()
|
||||||
trl, ok := list.items[tag.Tag]
|
trl, ok := list.items[tag.Tag]
|
||||||
if !ok {
|
if !ok {
|
||||||
list.items[tag.Tag] = NewTagRoomList(list, tag.Tag, NewDefaultOrderedRoom(room))
|
list.items[tag.Tag] = NewTagRoomList(list, tag.Tag, NewOrderedRoom(tag.Order, room))
|
||||||
} else {
|
} else {
|
||||||
trl.Insert(tag.Order, room)
|
trl.Insert(tag.Order, room)
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ package ui
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"maunium.net/go/gomuks/debug"
|
"maunium.net/go/gomuks/debug"
|
||||||
"maunium.net/go/mauview"
|
"maunium.net/go/mauview"
|
||||||
@ -32,13 +32,17 @@ import (
|
|||||||
|
|
||||||
type OrderedRoom struct {
|
type OrderedRoom struct {
|
||||||
*rooms.Room
|
*rooms.Room
|
||||||
order json.Number
|
order float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrderedRoom(order json.Number, room *rooms.Room) *OrderedRoom {
|
func NewOrderedRoom(order json.Number, room *rooms.Room) *OrderedRoom {
|
||||||
|
numOrder, err := order.Float64()
|
||||||
|
if err != nil {
|
||||||
|
numOrder = 0.5
|
||||||
|
}
|
||||||
return &OrderedRoom{
|
return &OrderedRoom{
|
||||||
Room: room,
|
Room: room,
|
||||||
order: order,
|
order: numOrder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,10 +80,15 @@ func (or *OrderedRoom) Draw(roomList *RoomList, screen mauview.Screen, x, y, lin
|
|||||||
|
|
||||||
type TagRoomList struct {
|
type TagRoomList struct {
|
||||||
mauview.NoopEventHandler
|
mauview.NoopEventHandler
|
||||||
|
// The list of rooms in the list, in reverse order
|
||||||
rooms []*OrderedRoom
|
rooms []*OrderedRoom
|
||||||
|
// Maximum number of rooms to show
|
||||||
maxShown int
|
maxShown int
|
||||||
|
// The internal name of this tag
|
||||||
name string
|
name string
|
||||||
|
// The displayname of this tag
|
||||||
displayname string
|
displayname string
|
||||||
|
// The parent RoomList instance
|
||||||
parent *RoomList
|
parent *RoomList
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +161,16 @@ func (trl *TagRoomList) HasVisibleRooms() bool {
|
|||||||
return !trl.IsEmpty() && trl.maxShown > 0
|
return !trl.IsEmpty() && trl.maxShown > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldBeBefore returns if the first room should be after the second room in the room list.
|
const equalityThreshold = 1e-6
|
||||||
|
|
||||||
|
func almostEqual(a, b float64) bool {
|
||||||
|
return math.Abs(a-b) <= equalityThreshold
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldBeAfter returns if the first room should be after the second room in the room list.
|
||||||
// The manual order and last received message timestamp are considered.
|
// The manual order and last received message timestamp are considered.
|
||||||
func (trl *TagRoomList) ShouldBeAfter(room1 *OrderedRoom, room2 *OrderedRoom) bool {
|
func (trl *TagRoomList) ShouldBeAfter(room1 *OrderedRoom, room2 *OrderedRoom) bool {
|
||||||
orderComp := strings.Compare(string(room1.order), string(room2.order))
|
return room1.order > room2.order || (almostEqual(room1.order, room2.order) && room2.LastReceivedMessage.After(room1.LastReceivedMessage))
|
||||||
return orderComp == 1 || (orderComp == 0 && room2.LastReceivedMessage.After(room1.LastReceivedMessage))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (trl *TagRoomList) Insert(order json.Number, mxRoom *rooms.Room) {
|
func (trl *TagRoomList) Insert(order json.Number, mxRoom *rooms.Room) {
|
||||||
@ -165,42 +179,39 @@ func (trl *TagRoomList) Insert(order json.Number, mxRoom *rooms.Room) {
|
|||||||
// That index will be used if all other rooms in the list have the same LastReceivedMessage timestamp.
|
// That index will be used if all other rooms in the list have the same LastReceivedMessage timestamp.
|
||||||
insertAt := len(trl.rooms)
|
insertAt := len(trl.rooms)
|
||||||
// Find the spot where the new room should be put according to the last received message timestamps.
|
// Find the spot where the new room should be put according to the last received message timestamps.
|
||||||
for i := 0; i < len(trl.rooms)-1; i++ {
|
for i := 0; i < len(trl.rooms); i++ {
|
||||||
if trl.rooms[i].Room == mxRoom {
|
if trl.rooms[i].Room == mxRoom {
|
||||||
debug.Printf("Warning: tried to re-insert room %s into tag %s", mxRoom.ID, trl.name)
|
debug.Printf("Warning: tried to re-insert room %s into tag %s", mxRoom.ID, trl.name)
|
||||||
return
|
return
|
||||||
} else if trl.ShouldBeAfter(room, trl.rooms[i]) {
|
} else if trl.ShouldBeAfter(room, trl.rooms[i]) {
|
||||||
insertAt = i
|
insertAt = i
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trl.rooms = append(trl.rooms, nil)
|
trl.rooms = append(trl.rooms, nil)
|
||||||
// Move newer rooms forward in the array.
|
copy(trl.rooms[insertAt+1:], trl.rooms[insertAt:])
|
||||||
for i := len(trl.rooms) - 1; i > insertAt; i-- {
|
|
||||||
trl.rooms[i] = trl.rooms[i-1]
|
|
||||||
}
|
|
||||||
// Insert room.
|
|
||||||
trl.rooms[insertAt] = room
|
trl.rooms[insertAt] = room
|
||||||
}
|
}
|
||||||
|
|
||||||
func (trl *TagRoomList) Bump(mxRoom *rooms.Room) {
|
func (trl *TagRoomList) Bump(mxRoom *rooms.Room) {
|
||||||
var found *OrderedRoom
|
var roomBeingBumped *OrderedRoom
|
||||||
for i := 0; i < len(trl.rooms); i++ {
|
for i := 0; i < len(trl.rooms); i++ {
|
||||||
currentRoom := trl.rooms[i]
|
currentIndexRoom := trl.rooms[i]
|
||||||
if found != nil {
|
if roomBeingBumped != nil {
|
||||||
if trl.ShouldBeAfter(found, trl.rooms[i]) {
|
if trl.ShouldBeAfter(roomBeingBumped, currentIndexRoom) {
|
||||||
// This room should be after the room being bumped, so insert the
|
// This room should be after the room being bumped, so insert the
|
||||||
// room being bumped here and return
|
// room being bumped here and return
|
||||||
trl.rooms[i-1] = found
|
trl.rooms[i-1] = roomBeingBumped
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Move older rooms back in the array
|
// Move older rooms back in the array
|
||||||
trl.rooms[i-1] = currentRoom
|
trl.rooms[i-1] = currentIndexRoom
|
||||||
} else if currentRoom.Room == mxRoom {
|
} else if currentIndexRoom.Room == mxRoom {
|
||||||
found = currentRoom
|
roomBeingBumped = currentIndexRoom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the room being bumped should be first in the list, it won't be inserted during the loop.
|
// If the room being bumped should be first in the list, it won't be inserted during the loop.
|
||||||
trl.rooms[len(trl.rooms)-1] = found
|
trl.rooms[len(trl.rooms)-1] = roomBeingBumped
|
||||||
}
|
}
|
||||||
|
|
||||||
func (trl *TagRoomList) Remove(room *rooms.Room) {
|
func (trl *TagRoomList) Remove(room *rooms.Room) {
|
||||||
|
Loading…
Reference in New Issue
Block a user