refactor(ui): use event-driven startup and logout
This commit is contained in:
parent
aa6845949f
commit
41a6833b81
7 changed files with 87 additions and 39 deletions
|
|
@ -62,6 +62,7 @@ func Run() error {
|
|||
screen.EnablePaste()
|
||||
screen.EnableFocus()
|
||||
|
||||
tview.Styles = tview.Theme{}
|
||||
app := tview.NewApplication()
|
||||
app.SetRoot(root.NewView(cfg, app))
|
||||
app.SetScreen(screen)
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -10,7 +10,7 @@ require (
|
|||
github.com/BurntSushi/toml v1.6.0
|
||||
github.com/alecthomas/chroma/v2 v2.23.1
|
||||
github.com/andybalholm/brotli v1.2.0
|
||||
github.com/ayn2op/tview v0.0.0-20260304032402-f69fad13517e
|
||||
github.com/ayn2op/tview v0.0.0-20260304052427-7549865d186e
|
||||
github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb
|
||||
github.com/diamondburned/arikawa/v3 v3.6.1-0.20260226015332-783a3e8e8e86
|
||||
github.com/diamondburned/ningen/v3 v3.0.1-0.20260226220604-93f1e60c3cdb
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -14,8 +14,8 @@ github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs
|
|||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
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-20260304032402-f69fad13517e h1:xbfoet3RFg7bRY3MhRi5WfxhbLNoOlM+E+f83ABCfoM=
|
||||
github.com/ayn2op/tview v0.0.0-20260304032402-f69fad13517e/go.mod h1:lZ8RdOegQWBQafTOasGE7Ps1/Ymy4jmXoPt5vz2QsS0=
|
||||
github.com/ayn2op/tview v0.0.0-20260304052427-7549865d186e h1:fc5qHUJV+XYlYabsJtWW/AwbGLFu6XMFTiHXDViUBeM=
|
||||
github.com/ayn2op/tview v0.0.0-20260304052427-7549865d186e/go.mod h1:lZ8RdOegQWBQafTOasGE7Ps1/Ymy4jmXoPt5vz2QsS0=
|
||||
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=
|
||||
|
|
|
|||
11
internal/ui/chat/events.go
Normal file
11
internal/ui/chat/events.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package chat
|
||||
|
||||
import "github.com/gdamore/tcell/v3"
|
||||
|
||||
type LogoutEvent struct{ tcell.EventTime }
|
||||
|
||||
func NewLogoutEvent() *LogoutEvent {
|
||||
event := &LogoutEvent{}
|
||||
event.SetEventNow()
|
||||
return event
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ayn2op/discordo/internal/config"
|
||||
"github.com/ayn2op/discordo/internal/keyring"
|
||||
"github.com/ayn2op/discordo/internal/ui"
|
||||
"github.com/ayn2op/tview"
|
||||
"github.com/ayn2op/tview/help"
|
||||
|
|
@ -51,11 +50,9 @@ type View struct {
|
|||
app *tview.Application
|
||||
cfg *config.Config
|
||||
state *ningen.State
|
||||
|
||||
onLogout func()
|
||||
}
|
||||
|
||||
func NewView(app *tview.Application, cfg *config.Config, onLogout func()) *View {
|
||||
func NewView(app *tview.Application, cfg *config.Config) *View {
|
||||
v := &View{
|
||||
Layers: layers.New(),
|
||||
|
||||
|
|
@ -65,9 +62,8 @@ func NewView(app *tview.Application, cfg *config.Config, onLogout func()) *View
|
|||
|
||||
typers: make(map[discord.UserID]*time.Timer),
|
||||
|
||||
app: app,
|
||||
cfg: cfg,
|
||||
onLogout: onLogout,
|
||||
app: app,
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
v.guildsTree = newGuildsTree(cfg, v)
|
||||
|
|
@ -249,13 +245,10 @@ func (v *View) HandleEvent(event tcell.Event) tview.Command {
|
|||
v.focusNext()
|
||||
return redraw
|
||||
case keybind.Matches(event, v.cfg.Keybinds.Logout.Keybind):
|
||||
if v.onLogout != nil {
|
||||
v.onLogout()
|
||||
if err := v.CloseState(); err != nil {
|
||||
slog.Error("failed to close the session", "err", err)
|
||||
}
|
||||
if err := keyring.DeleteToken(); err != nil {
|
||||
slog.Error("failed to delete token from keyring", "err", err)
|
||||
}
|
||||
return redraw
|
||||
return tview.EventCommand(func() tcell.Event { return NewLogoutEvent() })
|
||||
case keybind.Matches(event, v.cfg.Keybinds.ToggleGuildsTree.Keybind):
|
||||
v.toggleGuildsTree()
|
||||
return redraw
|
||||
|
|
|
|||
49
internal/ui/root/events.go
Normal file
49
internal/ui/root/events.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package root
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/ayn2op/discordo/internal/clipboard"
|
||||
"github.com/ayn2op/discordo/internal/keyring"
|
||||
"github.com/gdamore/tcell/v3"
|
||||
)
|
||||
|
||||
type tokenEvent struct {
|
||||
tcell.EventTime
|
||||
token string
|
||||
}
|
||||
|
||||
func newTokenEvent(token string) *tokenEvent {
|
||||
event := &tokenEvent{token: token}
|
||||
event.SetEventNow()
|
||||
return event
|
||||
}
|
||||
|
||||
func getToken() tcell.Event {
|
||||
token := os.Getenv(tokenEnvVarKey)
|
||||
if token == "" {
|
||||
tok, err := keyring.GetToken()
|
||||
if err != nil {
|
||||
slog.Info("failed to retrieve token from keyring", "err", err)
|
||||
}
|
||||
token = tok
|
||||
}
|
||||
return newTokenEvent(token)
|
||||
}
|
||||
|
||||
func deleteToken() tcell.Event {
|
||||
if err := keyring.DeleteToken(); err != nil {
|
||||
slog.Error("failed to delete token from keyring", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initClipboard() tcell.Event {
|
||||
if err := clipboard.Init(); err != nil {
|
||||
slog.Error("failed to init clipboard", "err", err)
|
||||
return tcell.NewEventError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -2,12 +2,9 @@ package root
|
|||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/ayn2op/discordo/internal/clipboard"
|
||||
"github.com/ayn2op/discordo/internal/config"
|
||||
"github.com/ayn2op/discordo/internal/consts"
|
||||
"github.com/ayn2op/discordo/internal/keyring"
|
||||
"github.com/ayn2op/discordo/internal/ui/chat"
|
||||
"github.com/ayn2op/discordo/internal/ui/login"
|
||||
"github.com/ayn2op/tview"
|
||||
|
|
@ -26,17 +23,10 @@ type View struct {
|
|||
}
|
||||
|
||||
func NewView(cfg *config.Config, app *tview.Application) *View {
|
||||
tview.Styles = tview.Theme{}
|
||||
v := &View{
|
||||
return &View{
|
||||
app: app,
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
if err := clipboard.Init(); err != nil {
|
||||
slog.Error("failed to init clipboard", "err", err)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *View) showLoginView() {
|
||||
|
|
@ -45,11 +35,12 @@ func (v *View) showLoginView() {
|
|||
slog.Error("failed to show chat view", "err", err)
|
||||
}
|
||||
})
|
||||
v.chat = nil
|
||||
v.inner = loginForm
|
||||
}
|
||||
|
||||
func (v *View) showChatView(token string) error {
|
||||
v.chat = chat.NewView(v.app, v.cfg, v.showLoginView)
|
||||
v.chat = chat.NewView(v.app, v.cfg)
|
||||
if err := v.chat.OpenState(token); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -77,24 +68,27 @@ func (v *View) Draw(screen tcell.Screen) {
|
|||
func (v *View) HandleEvent(event tcell.Event) tview.Command {
|
||||
switch event := event.(type) {
|
||||
case *tview.InitEvent:
|
||||
token := os.Getenv(tokenEnvVarKey)
|
||||
if token == "" {
|
||||
tok, err := keyring.GetToken()
|
||||
if err != nil {
|
||||
slog.Info("failed to retrieve token from keyring", "err", err)
|
||||
}
|
||||
token = tok
|
||||
return tview.BatchCommand{
|
||||
tview.SetTitleCommand(consts.Name),
|
||||
tview.EventCommand(initClipboard),
|
||||
tview.EventCommand(getToken),
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
case *tokenEvent:
|
||||
if event.token == "" {
|
||||
v.showLoginView()
|
||||
} else {
|
||||
if err := v.showChatView(token); err != nil {
|
||||
if err := v.showChatView(event.token); err != nil {
|
||||
slog.Error("failed to show chat view", "err", err)
|
||||
return tview.QuitCommand{}
|
||||
}
|
||||
}
|
||||
return tview.BatchCommand{tview.SetTitleCommand(consts.Name), tview.SetFocusCommand{Target: v.inner}}
|
||||
return tview.BatchCommand{tview.SetFocusCommand{Target: v.inner}}
|
||||
case *chat.LogoutEvent:
|
||||
v.showLoginView()
|
||||
return tview.BatchCommand{
|
||||
tview.EventCommand(deleteToken),
|
||||
tview.SetFocusCommand{Target: v.inner},
|
||||
}
|
||||
|
||||
case *tview.KeyEvent:
|
||||
switch {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue