refactor(ui,picker)!: upgrade tview to latest and use newer api (#771)
This commit is contained in:
parent
ee8439bc0a
commit
6167d7d3d8
20 changed files with 50 additions and 53 deletions
2
go.mod
2
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-20260315074416-50a7d9c11304
|
||||
github.com/ayn2op/tview v0.0.0-20260318010246-0993cedfe0c2
|
||||
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
|
||||
|
|
|
|||
4
go.sum
4
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-20260315074416-50a7d9c11304 h1:IbClNDuGoPrJtP4WkKr/iLXIxsR1WKSSJH46wLM0azM=
|
||||
github.com/ayn2op/tview v0.0.0-20260315074416-50a7d9c11304/go.mod h1:IXZrCv1VAZyWPdKDUJYs9ZYFiJ1GmCQUo9tLjQWoSnU=
|
||||
github.com/ayn2op/tview v0.0.0-20260318010246-0993cedfe0c2 h1:AMOGrvQ1+TnDRuKC2Jnr+H1WL4bq8GSNd2GDxvy3dig=
|
||||
github.com/ayn2op/tview v0.0.0-20260318010246-0993cedfe0c2/go.mod h1:IXZrCv1VAZyWPdKDUJYs9ZYFiJ1GmCQUo9tLjQWoSnU=
|
||||
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=
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/help"
|
||||
"github.com/ayn2op/tview/keybind"
|
||||
"github.com/gdamore/tcell/v3"
|
||||
)
|
||||
|
||||
type attachmentItem struct {
|
||||
|
|
@ -74,7 +73,7 @@ func (ap *attachmentsPicker) close() {
|
|||
ap.chatView.app.SetFocus(ap.chatView.messagesList)
|
||||
}
|
||||
|
||||
func (ap *attachmentsPicker) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (ap *attachmentsPicker) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *picker.SelectedEvent:
|
||||
index, ok := event.Reference.(int)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/ayn2op/tview/help"
|
||||
"github.com/ayn2op/tview/keybind"
|
||||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
"github.com/gdamore/tcell/v3"
|
||||
)
|
||||
|
||||
type channelsPicker struct {
|
||||
|
|
@ -52,7 +51,7 @@ func newChannelsPicker(cfg *config.Config, chatView *Model) *channelsPicker {
|
|||
return cp
|
||||
}
|
||||
|
||||
func (cp *channelsPicker) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (cp *channelsPicker) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *picker.SelectedEvent:
|
||||
channelID, ok := event.Reference.(discord.ChannelID)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
type LogoutEvent struct{ tcell.EventTime }
|
||||
|
||||
func (m *Model) logout() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
return &LogoutEvent{}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ func (m *Model) logout() tview.Command {
|
|||
type QuitEvent struct{ tcell.EventTime }
|
||||
|
||||
func (m *Model) closeState() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if m.state != nil {
|
||||
if err := m.state.Close(); err != nil {
|
||||
slog.Error("failed to close the session", "err", err)
|
||||
|
|
@ -35,7 +35,7 @@ type closeLayerEvent struct {
|
|||
}
|
||||
|
||||
func closeLayer(name string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
return &closeLayerEvent{name: name}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ func (gt *guildsTree) collapseParentNode(node *tview.TreeNode) {
|
|||
})
|
||||
}
|
||||
|
||||
func (gt *guildsTree) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (gt *guildsTree) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.TreeViewSelectedEvent:
|
||||
gt.onSelected(event.Node)
|
||||
|
|
@ -437,7 +437,7 @@ func (gt *guildsTree) yankID() tview.Command {
|
|||
// Reference of a tree node in the guilds tree is its ID.
|
||||
// discord.Snowflake (discord.GuildID and discord.ChannelID) have the String method.
|
||||
if id, ok := node.GetReference().(fmt.Stringer); ok {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := clipboard.Write(clipboard.FmtText, []byte(id.String())); err != nil {
|
||||
slog.Error("failed to copy node id", "err", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func (mi *messageInput) stopTypingTimer() {
|
|||
}
|
||||
}
|
||||
|
||||
func (mi *messageInput) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (mi *messageInput) HandleEvent(event tview.Event) tview.Command {
|
||||
handler := mi.TextArea.HandleEvent
|
||||
switch event := event.(type) {
|
||||
case *tview.KeyEvent:
|
||||
|
|
|
|||
|
|
@ -838,7 +838,7 @@ func (ml *messagesList) selectedMessage() (*discord.Message, error) {
|
|||
return &ml.messages[cursor], nil
|
||||
}
|
||||
|
||||
func (ml *messagesList) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (ml *messagesList) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.KeyEvent:
|
||||
switch {
|
||||
|
|
@ -1018,7 +1018,7 @@ func (ml *messagesList) yankMessageID() tview.Command {
|
|||
return nil
|
||||
}
|
||||
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := clipboard.Write(clipboard.FmtText, []byte(msg.ID.String())); err != nil {
|
||||
slog.Error("failed to copy message id", "err", err)
|
||||
}
|
||||
|
|
@ -1033,7 +1033,7 @@ func (ml *messagesList) yankContent() tview.Command {
|
|||
return nil
|
||||
}
|
||||
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := clipboard.Write(clipboard.FmtText, []byte(msg.Content)); err != nil {
|
||||
slog.Error("failed to copy message content", "err", err)
|
||||
}
|
||||
|
|
@ -1048,7 +1048,7 @@ func (ml *messagesList) yankURL() tview.Command {
|
|||
return nil
|
||||
}
|
||||
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := clipboard.Write(clipboard.FmtText, []byte(msg.URL())); err != nil {
|
||||
slog.Error("failed to copy message url", "err", err)
|
||||
}
|
||||
|
|
@ -1289,7 +1289,7 @@ func (ml *messagesList) deleteSelectedMessage() tview.Command {
|
|||
return nil
|
||||
}
|
||||
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if selectedMessage.GuildID.IsValid() {
|
||||
me, _ := ml.chatView.state.Cabinet.Me()
|
||||
if selectedMessage.Author.ID != me.ID && !ml.chatView.state.HasPermissions(selectedMessage.ChannelID, discord.PermissionManageMessages) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ type Model struct {
|
|||
typers map[discord.UserID]*time.Timer
|
||||
|
||||
confirmModalDone func(label string)
|
||||
confirmModalPreviousFocus tview.Primitive
|
||||
confirmModalPreviousFocus tview.Model
|
||||
|
||||
app *tview.Application
|
||||
cfg *config.Config
|
||||
|
|
@ -216,10 +216,10 @@ func (m *Model) focusNext() tview.Command {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (m *Model) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.InitEvent:
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := m.OpenState(m.token); err != nil {
|
||||
slog.Error("failed to open chat state", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func setClipboard(content string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := clipboard.Write(clipboard.FmtText, []byte(content)); err != nil {
|
||||
slog.Error("failed to copy error message", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ func NewModel(cfg *config.Config) *Model {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (m *Model) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tcell.EventError:
|
||||
if m.HasLayer(errorLayerName) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ type connCreateEvent struct {
|
|||
type connCloseEvent struct{ tcell.EventTime }
|
||||
|
||||
func (m *Model) connect() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
headers := http.Headers()
|
||||
headers.Set("User-Agent", http.BrowserUserAgent)
|
||||
conn, _, err := websocket.DefaultDialer.Dial(remoteAuthGatewayURL, headers)
|
||||
|
|
@ -46,7 +46,7 @@ func (m *Model) connect() tview.Command {
|
|||
}
|
||||
|
||||
func (m *Model) close() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if m.conn != nil {
|
||||
if err := m.conn.Close(); err != nil {
|
||||
return tcell.NewEventError(err)
|
||||
|
|
@ -85,7 +85,7 @@ type pendingLoginEvent struct {
|
|||
type cancelEvent struct{ tcell.EventTime }
|
||||
|
||||
func (m *Model) listen() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if m.conn == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -155,14 +155,14 @@ func (m *Model) listen() tview.Command {
|
|||
type heartbeatTickEvent struct{ tcell.EventTime }
|
||||
|
||||
func (m *Model) heartbeat() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
time.Sleep(m.heartbeatInterval)
|
||||
return &heartbeatTickEvent{}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Model) sendHeartbeat() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if m.conn == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ type privateKeyEvent struct {
|
|||
}
|
||||
|
||||
func (m *Model) generatePrivateKey() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return tcell.NewEventError(err)
|
||||
|
|
@ -192,7 +192,7 @@ func (m *Model) generatePrivateKey() tview.Command {
|
|||
}
|
||||
|
||||
func (m *Model) sendInit() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if m.privateKey == nil {
|
||||
return tcell.NewEventError(errors.New("missing private key"))
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ func (m *Model) sendInit() tview.Command {
|
|||
}
|
||||
|
||||
func (m *Model) sendNonceProof(encryptedNonce string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
decodedNonce, err := base64.StdEncoding.DecodeString(encryptedNonce)
|
||||
if err != nil {
|
||||
return tcell.NewEventError(err)
|
||||
|
|
@ -242,7 +242,7 @@ type qrCodeEvent struct {
|
|||
}
|
||||
|
||||
func (m *Model) generateQRCode(fingerprint string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
content := "https://discord.com/ra/" + fingerprint
|
||||
qrCode, err := qrcode.New(content, qrcode.Low)
|
||||
if err != nil {
|
||||
|
|
@ -260,7 +260,7 @@ type userEvent struct {
|
|||
}
|
||||
|
||||
func (m *Model) decryptUserPayload(encryptedPayload string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
decodedPayload, err := base64.StdEncoding.DecodeString(encryptedPayload)
|
||||
if err != nil {
|
||||
return tcell.NewEventError(err)
|
||||
|
|
@ -281,7 +281,7 @@ func (m *Model) decryptUserPayload(encryptedPayload string) tview.Command {
|
|||
}
|
||||
|
||||
func (m *Model) exchangeTicket(ticket string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
headers := http.Headers()
|
||||
headers.Set("Referer", "https://discord.com/login")
|
||||
if m.fingerprint != "" {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func (m *Model) Label() string {
|
|||
return "QR"
|
||||
}
|
||||
|
||||
func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (m *Model) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.InitEvent:
|
||||
m.msg = "Connecting to Remote Auth Gateway..."
|
||||
|
|
@ -103,7 +103,7 @@ func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
|||
|
||||
case *tcell.EventError:
|
||||
m.msg = event.Error()
|
||||
return tview.Batch(m.close(), tview.Command(func() tcell.Event { return event }))
|
||||
return tview.Batch(m.close(), tview.Command(func() tview.Event { return event }))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ type TokenEvent struct {
|
|||
}
|
||||
|
||||
func tokenCommand(token string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
return &TokenEvent{Token: token}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package token
|
|||
import (
|
||||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/tabs"
|
||||
"github.com/gdamore/tcell/v3"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
|
|
@ -23,7 +22,7 @@ func (m *Model) Label() string {
|
|||
return "Token"
|
||||
}
|
||||
|
||||
func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (m *Model) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event.(type) {
|
||||
case *tview.FormSubmitEvent:
|
||||
token := m.GetFormItem(0).(*tview.InputField).GetText()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type tokenEvent struct {
|
|||
}
|
||||
|
||||
func tokenCommand(token string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
return &tokenEvent{token: token}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ func tokenCommand(token string) tview.Command {
|
|||
type loginEvent struct{ tcell.EventTime }
|
||||
|
||||
func getToken() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
token, err := keyring.GetToken()
|
||||
if err != nil {
|
||||
slog.Info("failed to retrieve token from keyring", "err", err)
|
||||
|
|
@ -34,7 +34,7 @@ func getToken() tview.Command {
|
|||
}
|
||||
|
||||
func setToken(token string) tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := keyring.SetToken(token); err != nil {
|
||||
slog.Error("failed to set token to keyring", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
|
|
@ -44,7 +44,7 @@ func setToken(token string) tview.Command {
|
|||
}
|
||||
|
||||
func deleteToken() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := keyring.DeleteToken(); err != nil {
|
||||
slog.Error("failed to delete token from keyring", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
|
|
@ -54,7 +54,7 @@ func deleteToken() tview.Command {
|
|||
}
|
||||
|
||||
func initClipboard() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
if err := clipboard.Init(); err != nil {
|
||||
slog.Error("failed to init clipboard", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const tokenEnvVarKey = "DISCORDO_TOKEN"
|
|||
type Model struct {
|
||||
app *tview.Application
|
||||
rootFlex *flex.Model // inner + help
|
||||
inner tview.Primitive
|
||||
inner tview.Model
|
||||
help *help.Help
|
||||
|
||||
cfg *config.Config
|
||||
|
|
@ -74,13 +74,13 @@ func (m *Model) buildLayout() {
|
|||
m.updateHelpHeight()
|
||||
}
|
||||
|
||||
var _ tview.Primitive = (*Model)(nil)
|
||||
var _ tview.Model = (*Model)(nil)
|
||||
|
||||
func (m *Model) Draw(screen tcell.Screen) {
|
||||
m.rootFlex.Draw(screen)
|
||||
}
|
||||
|
||||
func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (m *Model) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.InitEvent:
|
||||
var cmd tview.Command
|
||||
|
|
@ -151,7 +151,7 @@ func (m *Model) SetRect(x int, y int, width int, height int) {
|
|||
m.rootFlex.SetRect(x, y, width, height)
|
||||
}
|
||||
|
||||
func (m *Model) Focus(delegate func(p tview.Primitive)) {
|
||||
func (m *Model) Focus(delegate func(tview.Model)) {
|
||||
if m.inner != nil {
|
||||
delegate(m.inner)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ func ConfigureBox(box *tview.Box, cfg *config.Theme) *tview.Box {
|
|||
}
|
||||
|
||||
// Centered creates a new grid with provided primitive aligned in the center.
|
||||
func Centered(p tview.Primitive, width, height int) tview.Primitive {
|
||||
func Centered(m tview.Model, width, height int) tview.Model {
|
||||
return tview.NewGrid().
|
||||
SetColumns(0, width, 0).
|
||||
SetRows(0, height, 0).
|
||||
AddItem(p, 1, 1, 1, 1, 0, 0, true)
|
||||
AddItem(m, 1, 1, 1, 1, 0, 0, true)
|
||||
}
|
||||
|
||||
func ChannelToString(channel discord.Channel, icons config.Icons, state *ningen.State) string {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ func (m *Model) _select() tview.Command {
|
|||
index := m.list.Cursor()
|
||||
if index >= 0 && index < len(m.filtered) {
|
||||
item := m.filtered[index]
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
return newSelectedEvent(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ func (m *Model) _select() tview.Command {
|
|||
type CancelEvent struct{ tcell.EventTime }
|
||||
|
||||
func cancel() tview.Command {
|
||||
return func() tcell.Event {
|
||||
return func() tview.Event {
|
||||
return &CancelEvent{}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ func (m *Model) onInputChanged(text string) {
|
|||
m.setFilteredItems(fuzzied)
|
||||
}
|
||||
|
||||
func (m *Model) HandleEvent(event tcell.Event) tview.Command {
|
||||
func (m *Model) HandleEvent(event tview.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.KeyEvent:
|
||||
if m.keyMap != nil {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue