refactor(chat): extract attachments picker package
This commit is contained in:
parent
3e2222414a
commit
71805de597
9 changed files with 82 additions and 116 deletions
4
go.mod
4
go.mod
|
|
@ -10,7 +10,7 @@ require (
|
|||
github.com/andybalholm/brotli v1.2.2
|
||||
github.com/ayn2op/arikawa/v3 v3.0.0-20260708075022-9cc760fe507e
|
||||
github.com/ayn2op/ningen/v3 v3.0.1-0.20260708075321-0ba1ffc70bd6
|
||||
github.com/ayn2op/tview v0.0.0-20260803165347-d8123f4ec53c
|
||||
github.com/ayn2op/tview v0.0.0-20260805051036-f8d695faec51
|
||||
github.com/bogdanfinn/fhttp v0.6.8
|
||||
github.com/bogdanfinn/tls-client v1.15.1
|
||||
github.com/gdamore/tcell/v3 v3.4.1
|
||||
|
|
@ -56,7 +56,7 @@ require (
|
|||
golang.org/x/crypto v0.54.0 // indirect
|
||||
golang.org/x/exp/shiny v0.0.0-20260727155853-b88d891fe743 // indirect
|
||||
golang.org/x/image v0.44.0 // indirect
|
||||
golang.org/x/mobile v0.0.0-20260730202154-c700fe717e6e // indirect
|
||||
golang.org/x/mobile v0.0.0-20260803200217-62cee1672c8e // indirect
|
||||
golang.org/x/net v0.57.0 // indirect
|
||||
golang.org/x/sys v0.47.0 // indirect
|
||||
golang.org/x/term v0.45.0 // indirect
|
||||
|
|
|
|||
8
go.sum
8
go.sum
|
|
@ -14,8 +14,8 @@ github.com/ayn2op/arikawa/v3 v3.0.0-20260708075022-9cc760fe507e h1:rsMifRXwxkbha
|
|||
github.com/ayn2op/arikawa/v3 v3.0.0-20260708075022-9cc760fe507e/go.mod h1:gqklpHK7WHYTzpd1ZY6Ho/p9GURBghzBCzRiBYpaUP8=
|
||||
github.com/ayn2op/ningen/v3 v3.0.1-0.20260708075321-0ba1ffc70bd6 h1:/khHm6G+GWwXpmwA8bJoaXoUhubqMEUG6spjZsnklIw=
|
||||
github.com/ayn2op/ningen/v3 v3.0.1-0.20260708075321-0ba1ffc70bd6/go.mod h1:vqLIvETLkjc2vIgQzVEBqpGNCrgNe7YJqS9TUAJsXRI=
|
||||
github.com/ayn2op/tview v0.0.0-20260803165347-d8123f4ec53c h1:ApOfdF/YBJ+oy5zG5yJW/IbgCOoWcfJ/qukTnfFlUXc=
|
||||
github.com/ayn2op/tview v0.0.0-20260803165347-d8123f4ec53c/go.mod h1:bJZdl/FfspPLEW3nuX6ubt7YbmDoSj7f2IoWH37w1NE=
|
||||
github.com/ayn2op/tview v0.0.0-20260805051036-f8d695faec51 h1:hvyPcZcLG6dEAVXNpsMSWj93oJ1TIcDkJ+2eBcT1Yi0=
|
||||
github.com/ayn2op/tview v0.0.0-20260805051036-f8d695faec51/go.mod h1:bJZdl/FfspPLEW3nuX6ubt7YbmDoSj7f2IoWH37w1NE=
|
||||
github.com/bdandy/go-errors v1.2.2 h1:WdFv/oukjTJCLa79UfkGmwX7ZxONAihKu4V0mLIs11Q=
|
||||
github.com/bdandy/go-errors v1.2.2/go.mod h1:NkYHl4Fey9oRRdbB1CoC6e84tuqQHiqrOcZpqFEkBxM=
|
||||
github.com/bdandy/go-socks4 v1.2.3 h1:Q6Y2heY1GRjCtHbmlKfnwrKVU/k81LS8mRGLRlmDlic=
|
||||
|
|
@ -119,8 +119,8 @@ golang.org/x/exp/shiny v0.0.0-20260727155853-b88d891fe743 h1:rQLtGtwpYzQUyxCqrT3
|
|||
golang.org/x/exp/shiny v0.0.0-20260727155853-b88d891fe743/go.mod h1:JRiBNgSZB8uVKtHGrvbGDQ8p9Ghn3+lkFSk1KqRIiPc=
|
||||
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
|
||||
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
|
||||
golang.org/x/mobile v0.0.0-20260730202154-c700fe717e6e h1:v5PGTbI7uer7FhpDeGryGytfbI8t7CDWkKukozvIsNU=
|
||||
golang.org/x/mobile v0.0.0-20260730202154-c700fe717e6e/go.mod h1:YX+n47s+53POxN3dx9cIGxG3hGUm/lD64hvrRJFbcSA=
|
||||
golang.org/x/mobile v0.0.0-20260803200217-62cee1672c8e h1:hi1b7Lmv+xvnrjeEv8BoDmU7H/FAOuH7hEHSvjMl2VM=
|
||||
golang.org/x/mobile v0.0.0-20260803200217-62cee1672c8e/go.mod h1:YX+n47s+53POxN3dx9cIGxG3hGUm/lD64hvrRJFbcSA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
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/picker"
|
||||
)
|
||||
|
||||
type attachmentItem struct {
|
||||
label string
|
||||
open tview.Cmd
|
||||
}
|
||||
|
||||
type attachmentsPicker struct {
|
||||
*picker.Model
|
||||
cfg *config.Config
|
||||
chat *Model
|
||||
items []attachmentItem
|
||||
}
|
||||
|
||||
var _ help.KeyMap = (*attachmentsPicker)(nil)
|
||||
|
||||
func newAttachmentsPicker(cfg *config.Config, chat *Model) *attachmentsPicker {
|
||||
ap := &attachmentsPicker{Model: picker.NewModel(), cfg: cfg, chat: chat}
|
||||
ui.ConfigurePicker(ap.Model, cfg, "Attachments")
|
||||
return ap
|
||||
}
|
||||
|
||||
func (ap *attachmentsPicker) SetItems(items []attachmentItem) {
|
||||
ap.items = items
|
||||
pickerItems := make(picker.Items, 0, len(items))
|
||||
for i, item := range items {
|
||||
pickerItems = append(pickerItems, picker.Item{
|
||||
Text: item.label,
|
||||
FilterText: item.label,
|
||||
Reference: i,
|
||||
})
|
||||
}
|
||||
ap.Model.SetItems(pickerItems)
|
||||
}
|
||||
|
||||
func (ap *attachmentsPicker) close() tview.Cmd {
|
||||
|
||||
ap.chat.RemoveLayer(attachmentsPickerLayerName)
|
||||
return tview.SetFocus(ap.chat.messagesList)
|
||||
}
|
||||
|
||||
func (ap *attachmentsPicker) Update(msg tview.Msg) tview.Cmd {
|
||||
switch msg := msg.(type) {
|
||||
case picker.SelectedMsg:
|
||||
index, ok := msg.Reference.(int)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if index < 0 || index >= len(ap.items) {
|
||||
return nil
|
||||
}
|
||||
return tview.Sequence(ap.items[index].open, ap.close())
|
||||
case picker.CancelMsg:
|
||||
return ap.close()
|
||||
}
|
||||
|
||||
return ap.Model.Update(msg)
|
||||
}
|
||||
|
||||
func (ap *attachmentsPicker) ShortHelp() []keybind.Keybind {
|
||||
cfg := ap.cfg.Keybinds.Picker
|
||||
return []keybind.Keybind{cfg.SelectUp.Keybind, cfg.SelectDown.Keybind, cfg.Select.Keybind, cfg.Cancel.Keybind}
|
||||
}
|
||||
|
||||
func (ap *attachmentsPicker) FullHelp() [][]keybind.Keybind {
|
||||
cfg := ap.cfg.Keybinds.Picker
|
||||
return [][]keybind.Keybind{
|
||||
{cfg.SelectUp.Keybind, cfg.SelectDown.Keybind, cfg.SelectTop.Keybind, cfg.SelectBottom.Keybind},
|
||||
{cfg.Select.Keybind, cfg.Cancel.Keybind},
|
||||
}
|
||||
}
|
||||
44
internal/ui/chat/attachmentspicker/model.go
Normal file
44
internal/ui/chat/attachmentspicker/model.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package attachmentspicker
|
||||
|
||||
import (
|
||||
"github.com/ayn2op/discordo/internal/config"
|
||||
"github.com/ayn2op/discordo/internal/ui"
|
||||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/picker"
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
Label string
|
||||
Open tview.Cmd
|
||||
}
|
||||
|
||||
type Model struct{ *picker.Model }
|
||||
|
||||
func NewModel(cfg *config.Config) *Model {
|
||||
m := &Model{Model: picker.NewModel()}
|
||||
ui.ConfigurePicker(m.Model, cfg, "Attachments")
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Model) SetItems(items []Item) {
|
||||
pickerItems := make(picker.Items, len(items))
|
||||
for i, item := range items {
|
||||
pickerItems[i] = picker.Item{Text: item.Label, Reference: item.Open}
|
||||
}
|
||||
m.Model.SetItems(pickerItems)
|
||||
}
|
||||
|
||||
func (m *Model) Update(msg tview.Msg) tview.Cmd {
|
||||
switch msg := msg.(type) {
|
||||
case picker.SelectedMsg:
|
||||
open, ok := msg.Reference.(tview.Cmd)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return func() tview.Msg { return SelectedMsg{Open: open} }
|
||||
case picker.CancelMsg:
|
||||
return func() tview.Msg { return CancelMsg{} }
|
||||
}
|
||||
|
||||
return m.Model.Update(msg)
|
||||
}
|
||||
9
internal/ui/chat/attachmentspicker/msg.go
Normal file
9
internal/ui/chat/attachmentspicker/msg.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package attachmentspicker
|
||||
|
||||
import "github.com/ayn2op/tview"
|
||||
|
||||
type SelectedMsg struct {
|
||||
Open tview.Cmd
|
||||
}
|
||||
|
||||
type CancelMsg struct{}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package channelspicker
|
||||
|
||||
import (
|
||||
"github.com/ayn2op/tview/help"
|
||||
"github.com/ayn2op/tview/keybind"
|
||||
)
|
||||
|
||||
var _ help.KeyMap = (*Model)(nil)
|
||||
|
||||
func (m *Model) ShortHelp() []keybind.Keybind {
|
||||
cfg := m.cfg.Keybinds.Picker
|
||||
return []keybind.Keybind{cfg.SelectUp.Keybind, cfg.SelectDown.Keybind, cfg.Select.Keybind, cfg.Cancel.Keybind}
|
||||
}
|
||||
|
||||
func (m *Model) FullHelp() [][]keybind.Keybind {
|
||||
cfg := m.cfg.Keybinds.Picker
|
||||
return [][]keybind.Keybind{
|
||||
{cfg.SelectUp.Keybind, cfg.SelectDown.Keybind, cfg.SelectTop.Keybind, cfg.SelectBottom.Keybind},
|
||||
{cfg.Select.Keybind, cfg.Cancel.Keybind},
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,9 @@ func (m *Model) activeKeyMap() help.KeyMap {
|
|||
if m.GetVisible(channelsPickerLayerName) {
|
||||
return m.channelsPicker
|
||||
}
|
||||
if m.GetVisible(attachmentsPickerLayerName) {
|
||||
return m.messagesList.attachmentsPicker
|
||||
}
|
||||
|
||||
switch m.app.Focused() {
|
||||
case m.guildsTree:
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/ayn2op/discordo/internal/consts"
|
||||
"github.com/ayn2op/discordo/internal/markdown"
|
||||
"github.com/ayn2op/discordo/internal/ui"
|
||||
"github.com/ayn2op/discordo/internal/ui/chat/attachmentspicker"
|
||||
"github.com/ayn2op/ningen/v3/discordmd"
|
||||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/help"
|
||||
|
|
@ -54,7 +55,7 @@ type messagesList struct {
|
|||
// itemByID caches rendered message TextViews.
|
||||
itemByID map[discord.MessageID]*tview.TextView
|
||||
|
||||
attachmentsPicker *attachmentsPicker
|
||||
attachmentsPicker *attachmentspicker.Model
|
||||
}
|
||||
|
||||
var _ help.KeyMap = (*messagesList)(nil)
|
||||
|
|
@ -80,7 +81,7 @@ func newMessagesList(cfg *config.Config, chat *Model) *messagesList {
|
|||
renderer: markdown.NewRenderer(cfg),
|
||||
itemByID: make(map[discord.MessageID]*tview.TextView),
|
||||
}
|
||||
ml.attachmentsPicker = newAttachmentsPicker(cfg, chat)
|
||||
ml.attachmentsPicker = attachmentspicker.NewModel(cfg)
|
||||
|
||||
ui.ConfigureBox(ml.Box, &cfg.Theme)
|
||||
ml.SetTitle("Messages")
|
||||
|
|
@ -1166,23 +1167,23 @@ func messageURLs(msg discord.Message) []string {
|
|||
}
|
||||
|
||||
func (ml *messagesList) showAttachmentsList(urls []string, attachments []discord.Attachment) tview.Cmd {
|
||||
var items []attachmentItem
|
||||
var items []attachmentspicker.Item
|
||||
for _, a := range attachments {
|
||||
attachment := a
|
||||
open := ml.openURL(attachment.URL)
|
||||
if strings.HasPrefix(attachment.ContentType, "image/") {
|
||||
open = ml.openAttachment(attachment)
|
||||
}
|
||||
items = append(items, attachmentItem{
|
||||
label: attachment.Filename,
|
||||
open: open,
|
||||
items = append(items, attachmentspicker.Item{
|
||||
Label: attachment.Filename,
|
||||
Open: open,
|
||||
})
|
||||
}
|
||||
for _, u := range urls {
|
||||
url := u
|
||||
items = append(items, attachmentItem{
|
||||
label: url,
|
||||
open: ml.openURL(url),
|
||||
items = append(items, attachmentspicker.Item{
|
||||
Label: url,
|
||||
Open: ml.openURL(url),
|
||||
})
|
||||
}
|
||||
ml.attachmentsPicker.SetItems(items)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
clientgateway "github.com/ayn2op/discordo/internal/gateway"
|
||||
"github.com/ayn2op/discordo/internal/http"
|
||||
"github.com/ayn2op/discordo/internal/ui"
|
||||
"github.com/ayn2op/discordo/internal/ui/chat/attachmentspicker"
|
||||
"github.com/ayn2op/discordo/internal/ui/chat/channelspicker"
|
||||
"github.com/ayn2op/ningen/v3"
|
||||
"github.com/ayn2op/ningen/v3/states/read"
|
||||
|
|
@ -170,6 +171,11 @@ func (m *Model) closePicker() {
|
|||
m.channelsPicker.Refresh()
|
||||
}
|
||||
|
||||
func (m *Model) closeAttachmentsPicker() tview.Cmd {
|
||||
m.RemoveLayer(attachmentsPickerLayerName)
|
||||
return tview.SetFocus(m.messagesList)
|
||||
}
|
||||
|
||||
func (m *Model) navigateToChannel(channelID discord.ChannelID) tview.Cmd {
|
||||
channel, err := m.state.Cabinet.Channel(channelID)
|
||||
if err != nil {
|
||||
|
|
@ -354,6 +360,10 @@ func (m *Model) Update(msg tview.Msg) tview.Cmd {
|
|||
case channelspicker.CancelMsg:
|
||||
m.closePicker()
|
||||
return nil
|
||||
case attachmentspicker.SelectedMsg:
|
||||
return tview.Sequence(msg.Open, m.closeAttachmentsPicker())
|
||||
case attachmentspicker.CancelMsg:
|
||||
return m.closeAttachmentsPicker()
|
||||
case QuitMsg:
|
||||
return m.closeState()
|
||||
case tview.KeyMsg:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue