aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-04-23 22:49:17 +0300
committerTulir Asokan <tulir@maunium.net>2018-04-24 02:13:43 +0300
commit1e8705319a2bc6461d8768273aac16df4b6df4be (patch)
tree2009edc21f527d62c501b320fffc771e1eb31876
parent16406d6c91acf322463b64d03a49af6aebc02834 (diff)
Organize room list by last received message (ref #11)
-rw-r--r--interface/ui.go1
-rw-r--r--lib/open/open_windows.go2
-rw-r--r--ui/room-list.go110
-rw-r--r--ui/view-main.go120
4 files changed, 137 insertions, 96 deletions
diff --git a/interface/ui.go b/interface/ui.go
index 83fa7da..ec85b0f 100644
--- a/interface/ui.go
+++ b/interface/ui.go
@@ -49,7 +49,6 @@ type GomuksUI interface {
type MainView interface {
GetRoom(roomID string) RoomView
- HasRoom(roomID string) bool
AddRoom(roomID string)
RemoveRoom(roomID string)
SetRooms(roomIDs []string)
diff --git a/lib/open/open_windows.go b/lib/open/open_windows.go
index aced662..374ad21 100644
--- a/lib/open/open_windows.go
+++ b/lib/open/open_windows.go
@@ -17,7 +17,9 @@
package open
import (
+ "os"
"os/exec"
+ "path/filepath"
)
const FileProtocolHandler = "url.dll,FileProtocolHandler"
diff --git a/ui/room-list.go b/ui/room-list.go
index 1162ad5..7637d4f 100644
--- a/ui/room-list.go
+++ b/ui/room-list.go
@@ -29,7 +29,6 @@ import (
type RoomList struct {
*tview.Box
- indices map[*rooms.Room]int
items []*rooms.Room
selected *rooms.Room
@@ -43,9 +42,8 @@ type RoomList struct {
func NewRoomList() *RoomList {
return &RoomList{
- Box: tview.NewBox(),
- indices: make(map[*rooms.Room]int),
- items: []*rooms.Room{},
+ Box: tview.NewBox(),
+ items: []*rooms.Room{},
mainTextColor: tcell.ColorWhite,
selectedTextColor: tcell.ColorWhite,
@@ -53,28 +51,49 @@ func NewRoomList() *RoomList {
}
}
+func (list *RoomList) Contains(roomID string) bool {
+ for _, room := range list.items {
+ if room.ID == roomID {
+ return true
+ }
+ }
+ return false
+}
+
func (list *RoomList) Add(room *rooms.Room) {
- list.indices[room] = len(list.items)
list.items = append(list.items, room)
- if list.selected == nil {
- list.selected = room
- }
}
func (list *RoomList) Remove(room *rooms.Room) {
- index, ok := list.indices[room]
- if !ok {
- return
+ index := list.Index(room)
+ if index != -1 {
+ list.items = append(list.items[0:index], list.items[index+1:]...)
+ if room == list.selected {
+ if index > 0 {
+ list.selected = list.items[index-1]
+ } else if len(list.items) > 0 {
+ list.selected = list.items[0]
+ } else {
+ list.selected = nil
+ }
+ }
}
- delete(list.indices, room)
- list.items = append(list.items[0:index], list.items[index+1:]...)
- if len(list.items) == 0 {
- list.selected = nil
+}
+
+func (list *RoomList) Bump(room *rooms.Room) {
+ found := false
+ for i := 0; i < len(list.items)-1; i++ {
+ if list.items[i] == room {
+ found = true
+ }
+ if found {
+ list.items[i] = list.items[i+1]
+ }
}
+ list.items[len(list.items)-1] = room
}
func (list *RoomList) Clear() {
- list.indices = make(map[*rooms.Room]int)
list.items = []*rooms.Room{}
list.selected = nil
}
@@ -83,11 +102,55 @@ func (list *RoomList) SetSelected(room *rooms.Room) {
list.selected = room
}
-func (list *RoomList) Get(n int) *rooms.Room {
- if n < 0 || n >= len(list.items) {
+func (list *RoomList) HasSelected() bool {
+ return list.selected != nil
+}
+
+func (list *RoomList) Selected() *rooms.Room {
+ return list.selected
+}
+
+func (list *RoomList) Previous() *rooms.Room {
+ if len(list.items) == 0 {
return nil
+ } else if list.selected == nil {
+ return list.items[0]
}
- return list.items[n]
+
+ 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 {
+ if len(list.items) == 0 {
+ return nil
+ } else if list.selected == nil {
+ return list.items[0]
+ }
+
+ index := list.Index(list.selected)
+ if index == 0 {
+ return list.items[len(list.items)-1]
+ }
+ return list.items[index-1]
+}
+
+func (list *RoomList) Index(room *rooms.Room) int {
+ roomIndex := -1
+ for index, entry := range list.items {
+ if entry == room {
+ roomIndex = index
+ break
+ }
+ }
+ return roomIndex
+}
+
+func (list *RoomList) Get(n int) *rooms.Room {
+ return list.items[len(list.items)-1-(n%len(list.items))]
}
// Draw draws this primitive onto the screen.
@@ -98,13 +161,16 @@ func (list *RoomList) Draw(screen tcell.Screen) {
bottomLimit := y + height
var offset int
- currentItemIndex, hasSelected := list.indices[list.selected]
- if hasSelected && currentItemIndex >= height {
+ currentItemIndex := list.Index(list.selected)
+ if currentItemIndex >= height {
offset = currentItemIndex + 1 - height
}
// Draw the list items.
- for index, item := range list.items {
+ for i := len(list.items) - 1; i >= 0; i-- {
+ item := list.items[i]
+ index := len(list.items) - 1 - i
+
if index < offset {
continue
}
diff --git a/ui/view-main.go b/ui/view-main.go
index c693fcd..e9350e7 100644
--- a/ui/view-main.go
+++ b/ui/view-main.go
@@ -18,7 +18,6 @@ package ui
import (
"fmt"
- "sort"
"strings"
"time"
"unicode"
@@ -39,11 +38,9 @@ import (
type MainView struct {
*tview.Flex
- roomList *RoomList
- roomView *tview.Pages
- rooms map[string]*RoomView
- currentRoomIndex int
- roomIDs []string
+ roomList *RoomList
+ roomView *tview.Pages
+ rooms map[string]*RoomView
lastFocusTime time.Time
@@ -166,9 +163,9 @@ func (view *MainView) KeyEventHandler(roomView *RoomView, key *tcell.EventKey) *
if key.Modifiers() == tcell.ModCtrl || key.Modifiers() == tcell.ModAlt {
switch k {
case tcell.KeyDown:
- view.SwitchRoom(view.currentRoomIndex + 1)
+ view.SwitchRoom(view.roomList.Next())
case tcell.KeyUp:
- view.SwitchRoom(view.currentRoomIndex - 1)
+ view.SwitchRoom(view.roomList.Previous())
default:
return key
}
@@ -241,9 +238,7 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo
} else if isInArea(x, y, view.roomList) && event.Buttons() == tcell.Button1 {
_, rly, _, _ := msgView.GetRect()
n := y - rly + 1
- if n >= 0 && n < len(view.roomIDs) {
- view.SwitchRoom(n)
- }
+ view.SwitchRoom(view.roomList.Get(n))
} else {
debug.Print("Unhandled mouse event:", event.Buttons(), event.Modifiers(), x, y)
}
@@ -253,35 +248,24 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo
return event
}
-func (view *MainView) CurrentRoomID() string {
- if len(view.roomIDs) == 0 {
- return ""
- }
- return view.roomIDs[view.currentRoomIndex]
-}
-
-func (view *MainView) SwitchRoom(roomIndex int) {
- if roomIndex < 0 {
- roomIndex = len(view.roomIDs) - 1
- }
- if len(view.roomIDs) == 0 {
- return
- }
- view.currentRoomIndex = roomIndex % len(view.roomIDs)
- view.roomView.SwitchToPage(view.CurrentRoomID())
- roomView := view.rooms[view.CurrentRoomID()]
+func (view *MainView) SwitchRoom(room *rooms.Room) {
+ view.roomView.SwitchToPage(room.ID)
+ roomView := view.rooms[room.ID]
if roomView.MessageView().ScrollOffset == 0 {
roomView.Room.MarkRead()
}
- view.roomList.SetSelected(roomView.Room)
+ view.roomList.SetSelected(room)
view.parent.app.SetFocus(view)
view.parent.Render()
}
func (view *MainView) Focus(delegate func(p tview.Primitive)) {
- roomView, ok := view.rooms[view.CurrentRoomID()]
- if ok {
- delegate(roomView)
+ room := view.roomList.Selected()
+ if room != nil {
+ roomView, ok := view.rooms[room.ID]
+ if ok {
+ delegate(roomView)
+ }
}
}
@@ -294,78 +278,67 @@ func (view *MainView) SaveAllHistory() {
}
}
-func (view *MainView) addRoom(index int, room string) {
- roomStore := view.matrix.GetRoom(room)
+func (view *MainView) addRoomPage(room *rooms.Room) {
- view.roomList.Add(roomStore)
- if !view.roomView.HasPage(room) {
- roomView := NewRoomView(view, roomStore).
+ if !view.roomView.HasPage(room.ID) {
+ roomView := NewRoomView(view, room).
SetInputSubmitFunc(view.InputSubmit).
SetInputChangedFunc(view.InputChanged).
SetInputCapture(view.KeyEventHandler).
SetMouseCapture(view.MouseEventHandler)
- view.rooms[room] = roomView
- view.roomView.AddPage(room, roomView, true, false)
+ view.rooms[room.ID] = roomView
+ view.roomView.AddPage(room.ID, roomView, true, false)
roomView.UpdateUserList()
count, err := roomView.LoadHistory(view.matrix, view.config.HistoryDir)
if err != nil {
debug.Printf("Failed to load history of %s: %v", roomView.Room.GetTitle(), err)
} else if count <= 0 {
- go view.LoadHistory(room, true)
+ go view.LoadHistory(room.ID, true)
}
}
}
-func (view *MainView) GetRoom(id string) ifc.RoomView {
- return view.rooms[id]
+func (view *MainView) GetRoom(roomID string) ifc.RoomView {
+ return view.rooms[roomID]
}
-func (view *MainView) HasRoom(room string) bool {
- for _, existingRoom := range view.roomIDs {
- if existingRoom == room {
- return true
- }
- }
- return false
-}
-
-func (view *MainView) AddRoom(room string) {
- if view.HasRoom(room) {
+func (view *MainView) AddRoom(roomID string) {
+ if view.roomList.Contains(roomID) {
return
}
- view.roomIDs = append(view.roomIDs, room)
- view.addRoom(len(view.roomIDs)-1, room)
+ room := view.matrix.GetRoom(roomID)
+ view.roomList.Add(room)
+ view.addRoomPage(room)
}
-func (view *MainView) RemoveRoom(room string) {
- roomView := view.GetRoom(room)
+func (view *MainView) RemoveRoom(roomID string) {
+ roomView := view.GetRoom(roomID)
if roomView == nil {
return
}
- removeIndex := 0
- if view.CurrentRoomID() == room {
- removeIndex = view.currentRoomIndex
- view.SwitchRoom(view.currentRoomIndex - 1)
- } else {
- removeIndex = sort.StringSlice(view.roomIDs).Search(room)
- }
+
view.roomList.Remove(roomView.MxRoom())
- view.roomIDs = append(view.roomIDs[:removeIndex], view.roomIDs[removeIndex+1:]...)
- view.roomView.RemovePage(room)
- delete(view.rooms, room)
+ view.SwitchRoom(view.roomList.Selected())
+
+ view.roomView.RemovePage(roomID)
+ delete(view.rooms, roomID)
+
view.parent.Render()
}
-func (view *MainView) SetRooms(rooms []string) {
- view.roomIDs = rooms
+func (view *MainView) SetRooms(roomIDs []string) {
view.roomList.Clear()
view.roomView.Clear()
view.rooms = make(map[string]*RoomView)
- for index, room := range rooms {
- view.addRoom(index, room)
+ for index, roomID := range roomIDs {
+ room := view.matrix.GetRoom(roomID)
+ view.roomList.Add(room)
+ view.addRoomPage(room)
+ if index == len(roomIDs)-1 {
+ view.SwitchRoom(room)
+ }
}
- view.SwitchRoom(0)
}
func (view *MainView) SetTyping(room string, users []string) {
@@ -385,7 +358,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) {
// Whether or not the room where the message came is the currently shown room.
- isCurrent := room.ID == view.CurrentRoomID()
+ isCurrent := room == view.roomList.Selected()
// Whether or not the terminal window is focused.
isFocused := view.lastFocusTime.Add(30 * time.Second).Before(time.Now())
@@ -408,6 +381,7 @@ func (view *MainView) NotifyMessage(room *rooms.Room, message ifc.Message, shoul
}
message.SetIsHighlight(should.Highlight)
+ view.roomList.Bump(room)
}
func (view *MainView) LoadHistory(room string, initial bool) {