ソースを参照

refactor(ui/chat): simplify pickers with ConfigurePicker (#773)

ayn2op 1 ヶ月 前
コミット
8806f87a46
5 ファイル変更54 行追加69 行削除
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 4 30
      internal/ui/chat/attachments_picker.go
  4. 7 35
      internal/ui/chat/channels_picker.go
  5. 40 1
      internal/ui/chat/util.go

+ 1 - 1
go.mod

@@ -11,7 +11,7 @@ require (
 	github.com/alecthomas/chroma/v2 v2.23.1
 	github.com/andybalholm/brotli v1.2.0
 	github.com/ayn2op/clipboard v0.0.0-20260308203959-c5ad7df3fc97
-	github.com/ayn2op/tview v0.0.0-20260318080250-5bddfb2ac264
+	github.com/ayn2op/tview v0.0.0-20260318094340-298d0ba151a8
 	github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb
 	github.com/diamondburned/arikawa/v3 v3.6.1-0.20260311205148-176ad9b9440f
 	github.com/diamondburned/ningen/v3 v3.0.1-0.20260306213430-5a08d3a709b4

+ 2 - 2
go.sum

@@ -16,8 +16,8 @@ github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwTo
 github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
 github.com/ayn2op/clipboard v0.0.0-20260308203959-c5ad7df3fc97 h1:WujETUV+v0DEJyZgjeLzQvihWyL80c0Tg4qf0dDo+Io=
 github.com/ayn2op/clipboard v0.0.0-20260308203959-c5ad7df3fc97/go.mod h1:3kFnpNCa3dF6WryzOMCDao7PfZ7DTCh+pievlfuwV80=
-github.com/ayn2op/tview v0.0.0-20260318080250-5bddfb2ac264 h1:UolGESVzxrK9JyGkpoc1sLZeIWDiMtCwRA8sRckqmrA=
-github.com/ayn2op/tview v0.0.0-20260318080250-5bddfb2ac264/go.mod h1:xgkca32kuEswK7Kzkfk3Pk24WHcKPjqK4xGmDi9QqOY=
+github.com/ayn2op/tview v0.0.0-20260318094340-298d0ba151a8 h1:po9BL01TxfLjrGARciJGuUMIlHFS7SCX0lE8Jxr6CHg=
+github.com/ayn2op/tview v0.0.0-20260318094340-298d0ba151a8/go.mod h1:xgkca32kuEswK7Kzkfk3Pk24WHcKPjqK4xGmDi9QqOY=
 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=

+ 4 - 30
internal/ui/chat/attachments_picker.go

@@ -2,11 +2,9 @@ package chat
 
 import (
 	"github.com/ayn2op/discordo/internal/config"
-	"github.com/ayn2op/discordo/internal/ui"
 	"github.com/ayn2op/tview"
 	"github.com/ayn2op/tview/help"
 	"github.com/ayn2op/tview/keybind"
-	"github.com/ayn2op/tview/list"
 	"github.com/ayn2op/tview/picker"
 )
 
@@ -30,45 +28,21 @@ func newAttachmentsPicker(cfg *config.Config, chatView *Model) *attachmentsPicke
 		cfg:      cfg,
 		chatView: chatView,
 	}
-	ap.Box = ui.ConfigureBox(tview.NewBox(), &cfg.Theme)
-	ap.
-		SetBlurFunc(nil).
-		SetFocusFunc(nil).
-		SetBorderSet(cfg.Theme.Border.ActiveSet.BorderSet).
-		SetBorderStyle(cfg.Theme.Border.ActiveStyle.Style).
-		SetTitleStyle(cfg.Theme.Title.ActiveStyle.Style).
-		SetFooterStyle(cfg.Theme.Footer.ActiveStyle.Style)
-
-	ap.SetTitle("Attachments")
-	ap.SetKeybinds(picker.Keybinds{
-		Cancel: cfg.Keybinds.Picker.Cancel.Keybind,
-		Keybinds: list.Keybinds{
-			SelectUp:     cfg.Keybinds.Picker.Up.Keybind,
-			SelectDown:   cfg.Keybinds.Picker.Down.Keybind,
-			SelectTop:    cfg.Keybinds.Picker.Top.Keybind,
-			SelectBottom: cfg.Keybinds.Picker.Bottom.Keybind,
-		},
-		Select: cfg.Keybinds.Picker.Select.Keybind,
-	})
-	ap.SetScrollBarVisibility(cfg.Theme.ScrollBar.Visibility.ScrollBarVisibility)
-	ap.SetScrollBar(tview.NewScrollBar().
-		SetTrackStyle(cfg.Theme.ScrollBar.TrackStyle.Style).
-		SetThumbStyle(cfg.Theme.ScrollBar.ThumbStyle.Style).
-		SetGlyphSet(cfg.Theme.ScrollBar.GlyphSet.GlyphSet))
+	ConfigurePicker(ap.Model, cfg, "Attachments")
 	return ap
 }
 
 func (ap *attachmentsPicker) SetItems(items []attachmentItem) {
 	ap.items = items
-	ap.ClearItems()
+	pickerItems := make(picker.Items, 0, len(items))
 	for i, item := range items {
-		ap.AddItem(picker.Item{
+		pickerItems = append(pickerItems, picker.Item{
 			Text:       item.label,
 			FilterText: item.label,
 			Reference:  i,
 		})
 	}
-	ap.Update()
+	ap.Model.SetItems(pickerItems)
 }
 
 func (ap *attachmentsPicker) close() {

+ 7 - 35
internal/ui/chat/channels_picker.go

@@ -9,7 +9,6 @@ import (
 	"github.com/ayn2op/tview"
 	"github.com/ayn2op/tview/help"
 	"github.com/ayn2op/tview/keybind"
-	"github.com/ayn2op/tview/list"
 	"github.com/ayn2op/tview/picker"
 	"github.com/diamondburned/arikawa/v3/discord"
 )
@@ -23,34 +22,7 @@ var _ help.KeyMap = (*channelsPicker)(nil)
 
 func newChannelsPicker(cfg *config.Config, chatView *Model) *channelsPicker {
 	cp := &channelsPicker{picker.NewModel(), chatView}
-	cp.Box = ui.ConfigureBox(tview.NewBox(), &cfg.Theme)
-	// When a child of the parent flex is focused, the parent layout itself is not reported as focused.
-	// Instead, the focused child (picker) is considered focused.
-	// Therefore, we manually set the active border style on the picker to ensure it displays the correct focused appearance.
-	cp.
-		SetBlurFunc(nil).
-		SetFocusFunc(nil).
-		SetBorderSet(cfg.Theme.Border.ActiveSet.BorderSet).
-		SetBorderStyle(cfg.Theme.Border.ActiveStyle.Style).
-		SetTitleStyle(cfg.Theme.Title.ActiveStyle.Style).
-		SetFooterStyle(cfg.Theme.Footer.ActiveStyle.Style)
-
-	cp.SetTitle("Channels")
-	cp.SetScrollBarVisibility(cfg.Theme.ScrollBar.Visibility.ScrollBarVisibility)
-	cp.SetScrollBar(tview.NewScrollBar().
-		SetTrackStyle(cfg.Theme.ScrollBar.TrackStyle.Style).
-		SetThumbStyle(cfg.Theme.ScrollBar.ThumbStyle.Style).
-		SetGlyphSet(cfg.Theme.ScrollBar.GlyphSet.GlyphSet))
-	cp.SetKeybinds(picker.Keybinds{
-		Cancel: cfg.Keybinds.Picker.Cancel.Keybind,
-		Keybinds: list.Keybinds{
-			SelectUp:     cfg.Keybinds.Picker.Up.Keybind,
-			SelectDown:   cfg.Keybinds.Picker.Down.Keybind,
-			SelectTop:    cfg.Keybinds.Picker.Top.Keybind,
-			SelectBottom: cfg.Keybinds.Picker.Bottom.Keybind,
-		},
-		Select: cfg.Keybinds.Picker.Select.Keybind,
-	})
+	ConfigurePicker(cp.Model, cfg, "Channels")
 	return cp
 }
 
@@ -90,7 +62,7 @@ func (cp *channelsPicker) HandleEvent(event tview.Event) tview.Command {
 }
 
 func (cp *channelsPicker) update() {
-	cp.ClearItems()
+	var items picker.Items
 	state := cp.chatView.state
 
 	privateChannels, err := state.Cabinet.PrivateChannels()
@@ -101,7 +73,7 @@ func (cp *channelsPicker) update() {
 
 	ui.SortPrivateChannels(privateChannels)
 	for _, channel := range privateChannels {
-		cp.addChannel(nil, channel)
+		items = append(items, cp.channelItem(nil, channel))
 	}
 
 	guilds, err := state.Cabinet.Guilds()
@@ -118,14 +90,14 @@ func (cp *channelsPicker) update() {
 		}
 
 		for _, channel := range channels {
-			cp.addChannel(&guild, channel)
+			items = append(items, cp.channelItem(&guild, channel))
 		}
 	}
 
-	cp.Update()
+	cp.Model.SetItems(items)
 }
 
-func (cp *channelsPicker) addChannel(guild *discord.Guild, channel discord.Channel) {
+func (cp *channelsPicker) channelItem(guild *discord.Guild, channel discord.Channel) picker.Item {
 	var b strings.Builder
 	b.WriteString(ui.ChannelToString(channel, cp.chatView.cfg.Icons, cp.chatView.state))
 
@@ -135,7 +107,7 @@ func (cp *channelsPicker) addChannel(guild *discord.Guild, channel discord.Chann
 	}
 
 	name := b.String()
-	cp.AddItem(picker.Item{Text: name, FilterText: name, Reference: channel.ID})
+	return picker.Item{Text: name, FilterText: name, Reference: channel.ID}
 }
 
 func (cp *channelsPicker) ShortHelp() []keybind.Keybind {

+ 40 - 1
internal/ui/chat/util.go

@@ -1,6 +1,45 @@
 package chat
 
-import "strings"
+import (
+	"strings"
+
+	"github.com/ayn2op/discordo/internal/config"
+	"github.com/ayn2op/discordo/internal/ui"
+	"github.com/ayn2op/tview"
+	"github.com/ayn2op/tview/list"
+	"github.com/ayn2op/tview/picker"
+)
+
+func ConfigurePicker(model *picker.Model, cfg *config.Config, title string) {
+	model.Box = ui.ConfigureBox(tview.NewBox(), &cfg.Theme)
+	// When a child of the parent flex is focused, the parent layout itself is not reported as focused.
+	// Instead, the focused child (picker) is considered focused.
+	// Therefore, we manually set the active border style on the picker to ensure it displays the correct focused appearance.
+	model.
+		SetBlurFunc(nil).
+		SetFocusFunc(nil).
+		SetBorderSet(cfg.Theme.Border.ActiveSet.BorderSet).
+		SetBorderStyle(cfg.Theme.Border.ActiveStyle.Style).
+		SetTitleStyle(cfg.Theme.Title.ActiveStyle.Style).
+		SetFooterStyle(cfg.Theme.Footer.ActiveStyle.Style)
+
+	model.SetTitle(title)
+	model.SetScrollBarVisibility(cfg.Theme.ScrollBar.Visibility.ScrollBarVisibility)
+	model.SetScrollBar(tview.NewScrollBar().
+		SetTrackStyle(cfg.Theme.ScrollBar.TrackStyle.Style).
+		SetThumbStyle(cfg.Theme.ScrollBar.ThumbStyle.Style).
+		SetGlyphSet(cfg.Theme.ScrollBar.GlyphSet.GlyphSet))
+	model.SetKeybinds(picker.Keybinds{
+		Cancel: cfg.Keybinds.Picker.Cancel.Keybind,
+		Keybinds: list.Keybinds{
+			SelectUp:     cfg.Keybinds.Picker.Up.Keybind,
+			SelectDown:   cfg.Keybinds.Picker.Down.Keybind,
+			SelectTop:    cfg.Keybinds.Picker.Top.Keybind,
+			SelectBottom: cfg.Keybinds.Picker.Bottom.Keybind,
+		},
+		Select: cfg.Keybinds.Picker.Select.Keybind,
+	})
+}
 
 func humanJoin(items []string) string {
 	count := len(items)