diff --git a/.gitignore b/.gitignore index 7888288..b529a72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ discordo* +.golangci* + # Visual Studio Code .vscode/ diff --git a/cmd/app.go b/cmd/application.go similarity index 84% rename from cmd/app.go rename to cmd/application.go index c355b7e..8ce7ba6 100644 --- a/cmd/app.go +++ b/cmd/application.go @@ -11,21 +11,21 @@ import ( "github.com/zalando/go-keyring" ) -type App struct { +type application struct { *tview.Application cfg *config.Config pages *tview.Pages flex *tview.Flex - guildsTree *GuildsTree - messagesText *MessagesText - messageInput *MessageInput + guildsTree *guildsTree + messagesText *messagesText + messageInput *messageInput } -func newApp(cfg *config.Config) *App { +func newApp(cfg *config.Config) *application { app := tview.NewApplication() - a := &App{ + a := &application{ Application: app, cfg: cfg, @@ -43,7 +43,7 @@ func newApp(cfg *config.Config) *App { return a } -func (app *App) show(token string) error { +func (app *application) show(token string) error { if token == "" { loginForm := login.NewForm(app.cfg, app.Application, func(token string) { if err := app.show(token); err != nil { @@ -65,7 +65,7 @@ func (app *App) show(token string) error { return nil } -func (app *App) run(token string) error { +func (app *application) run(token string) error { if err := app.show(token); err != nil { return err } @@ -73,13 +73,13 @@ func (app *App) run(token string) error { return app.Run() } -func (a *App) clearPages() { +func (a *application) clearPages() { for _, name := range a.pages.GetPageNames(false) { a.pages.RemovePage(name) } } -func (a *App) init() { +func (a *application) init() { a.clearPages() a.flex.Clear() @@ -93,7 +93,7 @@ func (a *App) init() { a.pages.AddAndSwitchToPage("flex", a.flex, true) } -func (app *App) onInputCapture(event *tcell.EventKey) *tcell.EventKey { +func (app *application) onInputCapture(event *tcell.EventKey) *tcell.EventKey { switch event.Name() { case app.cfg.Keys.Quit: if discordState != nil { @@ -111,7 +111,7 @@ func (app *App) onInputCapture(event *tcell.EventKey) *tcell.EventKey { return event } -func (app *App) onFlexInputCapture(event *tcell.EventKey) *tcell.EventKey { +func (app *application) onFlexInputCapture(event *tcell.EventKey) *tcell.EventKey { switch event.Name() { case app.cfg.Keys.FocusGuildsTree: app.SetFocus(app.guildsTree) diff --git a/cmd/guilds_tree.go b/cmd/guilds_tree.go index 37ec9df..9449bd6 100644 --- a/cmd/guilds_tree.go +++ b/cmd/guilds_tree.go @@ -15,15 +15,15 @@ import ( "github.com/rivo/tview" ) -type GuildsTree struct { +type guildsTree struct { *tview.TreeView cfg *config.Config app *tview.Application selectedChannelID discord.ChannelID } -func newGuildsTree(app *tview.Application, cfg *config.Config) *GuildsTree { - gt := &GuildsTree{ +func newGuildsTree(app *tview.Application, cfg *config.Config) *guildsTree { + gt := &guildsTree{ TreeView: tview.NewTreeView(), cfg: cfg, app: app, @@ -42,7 +42,7 @@ func newGuildsTree(app *tview.Application, cfg *config.Config) *GuildsTree { return gt } -func (gt *GuildsTree) createFolderNode(folder gateway.GuildFolder) { +func (gt *guildsTree) createFolderNode(folder gateway.GuildFolder) { var name string if folder.Name == "" { name = "Folder" @@ -66,14 +66,14 @@ func (gt *GuildsTree) createFolderNode(folder gateway.GuildFolder) { } } -func (gt *GuildsTree) createGuildNode(n *tview.TreeNode, g discord.Guild) { +func (gt *guildsTree) createGuildNode(n *tview.TreeNode, g discord.Guild) { guildNode := tview.NewTreeNode(g.Name) guildNode.SetReference(g.ID) guildNode.SetColor(tcell.GetColor(gt.cfg.Theme.GuildsTree.GuildColor)) n.AddChild(guildNode) } -func (gt *GuildsTree) channelToString(c discord.Channel) string { +func (gt *guildsTree) channelToString(c discord.Channel) string { switch c.Type { case discord.DirectMessage, discord.GroupDM: if c.Name != "" { @@ -102,7 +102,7 @@ func (gt *GuildsTree) channelToString(c discord.Channel) string { } } -func (gt *GuildsTree) createChannelNode(n *tview.TreeNode, c discord.Channel) *tview.TreeNode { +func (gt *guildsTree) createChannelNode(n *tview.TreeNode, c discord.Channel) *tview.TreeNode { if c.Type != discord.DirectMessage && c.Type != discord.GroupDM { ps, err := discordState.Permissions(c.ID, discordState.Ready().User.ID) if err != nil { @@ -122,7 +122,7 @@ func (gt *GuildsTree) createChannelNode(n *tview.TreeNode, c discord.Channel) *t return channelNode } -func (gt *GuildsTree) createChannelNodes(n *tview.TreeNode, cs []discord.Channel) { +func (gt *guildsTree) createChannelNodes(n *tview.TreeNode, cs []discord.Channel) { var orphanChs []discord.Channel for _, ch := range cs { if ch.Type != discord.GuildCategory && !ch.ParentID.IsValid() { @@ -165,7 +165,7 @@ PARENT_CHANNELS: } } -func (gt *GuildsTree) onSelected(n *tview.TreeNode) { +func (gt *guildsTree) onSelected(n *tview.TreeNode) { gt.selectedChannelID = 0 app.messagesText.reset() @@ -227,7 +227,7 @@ func (gt *GuildsTree) onSelected(n *tview.TreeNode) { } } -func (gt *GuildsTree) collapseParentNode(node *tview.TreeNode) { +func (gt *guildsTree) collapseParentNode(node *tview.TreeNode) { gt. GetRoot(). Walk(func(n, parent *tview.TreeNode) bool { @@ -241,7 +241,7 @@ func (gt *GuildsTree) collapseParentNode(node *tview.TreeNode) { }) } -func (gt *GuildsTree) onInputCapture(event *tcell.EventKey) *tcell.EventKey { +func (gt *guildsTree) onInputCapture(event *tcell.EventKey) *tcell.EventKey { switch event.Name() { case gt.cfg.Keys.GuildsTree.CollapseParentNode: gt.collapseParentNode(gt.GetCurrentNode()) diff --git a/cmd/message_input.go b/cmd/message_input.go index b079d3c..5cbb29c 100644 --- a/cmd/message_input.go +++ b/cmd/message_input.go @@ -19,15 +19,15 @@ import ( const tmpFilePattern = consts.Name + "_*.md" -type MessageInput struct { +type messageInput struct { *tview.TextArea cfg *config.Config app *tview.Application replyMessageID discord.MessageID } -func newMessageInput(app *tview.Application, cfg *config.Config) *MessageInput { - mi := &MessageInput{ +func newMessageInput(app *tview.Application, cfg *config.Config) *messageInput { + mi := &messageInput{ TextArea: tview.NewTextArea(), cfg: cfg, app: app, @@ -48,13 +48,13 @@ func newMessageInput(app *tview.Application, cfg *config.Config) *MessageInput { return mi } -func (mi *MessageInput) reset() { +func (mi *messageInput) reset() { mi.replyMessageID = 0 mi.SetTitle("") mi.SetText("", true) } -func (mi *MessageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey { +func (mi *messageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey { switch event.Name() { case mi.cfg.Keys.MessageInput.Send: mi.send() @@ -70,7 +70,7 @@ func (mi *MessageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey { return event } -func (mi *MessageInput) send() { +func (mi *messageInput) send() { if !app.guildsTree.selectedChannelID.IsValid() { return } @@ -105,7 +105,7 @@ func (mi *MessageInput) send() { app.messagesText.ScrollToEnd() } -func (mi *MessageInput) editor() { +func (mi *messageInput) editor() { e := mi.cfg.Editor if e == "default" { e = os.Getenv("EDITOR") diff --git a/cmd/messages_text.go b/cmd/messages_text.go index cee6b3c..1211c8a 100644 --- a/cmd/messages_text.go +++ b/cmd/messages_text.go @@ -26,7 +26,7 @@ import ( "github.com/yuin/goldmark/text" ) -type MessagesText struct { +type messagesText struct { *tview.TextView cfg *config.Config app *tview.Application @@ -39,8 +39,8 @@ type MessagesText struct { } } -func newMessagesText(app *tview.Application, cfg *config.Config) *MessagesText { - mt := &MessagesText{ +func newMessagesText(app *tview.Application, cfg *config.Config) *messagesText { + mt := &messagesText{ TextView: tview.NewTextView(), cfg: cfg, app: app, @@ -71,7 +71,7 @@ func newMessagesText(app *tview.Application, cfg *config.Config) *MessagesText { return mt } -func (mt *MessagesText) drawMsgs(cID discord.ChannelID) { +func (mt *messagesText) drawMsgs(cID discord.ChannelID) { ms, err := discordState.Messages(cID, uint(mt.cfg.MessagesLimit)) if err != nil { slog.Error("failed to get messages", "err", err, "channel_id", cID) @@ -89,7 +89,7 @@ func (mt *MessagesText) drawMsgs(cID discord.ChannelID) { } } -func (mt *MessagesText) reset() { +func (mt *messagesText) reset() { mt.selectedMessageID = 0 app.messageInput.replyMessageID = 0 @@ -100,16 +100,16 @@ func (mt *MessagesText) reset() { // Region tags are square brackets that contain a region ID in double quotes // https://pkg.go.dev/github.com/rivo/tview#hdr-Regions_and_Highlights -func (mt *MessagesText) startRegion(msgID discord.MessageID) { +func (mt *messagesText) startRegion(msgID discord.MessageID) { fmt.Fprintf(mt, `["%s"]`, msgID) } // Tags with no region ID ([""]) don't start new regions. They can therefore be used to mark the end of a region. -func (mt *MessagesText) endRegion() { +func (mt *messagesText) endRegion() { fmt.Fprint(mt, `[""]`) } -func (mt *MessagesText) createMsg(msg discord.Message) { +func (mt *messagesText) createMsg(msg discord.Message) { mt.startRegion(msg.ID) defer mt.endRegion() @@ -145,21 +145,21 @@ func (mt *MessagesText) createMsg(msg discord.Message) { fmt.Fprintln(mt) } -func (mt *MessagesText) formatTimestamp(ts discord.Timestamp) string { +func (mt *messagesText) formatTimestamp(ts discord.Timestamp) string { return ts.Time().In(time.Local).Format(mt.cfg.Timestamps.Format) } -func (mt *MessagesText) drawTimestamps(ts discord.Timestamp) { +func (mt *messagesText) drawTimestamps(ts discord.Timestamp) { fmt.Fprintf(mt, "[::d]%s[::D] ", mt.formatTimestamp(ts)) } -func (mt *MessagesText) drawAuthor(msg discord.Message) { +func (mt *messagesText) drawAuthor(msg discord.Message) { name := mt.authorName(msg.Author, msg.GuildID) color := mt.authorColor(msg.Author, msg.GuildID) fmt.Fprintf(mt, "[%s]%s[-] ", color, name) } -func (mt *MessagesText) drawContent(msg discord.Message) { +func (mt *messagesText) drawContent(msg discord.Message) { c := []byte(tview.Escape(msg.Content)) ast := discordmd.ParseWithMessage(c, *discordState.Cabinet, &msg, false) if app.cfg.MarkdownEnabled { @@ -169,13 +169,13 @@ func (mt *MessagesText) drawContent(msg discord.Message) { } } -func (mt *MessagesText) drawSnapshotContent(msg discord.MessageSnapshotMessage) { +func (mt *messagesText) drawSnapshotContent(msg discord.MessageSnapshotMessage) { c := []byte(tview.Escape(msg.Content)) // discordmd doesn't support MessageSnapshotMessage, so we just use write it as is. todo? mt.Write(c) } -func (mt *MessagesText) createDefaultMsg(msg discord.Message) { +func (mt *messagesText) createDefaultMsg(msg discord.Message) { if mt.cfg.Timestamps.Enabled { mt.drawTimestamps(msg.Timestamp) } @@ -197,7 +197,7 @@ func (mt *MessagesText) createDefaultMsg(msg discord.Message) { } } -func (mt *MessagesText) createReplyMsg(msg discord.Message) { +func (mt *messagesText) createReplyMsg(msg discord.Message) { // reply fmt.Fprintf(mt, "[::d]%s ", mt.cfg.Theme.MessagesText.ReplyIndicator) if refMsg := msg.ReferencedMessage; refMsg != nil { @@ -211,7 +211,7 @@ func (mt *MessagesText) createReplyMsg(msg discord.Message) { mt.createDefaultMsg(msg) } -func (mt *MessagesText) authorName(user discord.User, gID discord.GuildID) string { +func (mt *messagesText) authorName(user discord.User, gID discord.GuildID) string { name := user.DisplayOrUsername() if app.cfg.Theme.MessagesText.ShowNicknames && gID.IsValid() { // Use guild nickname if present @@ -223,7 +223,7 @@ func (mt *MessagesText) authorName(user discord.User, gID discord.GuildID) strin return name } -func (mt *MessagesText) createForwardedMsg(msg discord.Message) { +func (mt *messagesText) createForwardedMsg(msg discord.Message) { mt.drawTimestamps(msg.Timestamp) mt.drawAuthor(msg) fmt.Fprintf(mt, "[::d]%s [::-]", mt.cfg.Theme.MessagesText.ForwardedIndicator) @@ -231,7 +231,7 @@ func (mt *MessagesText) createForwardedMsg(msg discord.Message) { fmt.Fprintf(mt, " [::d](%s)[-:-:-] ", mt.formatTimestamp(msg.MessageSnapshots[0].Message.Timestamp)) } -func (mt *MessagesText) authorColor(user discord.User, gID discord.GuildID) string { +func (mt *messagesText) authorColor(user discord.User, gID discord.GuildID) string { color := mt.cfg.Theme.MessagesText.AuthorColor if app.cfg.Theme.MessagesText.ShowUsernameColors && gID.IsValid() { // Use color from highest role in guild @@ -243,7 +243,7 @@ func (mt *MessagesText) authorColor(user discord.User, gID discord.GuildID) stri return color } -func (mt *MessagesText) selectedMsg() (*discord.Message, error) { +func (mt *messagesText) selectedMsg() (*discord.Message, error) { if !mt.selectedMessageID.IsValid() { return nil, errors.New("no message is currently selected") } @@ -256,7 +256,7 @@ func (mt *MessagesText) selectedMsg() (*discord.Message, error) { return msg, nil } -func (mt *MessagesText) selectedMsgIndex() (int, error) { +func (mt *messagesText) selectedMsgIndex() (int, error) { ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID) if err != nil { return -1, err @@ -271,7 +271,7 @@ func (mt *MessagesText) selectedMsgIndex() (int, error) { return -1, nil } -func (mt *MessagesText) onInputCapture(event *tcell.EventKey) *tcell.EventKey { +func (mt *messagesText) onInputCapture(event *tcell.EventKey) *tcell.EventKey { switch event.Name() { case mt.cfg.Keys.MessagesText.Cancel: mt.selectedMessageID = 0 @@ -299,7 +299,7 @@ func (mt *MessagesText) onInputCapture(event *tcell.EventKey) *tcell.EventKey { return nil } -func (mt *MessagesText) _select(name string) { +func (mt *messagesText) _select(name string) { ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID) if err != nil { slog.Error("failed to get messages", "err", err, "channel_id", app.guildsTree.selectedChannelID) @@ -353,7 +353,7 @@ func (mt *MessagesText) _select(name string) { mt.ScrollToHighlight() } -func (mt *MessagesText) onHighlighted(added, removed, remaining []string) { +func (mt *messagesText) onHighlighted(added, removed, remaining []string) { if len(added) > 0 { id, err := discord.ParseSnowflake(added[0]) if err != nil { @@ -365,7 +365,7 @@ func (mt *MessagesText) onHighlighted(added, removed, remaining []string) { } } -func (mt *MessagesText) yankID() { +func (mt *messagesText) yankID() { msg, err := mt.selectedMsg() if err != nil { slog.Error("failed to get selected message", "err", err) @@ -377,7 +377,7 @@ func (mt *MessagesText) yankID() { } } -func (mt *MessagesText) yankContent() { +func (mt *messagesText) yankContent() { msg, err := mt.selectedMsg() if err != nil { slog.Error("failed to get selected message", "err", err) @@ -389,7 +389,7 @@ func (mt *MessagesText) yankContent() { } } -func (mt *MessagesText) yankURL() { +func (mt *messagesText) yankURL() { msg, err := mt.selectedMsg() if err != nil { slog.Error("failed to get selected message", "err", err) @@ -401,7 +401,7 @@ func (mt *MessagesText) yankURL() { } } -func (mt *MessagesText) open() { +func (mt *messagesText) open() { msg, err := mt.selectedMsg() if err != nil { slog.Error("failed to get selected message", "err", err) @@ -451,7 +451,7 @@ func extractURLs(content string) []string { return urls } -func (mt *MessagesText) showUrlSelector(urls []string, attachments []discord.Attachment) { +func (mt *messagesText) showUrlSelector(urls []string, attachments []discord.Attachment) { done := func() { app.pages.RemovePage("list").SwitchToPage("flex") app.SetFocus(app.messagesText) @@ -513,7 +513,7 @@ func openURL(url string) { } } -func (mt *MessagesText) reply(mention bool) { +func (mt *messagesText) reply(mention bool) { var title string if mention { title += "[@] Replying to " @@ -533,7 +533,7 @@ func (mt *MessagesText) reply(mention bool) { mt.app.SetFocus(app.messageInput) } -func (mt *MessagesText) delete() { +func (mt *messagesText) delete() { msg, err := mt.selectedMsg() if err != nil { slog.Error("failed to get selected message", "err", err) @@ -579,7 +579,7 @@ func (mt *MessagesText) delete() { } } -func (mt *MessagesText) requestGuildMembers(gID discord.GuildID, ms []discord.Message) { +func (mt *messagesText) requestGuildMembers(gID discord.GuildID, ms []discord.Message) { var usersToFetch []discord.UserID for _, m := range ms { if member, _ := discordState.Cabinet.Member(gID, m.Author.ID); member == nil { @@ -602,7 +602,7 @@ func (mt *MessagesText) requestGuildMembers(gID discord.GuildID, ms []discord.Me } } -func (mt *MessagesText) setFetchingChunk(value bool) { +func (mt *messagesText) setFetchingChunk(value bool) { mt.fetchingMembers.mu.Lock() defer mt.fetchingMembers.mu.Unlock() @@ -619,7 +619,7 @@ func (mt *MessagesText) setFetchingChunk(value bool) { } } -func (mt *MessagesText) waitForChunkEvent() { +func (mt *messagesText) waitForChunkEvent() { mt.fetchingMembers.mu.Lock() if !mt.fetchingMembers.value { mt.fetchingMembers.mu.Unlock() diff --git a/cmd/root.go b/cmd/root.go index 508b812..7a08081 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,8 +14,8 @@ import ( ) var ( - discordState *State - app *App + discordState *state + app *application ) func Run() error { diff --git a/cmd/state.go b/cmd/state.go index baea590..31ce3e3 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -15,7 +15,7 @@ import ( "github.com/rivo/tview" ) -type State struct { +type state struct { *ningen.State } @@ -34,7 +34,7 @@ func openState(token string) error { Status: app.cfg.Identify.Status, } - discordState = &State{ + discordState = &state{ State: ningen.New(token), } @@ -68,7 +68,7 @@ func openState(token string) error { return discordState.Open(context.TODO()) } -func (s *State) onRequest(r httpdriver.Request) error { +func (s *state) onRequest(r httpdriver.Request) error { req, ok := r.(*httpdriver.DefaultRequest) if ok { slog.Debug("new HTTP request", "method", req.Method, "url", req.URL) @@ -77,7 +77,7 @@ func (s *State) onRequest(r httpdriver.Request) error { return nil } -func (s *State) onReady(r *gateway.ReadyEvent) { +func (s *state) onReady(r *gateway.ReadyEvent) { root := app.guildsTree.GetRoot() root.ClearChildren() @@ -110,7 +110,7 @@ func (s *State) onReady(r *gateway.ReadyEvent) { app.SetFocus(app.guildsTree) } -func (s *State) onMessageCreate(m *gateway.MessageCreateEvent) { +func (s *state) onMessageCreate(m *gateway.MessageCreateEvent) { if app.guildsTree.selectedChannelID.IsValid() && app.guildsTree.selectedChannelID == m.ChannelID { app.messagesText.createMsg(m.Message) @@ -121,7 +121,7 @@ func (s *State) onMessageCreate(m *gateway.MessageCreateEvent) { } } -func (s *State) onMessageDelete(m *gateway.MessageDeleteEvent) { +func (s *state) onMessageDelete(m *gateway.MessageDeleteEvent) { if app.guildsTree.selectedChannelID == m.ChannelID { app.messagesText.selectedMessageID = 0 app.messagesText.Highlight()