refactor: layout -> app
This commit is contained in:
parent
bad44a4490
commit
34158b2f9e
6 changed files with 96 additions and 101 deletions
|
|
@ -11,20 +11,22 @@ import (
|
|||
"github.com/zalando/go-keyring"
|
||||
)
|
||||
|
||||
type Layout struct {
|
||||
type App struct {
|
||||
*tview.Application
|
||||
|
||||
cfg *config.Config
|
||||
app *tview.Application
|
||||
flex *tview.Flex
|
||||
guildsTree *GuildsTree
|
||||
messagesText *MessagesText
|
||||
messageInput *MessageInput
|
||||
}
|
||||
|
||||
func newLayout(cfg *config.Config) *Layout {
|
||||
func newApp(cfg *config.Config) *App {
|
||||
app := tview.NewApplication()
|
||||
l := &Layout{
|
||||
a := &App{
|
||||
Application: app,
|
||||
|
||||
cfg: cfg,
|
||||
app: app,
|
||||
flex: tview.NewFlex(),
|
||||
|
||||
guildsTree: newGuildsTree(app, cfg),
|
||||
|
|
@ -32,66 +34,64 @@ func newLayout(cfg *config.Config) *Layout {
|
|||
messageInput: newMessageInput(app, cfg),
|
||||
}
|
||||
|
||||
l.init()
|
||||
|
||||
l.app.EnableMouse(cfg.Mouse)
|
||||
l.app.SetInputCapture(l.onAppInputCapture)
|
||||
|
||||
l.flex.SetInputCapture(l.onFlexInputCapture)
|
||||
return l
|
||||
a.init()
|
||||
a.EnableMouse(cfg.Mouse)
|
||||
a.SetInputCapture(a.onInputCapture)
|
||||
a.flex.SetInputCapture(a.onFlexInputCapture)
|
||||
return a
|
||||
}
|
||||
|
||||
func (l *Layout) show(token string) error {
|
||||
func (app *App) show(token string) error {
|
||||
if token == "" {
|
||||
loginForm := login.NewForm(l.app, func(token string) {
|
||||
if err := l.show(token); err != nil {
|
||||
loginForm := login.NewForm(app.Application, func(token string) {
|
||||
if err := app.show(token); err != nil {
|
||||
slog.Error("failed to show app", "err", err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
l.app.SetRoot(loginForm, true)
|
||||
app.SetRoot(loginForm, true)
|
||||
} else {
|
||||
if err := openState(token, l.app, l.cfg); err != nil {
|
||||
if err := openState(token); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.app.SetRoot(l.flex, true)
|
||||
app.SetRoot(app.flex, true)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Layout) run(token string) error {
|
||||
if err := l.show(token); err != nil {
|
||||
func (app *App) run(token string) error {
|
||||
if err := app.show(token); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return l.app.Run()
|
||||
return app.Run()
|
||||
}
|
||||
|
||||
func (l *Layout) init() {
|
||||
l.flex.Clear()
|
||||
func (app *App) init() {
|
||||
app.flex.Clear()
|
||||
|
||||
right := tview.NewFlex()
|
||||
right.SetDirection(tview.FlexRow)
|
||||
right.AddItem(l.messagesText, 0, 1, false)
|
||||
right.AddItem(l.messageInput, 3, 1, false)
|
||||
right.AddItem(app.messagesText, 0, 1, false)
|
||||
right.AddItem(app.messageInput, 3, 1, false)
|
||||
// The guilds tree is always focused first at start-up.
|
||||
l.flex.AddItem(l.guildsTree, 0, 1, true)
|
||||
l.flex.AddItem(right, 0, 4, false)
|
||||
app.flex.AddItem(app.guildsTree, 0, 1, true)
|
||||
app.flex.AddItem(right, 0, 4, false)
|
||||
}
|
||||
|
||||
func (l *Layout) onAppInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
func (app *App) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
switch event.Name() {
|
||||
case l.cfg.Keys.Quit:
|
||||
case app.cfg.Keys.Quit:
|
||||
if discordState != nil {
|
||||
if err := discordState.Close(); err != nil {
|
||||
slog.Error("failed to close the session", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
l.app.Stop()
|
||||
app.Stop()
|
||||
case "Ctrl+C":
|
||||
// https://github.com/rivo/tview/blob/a64fc48d7654432f71922c8b908280cdb525805c/application.go#L153
|
||||
return tcell.NewEventKey(tcell.KeyCtrlC, 0, tcell.ModNone)
|
||||
|
|
@ -100,19 +100,19 @@ func (l *Layout) onAppInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
|||
return event
|
||||
}
|
||||
|
||||
func (l *Layout) onFlexInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
func (app *App) onFlexInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
switch event.Name() {
|
||||
case l.cfg.Keys.FocusGuildsTree:
|
||||
l.app.SetFocus(l.guildsTree)
|
||||
case app.cfg.Keys.FocusGuildsTree:
|
||||
app.SetFocus(app.guildsTree)
|
||||
return nil
|
||||
case l.cfg.Keys.FocusMessagesText:
|
||||
l.app.SetFocus(l.messagesText)
|
||||
case app.cfg.Keys.FocusMessagesText:
|
||||
app.SetFocus(app.messagesText)
|
||||
return nil
|
||||
case l.cfg.Keys.FocusMessageInput:
|
||||
l.app.SetFocus(l.messageInput)
|
||||
case app.cfg.Keys.FocusMessageInput:
|
||||
app.SetFocus(app.messageInput)
|
||||
return nil
|
||||
case l.cfg.Keys.Logout:
|
||||
l.app.Stop()
|
||||
case app.cfg.Keys.Logout:
|
||||
app.Stop()
|
||||
|
||||
if err := keyring.Delete(consts.Name, "token"); err != nil {
|
||||
slog.Error("failed to delete token from keyring", "err", err)
|
||||
|
|
@ -120,17 +120,17 @@ func (l *Layout) onFlexInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
|
||||
return nil
|
||||
case l.cfg.Keys.ToggleGuildsTree:
|
||||
case app.cfg.Keys.ToggleGuildsTree:
|
||||
// The guilds tree is visible if the numbers of items is two.
|
||||
if l.flex.GetItemCount() == 2 {
|
||||
l.flex.RemoveItem(l.guildsTree)
|
||||
if app.flex.GetItemCount() == 2 {
|
||||
app.flex.RemoveItem(app.guildsTree)
|
||||
|
||||
if l.guildsTree.HasFocus() {
|
||||
l.app.SetFocus(l.flex)
|
||||
if app.guildsTree.HasFocus() {
|
||||
app.SetFocus(app.flex)
|
||||
}
|
||||
} else {
|
||||
l.init()
|
||||
l.app.SetFocus(l.guildsTree)
|
||||
app.init()
|
||||
app.SetFocus(app.guildsTree)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -175,8 +175,8 @@ PARENT_CHANNELS:
|
|||
func (gt *GuildsTree) onSelected(n *tview.TreeNode) {
|
||||
gt.selectedChannelID = 0
|
||||
|
||||
layout.messagesText.reset()
|
||||
layout.messageInput.reset()
|
||||
app.messagesText.reset()
|
||||
app.messageInput.reset()
|
||||
|
||||
if len(n.GetChildren()) != 0 {
|
||||
n.SetExpanded(!n.IsExpanded())
|
||||
|
|
@ -197,8 +197,8 @@ func (gt *GuildsTree) onSelected(n *tview.TreeNode) {
|
|||
|
||||
gt.createChannelNodes(n, cs)
|
||||
case discord.ChannelID:
|
||||
layout.messagesText.drawMsgs(ref)
|
||||
layout.messagesText.ScrollToEnd()
|
||||
app.messagesText.drawMsgs(ref)
|
||||
app.messagesText.ScrollToEnd()
|
||||
|
||||
c, err := discordState.Cabinet.Channel(ref)
|
||||
if err != nil {
|
||||
|
|
@ -206,10 +206,10 @@ func (gt *GuildsTree) onSelected(n *tview.TreeNode) {
|
|||
return
|
||||
}
|
||||
|
||||
layout.messagesText.SetTitle(gt.channelToString(*c))
|
||||
app.messagesText.SetTitle(gt.channelToString(*c))
|
||||
|
||||
gt.selectedChannelID = ref
|
||||
gt.app.SetFocus(layout.messageInput)
|
||||
gt.app.SetFocus(app.messageInput)
|
||||
case nil: // Direct messages
|
||||
cs, err := discordState.PrivateChannels()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func (mi *MessageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
|
||||
func (mi *MessageInput) send() {
|
||||
if !layout.guildsTree.selectedChannelID.IsValid() {
|
||||
if !app.guildsTree.selectedChannelID.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -99,16 +99,16 @@ func (mi *MessageInput) send() {
|
|||
}
|
||||
|
||||
go func() {
|
||||
if _, err := discordState.SendMessageComplex(layout.guildsTree.selectedChannelID, data); err != nil {
|
||||
slog.Error("failed to send message in channel", "channel_id", layout.guildsTree.selectedChannelID, "err", err)
|
||||
if _, err := discordState.SendMessageComplex(app.guildsTree.selectedChannelID, data); err != nil {
|
||||
slog.Error("failed to send message in channel", "channel_id", app.guildsTree.selectedChannelID, "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
mi.replyMessageID = 0
|
||||
mi.reset()
|
||||
|
||||
layout.messagesText.Highlight()
|
||||
layout.messagesText.ScrollToEnd()
|
||||
app.messagesText.Highlight()
|
||||
app.messagesText.ScrollToEnd()
|
||||
}
|
||||
|
||||
func (mi *MessageInput) editor() {
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ func (mt *MessagesText) drawMsgs(cID discord.ChannelID) {
|
|||
}
|
||||
|
||||
for _, m := range slices.Backward(ms) {
|
||||
layout.messagesText.createMessage(m)
|
||||
app.messagesText.createMessage(m)
|
||||
}
|
||||
}
|
||||
|
||||
func (mt *MessagesText) reset() {
|
||||
layout.messagesText.selectedMessageID = 0
|
||||
app.messagesText.selectedMessageID = 0
|
||||
|
||||
mt.SetTitle("")
|
||||
mt.Clear()
|
||||
|
|
@ -172,7 +172,7 @@ func (mt *MessagesText) getSelectedMessage() (*discord.Message, error) {
|
|||
return nil, errors.New("no message is currently selected")
|
||||
}
|
||||
|
||||
msg, err := discordState.Cabinet.Message(layout.guildsTree.selectedChannelID, mt.selectedMessageID)
|
||||
msg, err := discordState.Cabinet.Message(app.guildsTree.selectedChannelID, mt.selectedMessageID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not retrieve selected message: %w", err)
|
||||
}
|
||||
|
|
@ -181,7 +181,7 @@ func (mt *MessagesText) getSelectedMessage() (*discord.Message, error) {
|
|||
}
|
||||
|
||||
func (mt *MessagesText) getSelectedMessageIndex() (int, error) {
|
||||
ms, err := discordState.Cabinet.Messages(layout.guildsTree.selectedChannelID)
|
||||
ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
|
@ -215,9 +215,9 @@ func (mt *MessagesText) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
|
||||
func (mt *MessagesText) _select(name string) {
|
||||
ms, err := discordState.Cabinet.Messages(layout.guildsTree.selectedChannelID)
|
||||
ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID)
|
||||
if err != nil {
|
||||
slog.Error("failed to get messages", "err", err, "channel_id", layout.guildsTree.selectedChannelID)
|
||||
slog.Error("failed to get messages", "err", err, "channel_id", app.guildsTree.selectedChannelID)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -341,9 +341,9 @@ func (mt *MessagesText) reply(mention bool) {
|
|||
}
|
||||
|
||||
title += msg.Author.Tag()
|
||||
layout.messageInput.SetTitle(title)
|
||||
layout.messageInput.replyMessageID = mt.selectedMessageID
|
||||
mt.app.SetFocus(layout.messageInput)
|
||||
app.messageInput.SetTitle(title)
|
||||
app.messageInput.replyMessageID = mt.selectedMessageID
|
||||
mt.app.SetFocus(app.messageInput)
|
||||
}
|
||||
|
||||
func (mt *MessagesText) delete() {
|
||||
|
|
@ -355,7 +355,7 @@ func (mt *MessagesText) delete() {
|
|||
|
||||
clientID := discordState.Ready().User.ID
|
||||
if msg.GuildID.IsValid() {
|
||||
ps, err := discordState.Permissions(layout.guildsTree.selectedChannelID, discordState.Ready().User.ID)
|
||||
ps, err := discordState.Permissions(app.guildsTree.selectedChannelID, discordState.Ready().User.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -369,25 +369,25 @@ func (mt *MessagesText) delete() {
|
|||
}
|
||||
}
|
||||
|
||||
if err := discordState.DeleteMessage(layout.guildsTree.selectedChannelID, msg.ID, ""); err != nil {
|
||||
slog.Error("failed to delete message", "err", err, "channel_id", layout.guildsTree.selectedChannelID, "message_id", msg.ID)
|
||||
if err := discordState.DeleteMessage(app.guildsTree.selectedChannelID, msg.ID, ""); err != nil {
|
||||
slog.Error("failed to delete message", "err", err, "channel_id", app.guildsTree.selectedChannelID, "message_id", msg.ID)
|
||||
return
|
||||
}
|
||||
|
||||
if err := discordState.MessageRemove(layout.guildsTree.selectedChannelID, msg.ID); err != nil {
|
||||
slog.Error("failed to delete message", "err", err, "channel_id", layout.guildsTree.selectedChannelID, "message_id", msg.ID)
|
||||
if err := discordState.MessageRemove(app.guildsTree.selectedChannelID, msg.ID); err != nil {
|
||||
slog.Error("failed to delete message", "err", err, "channel_id", app.guildsTree.selectedChannelID, "message_id", msg.ID)
|
||||
return
|
||||
}
|
||||
|
||||
ms, err := discordState.Cabinet.Messages(layout.guildsTree.selectedChannelID)
|
||||
ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID)
|
||||
if err != nil {
|
||||
slog.Error("failed to delete message", "err", err, "channel_id", layout.guildsTree.selectedChannelID)
|
||||
slog.Error("failed to delete message", "err", err, "channel_id", app.guildsTree.selectedChannelID)
|
||||
return
|
||||
}
|
||||
|
||||
mt.Clear()
|
||||
|
||||
for _, m := range slices.Backward(ms) {
|
||||
layout.messagesText.createMessage(m)
|
||||
app.messagesText.createMessage(m)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
var (
|
||||
discordState *State
|
||||
layout *Layout
|
||||
app *App
|
||||
)
|
||||
|
||||
func Run(token string) error {
|
||||
|
|
@ -34,6 +34,6 @@ func Run(token string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
layout = newLayout(cfg)
|
||||
return layout.run(token)
|
||||
app = newApp(cfg)
|
||||
return app.run(token)
|
||||
}
|
||||
|
|
|
|||
43
cmd/state.go
43
cmd/state.go
|
|
@ -6,7 +6,6 @@ import (
|
|||
"runtime"
|
||||
"slices"
|
||||
|
||||
"github.com/ayn2op/discordo/internal/config"
|
||||
"github.com/diamondburned/arikawa/v3/api"
|
||||
"github.com/diamondburned/arikawa/v3/discord"
|
||||
"github.com/diamondburned/arikawa/v3/gateway"
|
||||
|
|
@ -18,29 +17,25 @@ import (
|
|||
|
||||
type State struct {
|
||||
*ningen.State
|
||||
cfg *config.Config
|
||||
app *tview.Application
|
||||
}
|
||||
|
||||
func openState(token string, app *tview.Application, cfg *config.Config) error {
|
||||
api.UserAgent = cfg.UserAgent
|
||||
func openState(token string) error {
|
||||
api.UserAgent = app.cfg.UserAgent
|
||||
gateway.DefaultIdentity = gateway.IdentifyProperties{
|
||||
OS: runtime.GOOS,
|
||||
Device: "",
|
||||
|
||||
Browser: cfg.Browser,
|
||||
BrowserVersion: cfg.BrowserVersion,
|
||||
BrowserUserAgent: cfg.UserAgent,
|
||||
Browser: app.cfg.Browser,
|
||||
BrowserVersion: app.cfg.BrowserVersion,
|
||||
BrowserUserAgent: app.cfg.UserAgent,
|
||||
}
|
||||
|
||||
gateway.DefaultPresence = &gateway.UpdatePresenceCommand{
|
||||
Status: cfg.Status,
|
||||
Status: app.cfg.Status,
|
||||
}
|
||||
|
||||
discordState = &State{
|
||||
State: ningen.New(token),
|
||||
cfg: cfg,
|
||||
app: app,
|
||||
}
|
||||
|
||||
// Handlers
|
||||
|
|
@ -62,11 +57,11 @@ func (s *State) onRequest(r httpdriver.Request) error {
|
|||
}
|
||||
|
||||
func (s *State) onReady(r *gateway.ReadyEvent) {
|
||||
root := layout.guildsTree.GetRoot()
|
||||
root := app.guildsTree.GetRoot()
|
||||
root.ClearChildren()
|
||||
|
||||
dmNode := tview.NewTreeNode("Direct Messages")
|
||||
dmNode.SetColor(tcell.GetColor(s.cfg.Theme.GuildsTree.PrivateChannelColor))
|
||||
dmNode.SetColor(tcell.GetColor(app.cfg.Theme.GuildsTree.PrivateChannelColor))
|
||||
root.AddChild(dmNode)
|
||||
|
||||
// Track guilds that have a parent (folder) to add orphan channels later
|
||||
|
|
@ -78,32 +73,32 @@ func (s *State) onReady(r *gateway.ReadyEvent) {
|
|||
}
|
||||
folderGuildIds = append(folderGuildIds, folder.GuildIDs...)
|
||||
|
||||
layout.guildsTree.createFolderNode(folder)
|
||||
app.guildsTree.createFolderNode(folder)
|
||||
}
|
||||
|
||||
// add orphan (without folder) guilds to guilds tree
|
||||
for _, guild := range r.Guilds {
|
||||
if !slices.Contains(folderGuildIds, guild.ID) {
|
||||
layout.guildsTree.createGuildNode(root, guild.Guild)
|
||||
app.guildsTree.createGuildNode(root, guild.Guild)
|
||||
}
|
||||
}
|
||||
|
||||
layout.guildsTree.SetCurrentNode(root)
|
||||
s.app.SetFocus(layout.guildsTree)
|
||||
app.guildsTree.SetCurrentNode(root)
|
||||
app.SetFocus(app.guildsTree)
|
||||
}
|
||||
|
||||
func (s *State) onMessageCreate(m *gateway.MessageCreateEvent) {
|
||||
if layout.guildsTree.selectedChannelID.IsValid() && layout.guildsTree.selectedChannelID == m.ChannelID {
|
||||
layout.messagesText.createMessage(m.Message)
|
||||
if app.guildsTree.selectedChannelID.IsValid() && app.guildsTree.selectedChannelID == m.ChannelID {
|
||||
app.messagesText.createMessage(m.Message)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) onMessageDelete(m *gateway.MessageDeleteEvent) {
|
||||
if layout.guildsTree.selectedChannelID == m.ChannelID {
|
||||
layout.messagesText.selectedMessageID = 0
|
||||
layout.messagesText.Highlight()
|
||||
layout.messagesText.Clear()
|
||||
if app.guildsTree.selectedChannelID == m.ChannelID {
|
||||
app.messagesText.selectedMessageID = 0
|
||||
app.messagesText.Highlight()
|
||||
app.messagesText.Clear()
|
||||
|
||||
layout.messagesText.drawMsgs(m.ChannelID)
|
||||
app.messagesText.drawMsgs(m.ChannelID)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue