Fix room list ordering
This commit is contained in:
		@@ -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,11 +80,16 @@ func (or *OrderedRoom) Draw(roomList *RoomList, screen mauview.Screen, x, y, lin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type TagRoomList struct {
 | 
					type TagRoomList struct {
 | 
				
			||||||
	mauview.NoopEventHandler
 | 
						mauview.NoopEventHandler
 | 
				
			||||||
	rooms       []*OrderedRoom
 | 
						// The list of rooms in the list, in reverse order
 | 
				
			||||||
	maxShown    int
 | 
						rooms []*OrderedRoom
 | 
				
			||||||
	name        string
 | 
						// Maximum number of rooms to show
 | 
				
			||||||
 | 
						maxShown int
 | 
				
			||||||
 | 
						// The internal name of this tag
 | 
				
			||||||
 | 
						name string
 | 
				
			||||||
 | 
						// The displayname of this tag
 | 
				
			||||||
	displayname string
 | 
						displayname string
 | 
				
			||||||
	parent      *RoomList
 | 
						// The parent RoomList instance
 | 
				
			||||||
 | 
						parent *RoomList
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewTagRoomList(parent *RoomList, name string, rooms ...*OrderedRoom) *TagRoomList {
 | 
					func NewTagRoomList(parent *RoomList, name string, rooms ...*OrderedRoom) *TagRoomList {
 | 
				
			||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user