refactor text styling to line/segment APIs and fix list selection
This commit is contained in:
parent
d86b2f6e60
commit
01fe923a34
7 changed files with 27 additions and 19 deletions
2
go.mod
2
go.mod
|
|
@ -7,7 +7,7 @@ go 1.25.3
|
|||
require (
|
||||
github.com/BurntSushi/toml v1.6.0
|
||||
github.com/andybalholm/brotli v1.2.0
|
||||
github.com/ayn2op/tview v0.0.0-20260208060151-4a4f3e6ac892
|
||||
github.com/ayn2op/tview v0.0.0-20260208071935-3324c648db69
|
||||
github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb
|
||||
github.com/diamondburned/arikawa/v3 v3.6.1-0.20250928004212-a891a653eb26
|
||||
github.com/diamondburned/ningen/v3 v3.0.1-0.20250920191746-98fbd92e134d
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -8,8 +8,8 @@ github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw=
|
|||
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/ayn2op/tview v0.0.0-20260208060151-4a4f3e6ac892 h1:lQHJobFgud7g57eKr7ODWRqW0CWuuPwLtITSmVYbbhQ=
|
||||
github.com/ayn2op/tview v0.0.0-20260208060151-4a4f3e6ac892/go.mod h1:g6IOdF9SlnVZMDnRABANP8I0LFseKyYxWqEkzBSL5ho=
|
||||
github.com/ayn2op/tview v0.0.0-20260208071935-3324c648db69 h1:DU0vNRmldUajM4tY5feFG/WsxaLhiPUHuWaQotmCLH8=
|
||||
github.com/ayn2op/tview v0.0.0-20260208071935-3324c648db69/go.mod h1:g6IOdF9SlnVZMDnRABANP8I0LFseKyYxWqEkzBSL5ho=
|
||||
github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ=
|
||||
github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ func (gt *guildsTree) createFolderNode(folder gateway.GuildFolder) {
|
|||
folderNode := tview.NewTreeNode(name).SetExpanded(gt.cfg.Theme.GuildsTree.AutoExpandFolders)
|
||||
if folder.Color != 0 {
|
||||
folderStyle := tcell.StyleDefault.Foreground(tcell.NewHexColor(int32(folder.Color)))
|
||||
folderNode.SetTextStyle(folderStyle)
|
||||
gt.setNodeLineStyle(folderNode, folderStyle)
|
||||
}
|
||||
gt.GetRoot().AddChild(folderNode)
|
||||
|
||||
|
|
@ -109,9 +109,8 @@ func (gt *guildsTree) getChannelNodeStyle(channelID discord.ChannelID) tcell.Sty
|
|||
}
|
||||
|
||||
func (gt *guildsTree) createGuildNode(n *tview.TreeNode, guild discord.Guild) {
|
||||
guildNode := tview.NewTreeNode(guild.Name).
|
||||
SetReference(guild.ID).
|
||||
SetTextStyle(gt.getGuildNodeStyle(guild.ID))
|
||||
guildNode := tview.NewTreeNode(guild.Name).SetReference(guild.ID)
|
||||
gt.setNodeLineStyle(guildNode, gt.getGuildNodeStyle(guild.ID))
|
||||
n.AddChild(guildNode)
|
||||
gt.guildNodeByID[guild.ID] = guildNode
|
||||
}
|
||||
|
|
@ -121,13 +120,20 @@ func (gt *guildsTree) createChannelNode(node *tview.TreeNode, channel discord.Ch
|
|||
return
|
||||
}
|
||||
|
||||
channelNode := tview.NewTreeNode(ui.ChannelToString(channel, gt.cfg.Icons)).
|
||||
SetReference(channel.ID).
|
||||
SetTextStyle(gt.getChannelNodeStyle(channel.ID))
|
||||
channelNode := tview.NewTreeNode(ui.ChannelToString(channel, gt.cfg.Icons)).SetReference(channel.ID)
|
||||
gt.setNodeLineStyle(channelNode, gt.getChannelNodeStyle(channel.ID))
|
||||
node.AddChild(channelNode)
|
||||
gt.channelNodeByID[channel.ID] = channelNode
|
||||
}
|
||||
|
||||
func (gt *guildsTree) setNodeLineStyle(node *tview.TreeNode, style tcell.Style) {
|
||||
line := node.GetLine()
|
||||
for i := range line {
|
||||
line[i].Style = style
|
||||
}
|
||||
node.SetLine(line)
|
||||
}
|
||||
|
||||
func (gt *guildsTree) createChannelNodes(node *tview.TreeNode, channels []discord.Channel) {
|
||||
// Preserve exact ordering semantics:
|
||||
// 1) top-level non-categories (in input order),
|
||||
|
|
@ -243,14 +249,16 @@ func (gt *guildsTree) onSelected(node *tview.TreeNode) {
|
|||
|
||||
hasNoPerm := channel.Type != discord.DirectMessage && channel.Type != discord.GroupDM && !gt.chatView.state.HasPermissions(channel.ID, discord.PermissionSendMessages)
|
||||
gt.chatView.messageInput.SetDisabled(hasNoPerm)
|
||||
var text string
|
||||
if hasNoPerm {
|
||||
gt.chatView.messageInput.SetPlaceholder("You do not have permission to send messages in this channel.")
|
||||
text = "You do not have permission to send messages in this channel."
|
||||
} else {
|
||||
gt.chatView.messageInput.SetPlaceholder("Message...")
|
||||
text = "Message..."
|
||||
if gt.cfg.AutoFocus {
|
||||
gt.chatView.app.SetFocus(gt.chatView.messageInput)
|
||||
}
|
||||
}
|
||||
gt.chatView.messageInput.SetPlaceholder(tview.NewLine(tview.NewSegment(text, tcell.StyleDefault.Dim(true))))
|
||||
case dmNode: // Direct messages folder
|
||||
channels, err := gt.chatView.state.PrivateChannels()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -51,15 +51,16 @@ func (m *mentionsList) rebuild() {
|
|||
item := m.items[index]
|
||||
style := item.style
|
||||
if index == cursor {
|
||||
style = style.Foreground(tview.Styles.PrimitiveBackgroundColor).Background(tview.Styles.PrimaryTextColor)
|
||||
style = style.Reverse(true)
|
||||
}
|
||||
line := tview.NewLine(tview.NewSegment(item.displayText, style))
|
||||
|
||||
return tview.NewTextView().
|
||||
SetScrollable(false).
|
||||
SetWrap(false).
|
||||
SetWordWrap(false).
|
||||
SetTextStyle(style).
|
||||
SetLines([]tview.Line{{{Text: item.displayText, Style: style}}})
|
||||
SetLines([]tview.Line{line})
|
||||
})
|
||||
|
||||
if len(m.items) == 0 {
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ func newMessageInput(cfg *config.Config, chatView *View) *messageInput {
|
|||
mi.Box = ui.ConfigureBox(mi.Box, &cfg.Theme)
|
||||
mi.SetInputCapture(mi.onInputCapture)
|
||||
mi.
|
||||
SetPlaceholder("Select a channel to start chatting").
|
||||
SetPlaceholderStyle(tcell.StyleDefault.Dim(true)).
|
||||
SetPlaceholder(tview.NewLine(tview.NewSegment("Select a channel to start chatting", tcell.StyleDefault.Dim(true)))).
|
||||
SetClipboard(
|
||||
func(s string) { clipboard.Write(clipboard.FmtText, []byte(s)) },
|
||||
func() string { return string(clipboard.Read(clipboard.FmtText)) },
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ func (v *View) onReadUpdate(event *read.UpdateEvent) {
|
|||
var updated bool
|
||||
if event.GuildID.IsValid() {
|
||||
if guildNode := v.guildsTree.findNodeByReference(event.GuildID); guildNode != nil {
|
||||
guildNode.SetTextStyle(v.guildsTree.getGuildNodeStyle(event.GuildID))
|
||||
v.guildsTree.setNodeLineStyle(guildNode, v.guildsTree.getGuildNodeStyle(event.GuildID))
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
|
|
@ -276,7 +276,7 @@ func (v *View) onReadUpdate(event *read.UpdateEvent) {
|
|||
// Channel style is always updated for the target channel regardless of
|
||||
// whether it's in a guild or DM.
|
||||
if channelNode := v.guildsTree.findNodeByReference(event.ChannelID); channelNode != nil {
|
||||
channelNode.SetTextStyle(v.guildsTree.getChannelNodeStyle(event.ChannelID))
|
||||
v.guildsTree.setNodeLineStyle(channelNode, v.guildsTree.getChannelNodeStyle(event.ChannelID))
|
||||
updated = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ func (p *Picker) setFilteredItems(filtered Items) {
|
|||
}
|
||||
style := tcell.StyleDefault
|
||||
if index == cursor {
|
||||
style = style.Foreground(tview.Styles.PrimitiveBackgroundColor).Background(tview.Styles.PrimaryTextColor)
|
||||
style = style.Reverse(true)
|
||||
}
|
||||
return tview.NewTextView().
|
||||
SetScrollable(false).
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue