feat(messageslist): add option to show user status on messages (#454)
This commit is contained in:
parent
eb4028957d
commit
f68958f75c
5 changed files with 50 additions and 0 deletions
|
|
@ -367,6 +367,12 @@ The number of empty rows between messages, except those of a group.
|
||||||
|
|
||||||
Default: `1`
|
Default: `1`
|
||||||
|
|
||||||
|
### ui.messages_list.show_user_status
|
||||||
|
|
||||||
|
Whether to show the author's presence status dot alongside their name.
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
### ui.messages_list.reply_indicator
|
### ui.messages_list.reply_indicator
|
||||||
|
|
||||||
Default: `">"`
|
Default: `">"`
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,9 @@ type (
|
||||||
// The number of empty rows between messages, except those of a group.
|
// The number of empty rows between messages, except those of a group.
|
||||||
Spacing uint8 `toml:"spacing"`
|
Spacing uint8 `toml:"spacing"`
|
||||||
|
|
||||||
|
// Whether to show the author's presence status dot alongside their name.
|
||||||
|
ShowUserStatus bool `toml:"show_user_status"`
|
||||||
|
|
||||||
ReplyIndicator string `toml:"reply_indicator"`
|
ReplyIndicator string `toml:"reply_indicator"`
|
||||||
ForwardedIndicator string `toml:"forwarded_indicator"`
|
ForwardedIndicator string `toml:"forwarded_indicator"`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,14 @@ func (m Model) drawCozy(builder *markdown.Builder, message discord.Message, base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const statusMarker = "●"
|
||||||
|
|
||||||
func (m Model) drawAuthor(builder *markdown.Builder, message discord.Message, baseStyle tview.Style) {
|
func (m Model) drawAuthor(builder *markdown.Builder, message discord.Message, baseStyle tview.Style) {
|
||||||
|
if m.cfg.UI.MessagesList.ShowUserStatus && !message.WebhookID.IsValid() {
|
||||||
|
status := m.status(message.GuildID, message.Author.ID)
|
||||||
|
builder.Write(statusMarker+" ", m.cfg.Theme.MembersTree.StatusStyle(status))
|
||||||
|
}
|
||||||
|
|
||||||
name := message.Author.DisplayOrUsername()
|
name := message.Author.DisplayOrUsername()
|
||||||
foreground := tcell.ColorDefault
|
foreground := tcell.ColorDefault
|
||||||
|
|
||||||
|
|
@ -211,6 +218,17 @@ func (m Model) memberForMessage(message discord.Message) *discord.Member {
|
||||||
return member
|
return member
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Model) status(guildID discord.GuildID, userID discord.UserID) discord.Status {
|
||||||
|
if m.state == nil || m.state.Cabinet == nil {
|
||||||
|
return discord.OfflineStatus
|
||||||
|
}
|
||||||
|
presence, err := m.state.Cabinet.Presence(guildID, userID)
|
||||||
|
if err != nil {
|
||||||
|
return discord.OfflineStatus
|
||||||
|
}
|
||||||
|
return presence.Status
|
||||||
|
}
|
||||||
|
|
||||||
// drawContent renders the message body. root is its parsed content, or nil to parse it here.
|
// drawContent renders the message body. root is its parsed content, or nil to parse it here.
|
||||||
func (m Model) drawContent(builder *markdown.Builder, message discord.Message, root ast.Node, baseStyle tview.Style) {
|
func (m Model) drawContent(builder *markdown.Builder, message discord.Message, root ast.Node, baseStyle tview.Style) {
|
||||||
if root == nil && m.cfg.Markdown.Enabled {
|
if root == nil && m.cfg.Markdown.Enabled {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/ayn2op/arikawa/v3/discord"
|
"github.com/ayn2op/arikawa/v3/discord"
|
||||||
"github.com/ayn2op/arikawa/v3/state"
|
"github.com/ayn2op/arikawa/v3/state"
|
||||||
"github.com/ayn2op/discordo/internal/config"
|
"github.com/ayn2op/discordo/internal/config"
|
||||||
|
"github.com/ayn2op/discordo/internal/markdown"
|
||||||
"github.com/ayn2op/ningen/v3"
|
"github.com/ayn2op/ningen/v3"
|
||||||
"github.com/ayn2op/tview"
|
"github.com/ayn2op/tview"
|
||||||
tviewimage "github.com/ayn2op/tview/image"
|
tviewimage "github.com/ayn2op/tview/image"
|
||||||
|
|
@ -401,3 +402,22 @@ func TestModelReactionsView(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModelShowUserStatus(t *testing.T) {
|
||||||
|
cfg := testConfig(t)
|
||||||
|
cfg.UI.MessagesList.ShowUserStatus = true
|
||||||
|
ml := newTestModel(t, cfg)
|
||||||
|
user := discord.User{ID: 10, Username: "alice"}
|
||||||
|
_ = ml.state.PresenceSet(discord.NullGuildID, &discord.Presence{User: user, Status: discord.OnlineStatus}, false)
|
||||||
|
|
||||||
|
msg := discord.Message{ID: 1, Author: user, Content: "hello"}
|
||||||
|
builder := new(markdown.Builder)
|
||||||
|
ml.drawAuthor(builder, msg, tcell.StyleDefault)
|
||||||
|
spans := builder.Finish()
|
||||||
|
if len(spans) == 0 {
|
||||||
|
t.Fatal("expected spans from drawAuthor")
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(spans[0].Text, statusMarker) {
|
||||||
|
t.Fatalf("first span text = %q, want statusMarker %q", spans[0].Text, statusMarker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ func (m *Model) applyEvent(event gateway.Event) tview.Cmd {
|
||||||
case *gateway.MessageUpdateEvent:
|
case *gateway.MessageUpdateEvent:
|
||||||
return m.messagesList.UpdateMessage(event.Message)
|
return m.messagesList.UpdateMessage(event.Message)
|
||||||
case *gateway.PresenceUpdateEvent:
|
case *gateway.PresenceUpdateEvent:
|
||||||
|
if m.cfg.UI.MessagesList.ShowUserStatus {
|
||||||
|
m.messagesList.InvalidateRendered()
|
||||||
|
}
|
||||||
return tview.Batch(m.updatePane(paneGuildsTree, event), m.updatePane(paneMembersTree, event))
|
return tview.Batch(m.updatePane(paneGuildsTree, event), m.updatePane(paneMembersTree, event))
|
||||||
case *gateway.GuildMemberListUpdateEvent:
|
case *gateway.GuildMemberListUpdateEvent:
|
||||||
return m.updatePane(paneMembersTree, event)
|
return m.updatePane(paneMembersTree, event)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue