|
@@ -52,6 +52,11 @@ type messagesList struct {
|
|
|
|
|
|
|
|
lastWidth int
|
|
lastWidth int
|
|
|
|
|
|
|
|
|
|
+ // Help cache: invalidated when cursor changes or messages are modified.
|
|
|
|
|
+ cachedHelpCursor int
|
|
|
|
|
+ cachedHelpURLs []string
|
|
|
|
|
+ cachedHelpDirty bool
|
|
|
|
|
+
|
|
|
fetchingMembers struct {
|
|
fetchingMembers struct {
|
|
|
mu sync.Mutex
|
|
mu sync.Mutex
|
|
|
value bool
|
|
value bool
|
|
@@ -77,12 +82,14 @@ type messagesListRow struct {
|
|
|
|
|
|
|
|
func newMessagesList(cfg *config.Config, chatView *Model) *messagesList {
|
|
func newMessagesList(cfg *config.Config, chatView *Model) *messagesList {
|
|
|
ml := &messagesList{
|
|
ml := &messagesList{
|
|
|
- Model: list.NewModel(),
|
|
|
|
|
- cfg: cfg,
|
|
|
|
|
- chatView: chatView,
|
|
|
|
|
- renderer: markdown.NewRenderer(cfg),
|
|
|
|
|
- itemByID: make(map[discord.MessageID]*tview.TextView),
|
|
|
|
|
- expandedReplies: make(map[discord.MessageID]struct{}),
|
|
|
|
|
|
|
+ Model: list.NewModel(),
|
|
|
|
|
+ cfg: cfg,
|
|
|
|
|
+ chatView: chatView,
|
|
|
|
|
+ renderer: markdown.NewRenderer(cfg),
|
|
|
|
|
+ itemByID: make(map[discord.MessageID]*tview.TextView),
|
|
|
|
|
+ expandedReplies: make(map[discord.MessageID]struct{}),
|
|
|
|
|
+ cachedHelpCursor: -1,
|
|
|
|
|
+ cachedHelpDirty: true,
|
|
|
}
|
|
}
|
|
|
ml.attachmentsPicker = newAttachmentsPicker(cfg, chatView)
|
|
ml.attachmentsPicker = newAttachmentsPicker(cfg, chatView)
|
|
|
|
|
|
|
@@ -319,6 +326,7 @@ func (ml *messagesList) rebuildRows() {
|
|
|
|
|
|
|
|
func (ml *messagesList) invalidateRows() {
|
|
func (ml *messagesList) invalidateRows() {
|
|
|
ml.rowsDirty = true
|
|
ml.rowsDirty = true
|
|
|
|
|
+ ml.cachedHelpDirty = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ensureRows lazily rebuilds list rows. This avoids repeated O(n) row rebuild
|
|
// ensureRows lazily rebuilds list rows. This avoids repeated O(n) row rebuild
|
|
@@ -1197,6 +1205,29 @@ func (ml *messagesList) waitForChunkEvent() uint {
|
|
|
return ml.fetchingMembers.count
|
|
return ml.fetchingMembers.count
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// cachedMessageURLs returns the URLs for the selected message, caching the
|
|
|
|
|
+// result of the expensive messageURLs parse so that ShortHelp and FullHelp
|
|
|
|
|
+// (both called every draw frame) only run the goldmark parser once per cursor
|
|
|
|
|
+// position change.
|
|
|
|
|
+func (ml *messagesList) cachedMessageURLs() ([]string, *discord.Message, bool) {
|
|
|
|
|
+ cursor := ml.Cursor()
|
|
|
|
|
+ if !ml.cachedHelpDirty && cursor == ml.cachedHelpCursor {
|
|
|
|
|
+ msg, err := ml.selectedMessage()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, nil, false
|
|
|
|
|
+ }
|
|
|
|
|
+ return ml.cachedHelpURLs, msg, true
|
|
|
|
|
+ }
|
|
|
|
|
+ msg, err := ml.selectedMessage()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, nil, false
|
|
|
|
|
+ }
|
|
|
|
|
+ ml.cachedHelpURLs = messageURLs(*msg)
|
|
|
|
|
+ ml.cachedHelpCursor = cursor
|
|
|
|
|
+ ml.cachedHelpDirty = false
|
|
|
|
|
+ return ml.cachedHelpURLs, msg, true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func (ml *messagesList) ShortHelp() []keybind.Keybind {
|
|
func (ml *messagesList) ShortHelp() []keybind.Keybind {
|
|
|
cfg := ml.cfg.Keybinds.MessagesList
|
|
cfg := ml.cfg.Keybinds.MessagesList
|
|
|
help := []keybind.Keybind{
|
|
help := []keybind.Keybind{
|
|
@@ -1206,13 +1237,13 @@ func (ml *messagesList) ShortHelp() []keybind.Keybind {
|
|
|
cfg.Search.Keybind,
|
|
cfg.Search.Keybind,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if msg, err := ml.selectedMessage(); err == nil {
|
|
|
|
|
|
|
+ if urls, msg, ok := ml.cachedMessageURLs(); ok {
|
|
|
if me, err := ml.chatView.state.Cabinet.Me(); err == nil {
|
|
if me, err := ml.chatView.state.Cabinet.Me(); err == nil {
|
|
|
if msg.Author.ID != me.ID {
|
|
if msg.Author.ID != me.ID {
|
|
|
help = append(help, cfg.Reply.Keybind)
|
|
help = append(help, cfg.Reply.Keybind)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if len(messageURLs(*msg)) != 0 || len(msg.Attachments) != 0 {
|
|
|
|
|
|
|
+ if len(urls) != 0 || len(msg.Attachments) != 0 {
|
|
|
help = append(help, cfg.Open.Keybind)
|
|
help = append(help, cfg.Open.Keybind)
|
|
|
}
|
|
}
|
|
|
if msg.Thread != nil {
|
|
if msg.Thread != nil {
|
|
@@ -1232,9 +1263,9 @@ func (ml *messagesList) FullHelp() [][]keybind.Keybind {
|
|
|
canDelete := false
|
|
canDelete := false
|
|
|
canOpen := false
|
|
canOpen := false
|
|
|
canOpenThread := false
|
|
canOpenThread := false
|
|
|
- if msg, err := ml.selectedMessage(); err == nil {
|
|
|
|
|
|
|
+ if urls, msg, ok := ml.cachedMessageURLs(); ok {
|
|
|
canSelectReply = msg.ReferencedMessage != nil
|
|
canSelectReply = msg.ReferencedMessage != nil
|
|
|
- canOpen = len(messageURLs(*msg)) != 0 || len(msg.Attachments) != 0
|
|
|
|
|
|
|
+ canOpen = len(urls) != 0 || len(msg.Attachments) != 0
|
|
|
canOpenThread = msg.Thread != nil
|
|
canOpenThread = msg.Thread != nil
|
|
|
|
|
|
|
|
if me, err := ml.chatView.state.Cabinet.Me(); err == nil {
|
|
if me, err := ml.chatView.state.Cabinet.Me(); err == nil {
|