From fcd9a932cb5542ed8980fc1daba7ee1f0041a3f2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Apr 2018 02:11:32 +0300 Subject: [PATCH 1/6] Initial move to initial sync. Everything broke :( --- config/session.go | 6 ++++++ matrix/matrix.go | 6 +++++- matrix/sync.go | 18 ++++++------------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/config/session.go b/config/session.go index 9419038..2a6ce36 100644 --- a/config/session.go +++ b/config/session.go @@ -35,6 +35,8 @@ type Session struct { FilterID string Rooms map[string]*rooms.Room PushRules *pushrules.PushRuleset + + InitialSyncDone bool } func (config *Config) LoadSession(mxid string) error { @@ -50,6 +52,10 @@ func (config *Config) NewSession(mxid string) *Session { } } +func (s *Session) SetInitialSyncDone() { + s.InitialSyncDone = true +} + func (s *Session) GetUserID() string { return s.UserID } diff --git a/matrix/matrix.go b/matrix/matrix.go index d58ce20..5345c40 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -191,7 +191,7 @@ func (c *Container) OnLogin() { c.syncer.OnEventType("m.tag", c.HandleTag) c.client.Syncer = c.syncer - c.UpdateRoomList() + //c.UpdateRoomList() } // Start moves the UI to the main view, calls OnLogin() and runs the syncer forever until stopped with Stop() @@ -296,6 +296,10 @@ func (c *Container) HandleMembership(evt *gomatrix.Event) { c.processOwnMembershipChange(evt) } + if !c.config.Session.InitialSyncDone && evt.Timestamp < time.Now().Add(-1*time.Hour).Unix() { + return + } + mainView := c.ui.MainView() roomView := mainView.GetRoom(evt.RoomID) if roomView == nil { diff --git a/matrix/sync.go b/matrix/sync.go index f3966cb..ec1c34e 100644 --- a/matrix/sync.go +++ b/matrix/sync.go @@ -20,16 +20,16 @@ package matrix import ( "encoding/json" - "fmt" - "runtime/debug" "time" "maunium.net/go/gomatrix" + "maunium.net/go/gomuks/debug" "maunium.net/go/gomuks/matrix/rooms" ) type SyncerSession interface { GetRoom(id string) *rooms.Room + SetInitialSyncDone() GetUserID() string } @@ -53,16 +53,7 @@ func NewGomuksSyncer(session SyncerSession) *GomuksSyncer { // ProcessResponse processes a Matrix sync response. func (s *GomuksSyncer) ProcessResponse(res *gomatrix.RespSync, since string) (err error) { - if len(since) == 0 { - return - } - // debug.Print("Processing sync response", since, res) - - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("ProcessResponse for %s since %s panicked: %s\n%s", s.Session.GetUserID(), since, r, debug.Stack()) - } - }() + debug.Print("Processing sync response", since, res) s.processSyncEvents(nil, res.Presence.Events, false, false) s.processSyncEvents(nil, res.AccountData.Events, false, false) @@ -93,6 +84,9 @@ func (s *GomuksSyncer) ProcessResponse(res *gomatrix.RespSync, since string) (er } } + if since == "" { + s.Session.SetInitialSyncDone() + } s.FirstSyncDone = true return From e64df67ec397795b8c6ebd06b391d953afe5a766 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Apr 2018 16:51:40 +0300 Subject: [PATCH 2/6] Everything is no longer broken --- config/session.go | 1 + gomuks.go | 9 +++++++ interface/ui.go | 2 +- matrix/matrix.go | 53 +++++++++++++++++++++-------------------- matrix/rooms/room.go | 10 ++++++++ matrix/sync.go | 11 +++++---- ui/message-view.go | 5 ++-- ui/messages/textbase.go | 8 ++++++- ui/room-list.go | 13 +++++++--- ui/view-main.go | 5 ++-- 10 files changed, 77 insertions(+), 40 deletions(-) diff --git a/config/session.go b/config/session.go index 2a6ce36..e47592c 100644 --- a/config/session.go +++ b/config/session.go @@ -65,6 +65,7 @@ func (s *Session) Clear() { s.PushRules = nil s.NextBatch = "" s.FilterID = "" + s.InitialSyncDone = false s.Save() } diff --git a/gomuks.go b/gomuks.go index ffdfad3..5f5d74b 100644 --- a/gomuks.go +++ b/gomuks.go @@ -18,7 +18,9 @@ package main import ( "os" + "os/signal" "path/filepath" + "syscall" "time" "maunium.net/go/gomuks/config" @@ -104,6 +106,13 @@ func (gmx *Gomuks) Stop() { func (gmx *Gomuks) Start() { _ = gmx.matrix.InitClient() + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + gmx.Stop() + }() + go gmx.StartAutosave() if err := gmx.ui.Start(); err != nil { panic(err) diff --git a/interface/ui.go b/interface/ui.go index c36819a..baa34bc 100644 --- a/interface/ui.go +++ b/interface/ui.go @@ -51,7 +51,7 @@ type MainView interface { GetRoom(roomID string) RoomView AddRoom(roomID string) RemoveRoom(roomID string) - SetRooms(roomIDs []string) + SetRooms(rooms map[string]*rooms.Room) SaveAllHistory() UpdateTags(room *rooms.Room, newTags []rooms.RoomTag) diff --git a/matrix/matrix.go b/matrix/matrix.go index 5345c40..530612c 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -129,6 +129,7 @@ func (c *Container) Login(user, password string) error { // Stop stops the Matrix syncer. func (c *Container) Stop() { if c.running { + debug.Print("Stopping Matrix container...") c.stop <- true c.client.StopSync() } @@ -157,22 +158,6 @@ func (c *Container) PushRules() *pushrules.PushRuleset { return c.config.Session.PushRules } -// UpdateRoomList fetches the list of rooms the user has joined and sends them to the UI. -func (c *Container) UpdateRoomList() { - resp, err := c.client.JoinedRooms() - if err != nil { - respErr, _ := err.(gomatrix.HTTPError).WrappedError.(gomatrix.RespError) - if respErr.ErrCode == "M_UNKNOWN_TOKEN" { - c.OnLogout() - return - } - debug.Print("Error fetching room list:", err) - return - } - - c.ui.MainView().SetRooms(resp.JoinedRooms) -} - // OnLogout stops the syncer and moves the UI back to the login view. func (c *Container) OnLogout() { c.Stop() @@ -183,6 +168,7 @@ func (c *Container) OnLogout() { func (c *Container) OnLogin() { c.client.Store = c.config.Session + debug.Print("Initializing syncer") c.syncer = NewGomuksSyncer(c.config.Session) c.syncer.OnEventType("m.room.message", c.HandleMessage) c.syncer.OnEventType("m.room.member", c.HandleMembership) @@ -191,7 +177,10 @@ func (c *Container) OnLogin() { c.syncer.OnEventType("m.tag", c.HandleTag) c.client.Syncer = c.syncer - //c.UpdateRoomList() + debug.Print("Setting existing rooms") + c.ui.MainView().SetRooms(c.config.Session.Rooms) + + debug.Print("OnLogin() done.") } // Start moves the UI to the main view, calls OnLogin() and runs the syncer forever until stopped with Stop() @@ -226,19 +215,24 @@ func (c *Container) Start() { // HandleMessage is the event handler for the m.room.message timeline event. func (c *Container) HandleMessage(evt *gomatrix.Event) { mainView := c.ui.MainView() + roomView := mainView.GetRoom(evt.RoomID) if roomView == nil { + debug.Printf("Failed to handle event %v: No room view found.", evt) return } message := mainView.ParseEvent(roomView, evt) if message != nil { + debug.Print("Adding message", message.ID(), c.syncer.FirstSyncDone, c.config.Session.InitialSyncDone) + roomView.AddMessage(message, ifc.AppendMessage) if c.syncer.FirstSyncDone { pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should() mainView.NotifyMessage(roomView.MxRoom(), message, pushRules) + c.ui.Render() } - roomView.AddMessage(message, ifc.AppendMessage) - c.ui.Render() + } else { + debug.Printf("Parsing event %v failed (ParseEvent() returned nil).", evt) } } @@ -279,6 +273,7 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) { if evt.Unsigned.PrevContent != nil { prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string) } + debug.Printf("Processing own membership change: %s->%s in %s", membership, prevMembership, evt.RoomID) if membership == prevMembership { return } @@ -287,6 +282,9 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) { c.ui.MainView().AddRoom(evt.RoomID) case "leave": c.ui.MainView().RemoveRoom(evt.RoomID) + case "invite": + // TODO handle + debug.Printf("%s invited the user to %s", evt.Sender, evt.RoomID) } } @@ -296,7 +294,8 @@ func (c *Container) HandleMembership(evt *gomatrix.Event) { c.processOwnMembershipChange(evt) } - if !c.config.Session.InitialSyncDone && evt.Timestamp < time.Now().Add(-1*time.Hour).Unix() { + if !c.config.Session.InitialSyncDone /*&& evt.Timestamp < time.Now().Add(-1*time.Hour).Unix()*/ { + // We don't care about other users' membership events in the initial sync. return } @@ -308,17 +307,19 @@ func (c *Container) HandleMembership(evt *gomatrix.Event) { message := mainView.ParseEvent(roomView, evt) if message != nil { + debug.Print("Adding membership event", message.ID(), c.syncer.FirstSyncDone, c.config.Session.InitialSyncDone) // TODO this shouldn't be necessary - roomView.MxRoom().UpdateState(evt) + //roomView.MxRoom().UpdateState(evt) // TODO This should probably also be in a different place - roomView.UpdateUserList() + //roomView.UpdateUserList() + roomView.AddMessage(message, ifc.AppendMessage) + // We don't want notifications at startup. if c.syncer.FirstSyncDone { pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should() mainView.NotifyMessage(roomView.MxRoom(), message, pushRules) + c.ui.Render() } - roomView.AddMessage(message, ifc.AppendMessage) - c.ui.Render() } } @@ -475,12 +476,12 @@ func (c *Container) GetHistory(roomID, prevBatch string, limit int) ([]gomatrix. func (c *Container) GetRoom(roomID string) *rooms.Room { room := c.config.Session.GetRoom(roomID) if room != nil && len(room.State) == 0 { - events := c.getState(room.ID) + /*events := c.getState(room.ID) if events != nil { for _, event := range events { room.UpdateState(event) } - } + }*/ } return room } diff --git a/matrix/rooms/room.go b/matrix/rooms/room.go index 44a386b..9aae5ea 100644 --- a/matrix/rooms/room.go +++ b/matrix/rooms/room.go @@ -23,6 +23,7 @@ import ( "time" "maunium.net/go/gomatrix" + "maunium.net/go/gomuks/debug" ) type RoomNameSource int @@ -148,6 +149,15 @@ func (room *Room) UpdateState(event *gomatrix.Event) { case "m.room.topic": room.topicCache = "" } + + stateKey := "" + if event.StateKey != nil { + stateKey = *event.StateKey + } + if event.Type != "m.room.member" { + debug.Printf("[ROOM] Updating state %s#%s for %s", event.Type, stateKey, room.ID) + } + if event.StateKey == nil { room.State[event.Type][""] = event } else { diff --git a/matrix/sync.go b/matrix/sync.go index ec1c34e..d0e1e69 100644 --- a/matrix/sync.go +++ b/matrix/sync.go @@ -23,7 +23,6 @@ import ( "time" "maunium.net/go/gomatrix" - "maunium.net/go/gomuks/debug" "maunium.net/go/gomuks/matrix/rooms" ) @@ -53,8 +52,6 @@ func NewGomuksSyncer(session SyncerSession) *GomuksSyncer { // ProcessResponse processes a Matrix sync response. func (s *GomuksSyncer) ProcessResponse(res *gomatrix.RespSync, since string) (err error) { - debug.Print("Processing sync response", since, res) - s.processSyncEvents(nil, res.Presence.Events, false, false) s.processSyncEvents(nil, res.AccountData.Events, false, false) @@ -141,7 +138,13 @@ func (s *GomuksSyncer) GetFilterJSON(userID string) json.RawMessage { "room": { "include_leave": true, "state": { - "types": ["m.room.member"] + "types": [ + "m.room.member", + "m.room.name", + "m.room.topic", + "m.room.canonical_alias", + "m.room.aliases" + ] }, "timeline": { "types": ["m.room.message"], diff --git a/ui/message-view.go b/ui/message-view.go index ca03e73..2e33cd7 100644 --- a/ui/message-view.go +++ b/ui/message-view.go @@ -183,7 +183,8 @@ func (view *MessageView) AddMessage(ifcMessage ifc.Message, direction ifc.Messag } else if oldMsg != nil { view.replaceBuffer(oldMsg, message) } else { - view.replaceBuffer(message, message) + debug.Print("Unexpected AddMessage() call: Direction is not append or prepend, but message is new.") + debug.PrintStack() } view.messageIDs[message.ID()] = message @@ -232,7 +233,7 @@ func (view *MessageView) replaceBuffer(original messages.UIMessage, new messages } if start == -1 { - debug.Print("Called replaceBuffer() with message that was not in the buffer:", original) + debug.Print("Called replaceBuffer() with message that was not in the buffer:", original.ID()) view.appendBuffer(new) return } diff --git a/ui/messages/textbase.go b/ui/messages/textbase.go index 0960a57..79913f8 100644 --- a/ui/messages/textbase.go +++ b/ui/messages/textbase.go @@ -73,7 +73,13 @@ func (msg *BaseTextMessage) calculateBufferWithText(text tstring.TString, width matches := boundaryPattern.FindAllStringIndex(extract.String(), -1) if len(matches) > 0 { - extract = extract[:matches[len(matches)-1][1]] + match := matches[len(matches)-1] + if len(match) > 1 { + until := match[1] + if until < len(extract) { + extract = extract[:until] + } + } } } msg.buffer = append(msg.buffer, extract) diff --git a/ui/room-list.go b/ui/room-list.go index a70fd68..19202f8 100644 --- a/ui/room-list.go +++ b/ui/room-list.go @@ -210,7 +210,7 @@ func (list *RoomList) Clear() { func (list *RoomList) SetSelected(tag string, room *rooms.Room) { list.selected = room - list.selectedTag = "" + list.selectedTag = tag } func (list *RoomList) HasSelected() bool { @@ -264,7 +264,9 @@ func (list *RoomList) Previous() (string, *rooms.Room) { items := list.items[list.selectedTag] index := list.indexInTag(list.selectedTag, list.selected) - if index == len(items)-1 { + if index == -1 { + return list.First() + } else if index == len(items)-1 { tagIndex := list.IndexTag(list.selectedTag) tagIndex++ for ; tagIndex < len(list.tags); tagIndex++ { @@ -288,7 +290,9 @@ func (list *RoomList) Next() (string, *rooms.Room) { items := list.items[list.selectedTag] index := list.indexInTag(list.selectedTag, list.selected) - if index == 0 { + if index == -1 { + return list.Last() + } else if index == 0 { tagIndex := list.IndexTag(list.selectedTag) tagIndex-- for ; tagIndex >= 0; tagIndex-- { @@ -332,6 +336,8 @@ func (list *RoomList) Get(n int) (string, *rooms.Room) { // Tag items n -= len(items) + // Tag footer + n-- } return "", nil } @@ -420,5 +426,6 @@ func (list *RoomList) Draw(screen tcell.Screen) { break } } + y++ } } diff --git a/ui/view-main.go b/ui/view-main.go index ba3a55b..473ab94 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -336,12 +336,11 @@ func (view *MainView) RemoveRoom(roomID string) { view.parent.Render() } -func (view *MainView) SetRooms(roomIDs []string) { +func (view *MainView) SetRooms(rooms map[string]*rooms.Room) { view.roomList.Clear() view.roomView.Clear() view.rooms = make(map[string]*RoomView) - for _, roomID := range roomIDs { - room := view.matrix.GetRoom(roomID) + for _, room := range rooms { view.roomList.Add(room) view.addRoomPage(room) } From 28c65275440b3f7371540b49733db8b6b170a64d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Apr 2018 17:12:08 +0300 Subject: [PATCH 3/6] Fix/break/change things --- config/session.go | 4 ---- matrix/matrix.go | 6 ++++-- matrix/rooms/room.go | 2 +- matrix/sync.go | 12 ++++++------ ui/message-view.go | 1 + 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/config/session.go b/config/session.go index e47592c..d23c778 100644 --- a/config/session.go +++ b/config/session.go @@ -52,10 +52,6 @@ func (config *Config) NewSession(mxid string) *Session { } } -func (s *Session) SetInitialSyncDone() { - s.InitialSyncDone = true -} - func (s *Session) GetUserID() string { return s.UserID } diff --git a/matrix/matrix.go b/matrix/matrix.go index 530612c..f2b8bf3 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -175,6 +175,10 @@ func (c *Container) OnLogin() { c.syncer.OnEventType("m.typing", c.HandleTyping) c.syncer.OnEventType("m.push_rules", c.HandlePushRules) c.syncer.OnEventType("m.tag", c.HandleTag) + c.syncer.InitDoneCallback = func() { + c.config.Session.InitialSyncDone = true + c.ui.Render() + } c.client.Syncer = c.syncer debug.Print("Setting existing rooms") @@ -224,7 +228,6 @@ func (c *Container) HandleMessage(evt *gomatrix.Event) { message := mainView.ParseEvent(roomView, evt) if message != nil { - debug.Print("Adding message", message.ID(), c.syncer.FirstSyncDone, c.config.Session.InitialSyncDone) roomView.AddMessage(message, ifc.AppendMessage) if c.syncer.FirstSyncDone { pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should() @@ -307,7 +310,6 @@ func (c *Container) HandleMembership(evt *gomatrix.Event) { message := mainView.ParseEvent(roomView, evt) if message != nil { - debug.Print("Adding membership event", message.ID(), c.syncer.FirstSyncDone, c.config.Session.InitialSyncDone) // TODO this shouldn't be necessary //roomView.MxRoom().UpdateState(evt) // TODO This should probably also be in a different place diff --git a/matrix/rooms/room.go b/matrix/rooms/room.go index 9aae5ea..95349c3 100644 --- a/matrix/rooms/room.go +++ b/matrix/rooms/room.go @@ -155,7 +155,7 @@ func (room *Room) UpdateState(event *gomatrix.Event) { stateKey = *event.StateKey } if event.Type != "m.room.member" { - debug.Printf("[ROOM] Updating state %s#%s for %s", event.Type, stateKey, room.ID) + debug.Printf("Updating state %s#%s for %s", event.Type, stateKey, room.ID) } if event.StateKey == nil { diff --git a/matrix/sync.go b/matrix/sync.go index d0e1e69..8ad7ad5 100644 --- a/matrix/sync.go +++ b/matrix/sync.go @@ -28,7 +28,6 @@ import ( type SyncerSession interface { GetRoom(id string) *rooms.Room - SetInitialSyncDone() GetUserID() string } @@ -36,9 +35,10 @@ type SyncerSession interface { // replace parts of this default syncer (e.g. the ProcessResponse method). The default syncer uses the observer // pattern to notify callers about incoming events. See GomuksSyncer.OnEventType for more information. type GomuksSyncer struct { - Session SyncerSession - listeners map[string][]gomatrix.OnEventListener // event type to listeners array - FirstSyncDone bool + Session SyncerSession + listeners map[string][]gomatrix.OnEventListener // event type to listeners array + FirstSyncDone bool + InitDoneCallback func() } // NewGomuksSyncer returns an instantiated GomuksSyncer @@ -81,8 +81,8 @@ func (s *GomuksSyncer) ProcessResponse(res *gomatrix.RespSync, since string) (er } } - if since == "" { - s.Session.SetInitialSyncDone() + if since == "" && s.InitDoneCallback != nil { + s.InitDoneCallback() } s.FirstSyncDone = true diff --git a/ui/message-view.go b/ui/message-view.go index 2e33cd7..f2fb72f 100644 --- a/ui/message-view.go +++ b/ui/message-view.go @@ -234,6 +234,7 @@ func (view *MessageView) replaceBuffer(original messages.UIMessage, new messages if start == -1 { debug.Print("Called replaceBuffer() with message that was not in the buffer:", original.ID()) + debug.PrintStack() view.appendBuffer(new) return } From 9ccceb48b98a999eb31de113bd0b994844ce7dc3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Apr 2018 22:08:09 +0300 Subject: [PATCH 4/6] Disable initial history fetch (comes with initial sync) --- matrix/matrix.go | 2 +- ui/view-main.go | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/matrix/matrix.go b/matrix/matrix.go index f2b8bf3..2e97ef4 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -276,7 +276,7 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) { if evt.Unsigned.PrevContent != nil { prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string) } - debug.Printf("Processing own membership change: %s->%s in %s", membership, prevMembership, evt.RoomID) + debug.Printf("Processing own membership change: %s->%s in %s", prevMembership, membership, evt.RoomID) if membership == prevMembership { return } diff --git a/ui/view-main.go b/ui/view-main.go index 473ab94..f3fb210 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -173,7 +173,7 @@ func (view *MainView) KeyEventHandler(roomView *RoomView, key *tcell.EventKey) * msgView := roomView.MessageView() if msgView.IsAtTop() && (k == tcell.KeyPgUp || k == tcell.KeyUp) { - go view.LoadHistory(roomView.Room.ID, false) + go view.LoadHistory(roomView.Room.ID) } switch k { @@ -215,7 +215,7 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo switch event.Buttons() { case tcell.WheelUp: if msgView.IsAtTop() { - go view.LoadHistory(roomView.Room.ID, false) + go view.LoadHistory(roomView.Room.ID) } else { msgView.AddScrollOffset(WheelScrollOffsetDiff) @@ -293,11 +293,9 @@ func (view *MainView) addRoomPage(room *rooms.Room) { view.roomView.AddPage(room.ID, roomView, true, false) roomView.UpdateUserList() - count, err := roomView.LoadHistory(view.matrix, view.config.HistoryDir) + _, 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.ID, true) } } } @@ -314,8 +312,10 @@ func (view *MainView) GetRoom(roomID string) ifc.RoomView { func (view *MainView) AddRoom(roomID string) { if view.roomList.Contains(roomID) { + debug.Print("Add aborted", roomID) return } + debug.Print("Adding", roomID) room := view.matrix.GetRoom(roomID) view.roomList.Add(room) view.addRoomPage(room) @@ -324,8 +324,10 @@ func (view *MainView) AddRoom(roomID string) { func (view *MainView) RemoveRoom(roomID string) { roomView := view.GetRoom(roomID) if roomView == nil { + debug.Print("Remove aborted", roomID) return } + debug.Print("Removing", roomID) view.roomList.Remove(roomView.MxRoom()) view.SwitchRoom(view.roomList.Selected()) @@ -424,7 +426,7 @@ func (view *MainView) NotifyMessage(room *rooms.Room, message ifc.Message, shoul view.roomList.Bump(room) } -func (view *MainView) LoadHistory(room string, initial bool) { +func (view *MainView) LoadHistory(room string) { defer debug.Recover() roomView := view.rooms[room] @@ -445,12 +447,7 @@ func (view *MainView) LoadHistory(room string, initial bool) { return } - if initial { - batch = view.config.Session.NextBatch - debug.Print("Loading initial history for", room) - } else { - debug.Print("Loading more history for", room, "starting from", batch) - } + debug.Print("Fetching history for", room, "starting from", batch) history, prevBatch, err := view.matrix.GetHistory(roomView.Room.ID, batch, 50) if err != nil { roomView.AddServiceMessage("Failed to fetch history") From 6aceb4f8d2061fb99fd16deda58f4807d81a6ff7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Apr 2018 22:46:16 +0300 Subject: [PATCH 5/6] Fix First(), Last(), Next() and Previous() of RoomList --- ui/room-list.go | 44 +++++++++++++++++++++++++------------------- ui/view-main.go | 3 +++ 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/ui/room-list.go b/ui/room-list.go index 19202f8..d361a12 100644 --- a/ui/room-list.go +++ b/ui/room-list.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "maunium.net/go/gomuks/debug" "maunium.net/go/gomuks/matrix/rooms" "maunium.net/go/gomuks/ui/widget" "maunium.net/go/tcell" @@ -57,6 +58,7 @@ func NewRoomList() *RoomList { return &RoomList{ Box: tview.NewBox(), items: make(map[string][]*rooms.Room), + tags: []string{"m.favourite", "im.vector.fake.direct", "", "m.lowpriority"}, mainTextColor: tcell.ColorWhite, selectedTextColor: tcell.ColorWhite, @@ -86,16 +88,17 @@ func (list *RoomList) CheckTag(tag string) { items, ok := list.items[tag] - if len(items) == 0 { + if ok && len(items) == 0 { delete(list.items, tag) ok = false } if ok && index == -1 { list.tags = append(list.tags, tag) - } else if index != -1 { + }/* TODO this doesn't work properly + else if index != -1 { list.tags = append(list.tags[0:index], list.tags[index+1:]...) - } + }*/ } func (list *RoomList) AddToTag(tag string, room *rooms.Room) { @@ -211,6 +214,7 @@ func (list *RoomList) Clear() { func (list *RoomList) SetSelected(tag string, room *rooms.Room) { list.selected = room list.selectedTag = tag + debug.Print("Selecting", room.GetTitle(), "in", tag) } func (list *RoomList) HasSelected() bool { @@ -229,7 +233,7 @@ func (list *RoomList) First() (string, *rooms.Room) { for _, tag := range list.tags { items := list.items[tag] if len(items) > 0 { - return tag, items[0] + return tag, items[len(items)-1] } } return "", nil @@ -240,7 +244,7 @@ func (list *RoomList) Last() (string, *rooms.Room) { tag := list.tags[tagIndex] items := list.items[tag] if len(items) > 0 { - return tag, items[len(items)-1] + return tag, items[0] } } return "", nil @@ -268,15 +272,15 @@ func (list *RoomList) Previous() (string, *rooms.Room) { return list.First() } else 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] + tagIndex-- + for ; tagIndex >= 0; tagIndex-- { + prevTag := list.tags[tagIndex] + prevTagItems := list.items[prevTag] + if len(prevTagItems) > 0 { + return prevTag, prevTagItems[0] } } - return list.First() + return list.Last() } return list.selectedTag, items[index+1] } @@ -294,15 +298,15 @@ func (list *RoomList) Next() (string, *rooms.Room) { return list.Last() } else if index == 0 { 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] + tagIndex++ + for ; tagIndex < len(list.tags); tagIndex++ { + nextTag := list.tags[tagIndex] + nextTagItems := list.items[nextTag] + if len(nextTagItems) > 0 { + return nextTag, nextTagItems[len(nextTagItems)-1] } } - return list.Last() + return list.First() } return list.selectedTag, items[index-1] } @@ -352,6 +356,8 @@ func (list *RoomList) GetTagDisplayName(tag string) string { return "Favorites" case tag == "m.lowpriority": return "Low Priority" + case tag == "im.vector.fake.direct": + return "People" case strings.HasPrefix(tag, "m."): return strings.Title(strings.Replace(tag[len("m."):], "_", " ", -1)) case strings.HasPrefix(tag, "u."): diff --git a/ui/view-main.go b/ui/view-main.go index f3fb210..d20fed3 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -319,6 +319,9 @@ func (view *MainView) AddRoom(roomID string) { room := view.matrix.GetRoom(roomID) view.roomList.Add(room) view.addRoomPage(room) + if !view.roomList.HasSelected() { + view.SwitchRoom(view.roomList.First()) + } } func (view *MainView) RemoveRoom(roomID string) { From d7d654e2ec0a1d001f936b1575a3e6af3973a874 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Apr 2018 22:49:41 +0300 Subject: [PATCH 6/6] Flatten calculateBufferWithText() and gofmt --- ui/messages/textbase.go | 20 ++++++++++++-------- ui/room-list.go | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ui/messages/textbase.go b/ui/messages/textbase.go index 79913f8..f44d5d5 100644 --- a/ui/messages/textbase.go +++ b/ui/messages/textbase.go @@ -72,14 +72,18 @@ func (msg *BaseTextMessage) calculateBufferWithText(text tstring.TString, width } matches := boundaryPattern.FindAllStringIndex(extract.String(), -1) - if len(matches) > 0 { - match := matches[len(matches)-1] - if len(match) > 1 { - until := match[1] - if until < len(extract) { - extract = extract[:until] - } - } + if len(matches) == 0 { + continue + } + + match := matches[len(matches)-1] + if len(match) < 2 { + continue + } + + until := match[1] + if until < len(extract) { + extract = extract[:until] } } msg.buffer = append(msg.buffer, extract) diff --git a/ui/room-list.go b/ui/room-list.go index d361a12..9444313 100644 --- a/ui/room-list.go +++ b/ui/room-list.go @@ -58,7 +58,7 @@ func NewRoomList() *RoomList { return &RoomList{ Box: tview.NewBox(), items: make(map[string][]*rooms.Room), - tags: []string{"m.favourite", "im.vector.fake.direct", "", "m.lowpriority"}, + tags: []string{"m.favourite", "im.vector.fake.direct", "", "m.lowpriority"}, mainTextColor: tcell.ColorWhite, selectedTextColor: tcell.ColorWhite, @@ -95,7 +95,7 @@ func (list *RoomList) CheckTag(tag string) { if ok && index == -1 { list.tags = append(list.tags, tag) - }/* TODO this doesn't work properly + } /* TODO this doesn't work properly else if index != -1 { list.tags = append(list.tags[0:index], list.tags[index+1:]...) }*/