ソースを参照

refactor: layout -> app

ayn2op 1 年間 前
コミット
34158b2f9e
6 ファイル変更96 行追加101 行削除
  1. 46 46
      cmd/app.go
  2. 6 6
      cmd/guilds_tree.go
  3. 5 5
      cmd/message_input.go
  4. 17 17
      cmd/messages_text.go
  5. 3 3
      cmd/run.go
  6. 19 24
      cmd/state.go

+ 46 - 46
cmd/layout.go → cmd/app.go

@@ -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

+ 6 - 6
cmd/guilds_tree.go

@@ -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 {

+ 5 - 5
cmd/message_input.go

@@ -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() {

+ 17 - 17
cmd/messages_text.go

@@ -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)
 	}
 }

+ 3 - 3
cmd/run.go

@@ -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)
 }

+ 19 - 24
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)
 	}
 }