### Keybind Configuration Example Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/configuration.md Example of how to configure keyboard shortcuts for actions. Keybinds can be set as a single string or an array of strings for multiple key combinations. ```toml key = ["ctrl+x", "cmd+x"] ``` -------------------------------- ### Complete Discordo Configuration Example Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/configuration.md A comprehensive example showcasing various configuration options for Discordo, including general settings, markdown, help, picker, timestamps, notifications, and sidebar markers. ```toml auto_focus = true mouse = true editor = "vim" status = "online" hide_blocked_users = true show_attachment_links = true autocomplete_limit = 20 messages_limit = 50 [markdown] enabled = true theme = "monokai" [help] compact_modifiers = true padding = [1, 1] separator = " • " [picker] width = 80 height = 25 [timestamps] enabled = true format = "3:04PM" [date_separator] enabled = true format = "January 2, 2006" character = "─" [notifications] enabled = true duration = 0 [notifications.sound] enabled = true only_on_ping = true [typing_indicator] send = true receive = true [sidebar.markers] expanded = "▾ " collapsed = "▸ " leaf = "" [sidebar.indents] dm = 2 group_dm = 1 guild = 2 category = 1 channel = 2 forum = 2 [icons] guild_category = "" guild_text = "#" guild_voice = "♪ " # ... rest of icons # ... keybinds and theme sections ``` -------------------------------- ### Startup Flow Example Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/10-ui-root.md Illustrates the sequence of calls during the application's startup, highlighting the initialization of the root model. ```go cmd.Run() → tcell.NewScreen() → tview.NewApplication() → root.NewModel() // ← You are here → app.SetRoot() → app.Run() → sends tview.InitMsg → root.Update() checks env/keyring → showLogin() or showChat() ``` -------------------------------- ### Install Discordo with Scoop Source: https://github.com/ayn2op/discordo/blob/main/README.md Installs Discordo using the Scoop package manager on Windows. Ensure you have Scoop installed and have added the necessary bucket. ```bash scoop bucket add vvxrtues https://github.com/vvirtues/bucket scoop install discordo ``` -------------------------------- ### Handle Login and Token Messages Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/10-ui-root.md Example handlers for `loginMsg` to show the login UI and `token.TokenMsg` to display the chat UI after successful login and store the token. ```go // Receives login message from UI case loginMsg: return m.showLogin() // Receives token after successful login case token.TokenMsg: return tview.Batch( m.showChat(string(msg)), setToken(string(msg)), // Store in keyring ) ``` -------------------------------- ### Build Discordo from Source Source: https://github.com/ayn2op/discordo/blob/main/README.md Clones the Discordo repository and builds the executable from source using Go. This method requires Go to be installed. ```bash git clone https://github.com/ayn2op/discordo cd discordo go build . ``` -------------------------------- ### Login with Discordo using Environment Variable Source: https://github.com/ayn2op/discordo/blob/main/README.md Launches Discordo and authenticates using a provided Discord token set as an environment variable. Replace the example token with your actual token. ```bash DISCORDO_TOKEN="OTI2MDU5NTQxNDE2Nzc5ODA2.Yc2KKA.2iZ-5JxgxG-9Ub8GHzBSn-NJjNg" discordo ``` -------------------------------- ### Markdown Configuration Example Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/08-markdown.md Configuration for the markdown package, enabling rendering and specifying the theme for code blocks. Available themes can be found at https://xyproto.github.io/splash/docs. ```TOML [markdown] enabled = true theme = "monokai" # Chroma theme name ``` -------------------------------- ### Create New Cache Instance Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/03-cache.md Initializes a new Cache object. Use this to start using the caching mechanism. ```go func NewCache() *Cache { return &Cache{items: sync.Map{}} } ``` ```go cache := cache.NewCache() ``` -------------------------------- ### Create Chat Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/11-ui-chat.md Initializes the chat model with the tview application, configuration, and Discord authentication token. The gateway connection starts automatically when the tview application initializes. ```go func NewModel( app *tview.Application, cfg *config.Config, token string, ) *Model ``` ```go model := chat.NewModel(app, cfg, token) // model is ready for display // Gateway connection starts on tview.InitMsg ``` -------------------------------- ### Get Default Logging Path Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Retrieves the default path for logging configuration files. ```go logger.DefaultPath() string ``` -------------------------------- ### Example slog Calls Throughout Application Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/05-logger.md Demonstrates various levels of logging messages (Info, Warn, Error, Debug) that can be made using the slog package after the logger has been initialized. These messages are written to the configured log file with timestamps and context. ```go // In slog calls throughout the application: slog.Info("channel selected", "channel_id", channelID) slog.Warn("failed to get user cache dir", "err", err) slog.Error("state log error", "err", err) slog.Debug("received gateway event", "event_type", eventType) ``` -------------------------------- ### Get Default Configuration Path Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Returns the platform-specific default configuration directory path for the config.toml file. Use this to find the default location for your configuration. ```go func DefaultPath() string ``` ```go path := config.DefaultPath() cfg, err := config.Load(path) ``` -------------------------------- ### Notification Configuration Example Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/07-notifications.md This TOML configuration controls notification behavior, including enabling/disabling notifications, setting display duration, and configuring sound playback preferences like playing only on pings. ```toml [notifications] enabled = true duration = 0 # 0 = default duration [notifications.sound] enabled = true only_on_ping = true # Only play sound for direct mentions ``` -------------------------------- ### Get Discord Web Client HTTP Headers Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/04-http.md Returns a set of HTTP headers that mimic a Discord web client, including Accept, Accept-Encoding, and Sec-Fetch headers. Use these headers in custom HTTP requests to make them appear as if they originated from a browser. ```go headers := http.Headers() // Use in custom HTTP requests to mimic web client ``` -------------------------------- ### Render Markdown AST to Styled Lines Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/08-markdown.md Renders Markdown AST to styled text lines, preserving newlines and styles. This method walks the AST and renders various node types including text, emphasis, code, links, headings, lists, and more. Styles are stacked and applied cumulatively starting with a base style. ```Go renderer := markdown.NewRenderer(cfg) source := []byte("**bold** and `code`") node := discordmd.Parse(source) lines := renderer.RenderLines(source, node, style) // Returns lines with bold styling and code styling ``` -------------------------------- ### Get Discord Token from Keyring Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/06-keyring.md Retrieves the stored Discord authentication token from the system keyring. Use this when the application starts to automatically log the user in if a token is found. ```go func GetToken() (string, error) ``` ```go token, err := keyring.GetToken() if err != nil { // Token not stored, show login screen log.Print("token not found in keyring") } // token is now ready to use for API client ``` -------------------------------- ### Build and Run Discordo from Source Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Clone the repository, navigate to the directory, build the project using go build, and then run the executable. ```bash git clone https://github.com/ayn2op/discordo cd discordo go build . ./discordo ``` -------------------------------- ### Create Root Application Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/10-ui-root.md Creates the root application model with help panel and state management. Use this to initialize the main application structure. ```go func NewModel( cfg *config.Config, app *tview.Application, ) *Model ``` ```go model := root.NewModel(cfg, app) app.SetRoot(model) if err := app.Run(); err != nil { log.Fatal(err) } ``` -------------------------------- ### Discord API HTTP Client Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Setup and configuration for the HTTP client used to interact with the Discord API. ```APIDOC ## http.NewClient() ### Description Creates a new Discord API HTTP client, pre-configured with necessary headers and transport settings. ### Method `http.NewClient()` ### Parameters None explicitly documented. ``` ```APIDOC ## http.NewTransport() ### Description Creates a custom HTTP transport layer, allowing for modifications to request/response handling, such as adding browser-specific properties and headers. ### Method `http.NewTransport()` ### Parameters None explicitly documented. ``` -------------------------------- ### Create HTTP Client Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes a new HTTP client with an authentication token. ```go http.NewClient(token string) *api.Client ``` -------------------------------- ### Create Commands for State Changes Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Demonstrates creating commands that return messages, which can be used to trigger state changes or other actions within the application. It also shows how to batch multiple commands together. ```go // Send custom message to self func someCommand() tview.Cmd { return func() tview.Msg { return customMsg{data: value} } } // Batch multiple commands return tview.Batch( m.inner.Update(tview.InitMsg{}), tview.SetFocus(m.input), someCommand(), ) ``` -------------------------------- ### Create Login UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes the general login UI model, requiring application configuration. ```go ui/login.NewModel(cfg *config.Config) *Model ``` -------------------------------- ### Create Root UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes the main UI root model, requiring configuration and the TUI application instance. ```go ui/root.NewModel(cfg *config.Config, app *tview.Application) *Model ``` -------------------------------- ### Fenced Code Block Markdown Format Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/08-markdown.md Example of a fenced code block in Markdown with a specified language (Python). This format is used for syntax highlighting. ```Markdown ```python def hello(): print("world") ``` ``` -------------------------------- ### Create Markdown Renderer Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes a new Markdown renderer with custom configuration. ```go markdown.NewRenderer(cfg *config.Config) *Renderer ``` -------------------------------- ### Create Login Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/12-ui-login.md Initializes the login UI model, which includes a tabbed interface for token and QR code login, error dialog handling, and configuration styling. ```go func NewModel(cfg *config.Config) *Model ``` ```go model := login.NewModel(cfg) // Shows login UI with Token and QR tabs ``` -------------------------------- ### Initialize Logger and Load Log File Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/05-logger.md Initializes the logger, opens a log file for writing, and sets it as the default logger. The returned io.Closer must be closed by the caller. Parent directories are created if they don't exist, and the log file is created or truncated. ```go func Load(path string, level slog.Level) (io.Closer, error) ``` ```go logFile, err := logger.Load("/var/log/discordo/logs.txt", slog.LevelInfo) if err != nil { log.Fatal(err) } deferr logFile.Close() // Now all slog calls write to the file slog.Info("application started") slog.Error("something failed", "err", err) ``` -------------------------------- ### Initialize Discordo Application Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md The main entry point for the Discordo application. It orchestrates the loading of configuration, initialization of the logger, and creation of the terminal screen. ```go package main import ( "log" "discordo/cmd" "discordo/config" "discordo/logger" "discordo/root" "discordo/ui/login" "discordo/ui/root" "github.com/diamondburned/tcell/v2" ) func main() { // Load configuration cfg, err := config.Load() if err != nil { log.Fatalf("Failed to load configuration: %v", err) } // Initialize logger logger.Load(cfg.Log) // Create terminal screen sscreen, err := tcell.NewScreen() if err != nil { log.Fatalf("Failed to create screen: %v", err) } // Initialize root UI model appRoot, err := root.NewModel(cfg, screen) if err != nil { log.Fatalf("Failed to create root model: %v", err) } // Run the application if err := cmd.Run(cfg, appRoot, screen); err != nil { log.Fatalf("Application error: %v", err) } } ``` -------------------------------- ### Create Token Login UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes a specific UI model for logging in via a token. ```go ui/login/token.NewModel() *Model ``` -------------------------------- ### Typing Indicators Management Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/11-ui-chat.md Manages active typing indicators from other users using a map of user IDs to timers. A timer is started when a user begins typing and cancelled when they stop. ```go typers map[discord.UserID]*time.Timer ``` -------------------------------- ### Load Configuration from File Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Loads configuration from a TOML file, merging user settings with embedded defaults. Use this to load your application's settings. ```go func Load(path string) (*Config, error) ``` ```go cfg, err := config.Load("/home/user/.config/discordo/config.toml") if err != nil { log.Fatal(err) } // cfg now contains all configuration with user overrides applied ``` -------------------------------- ### Cache Directory Initialization Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/09-clipboard-consts.md Initializes the application cache directory. It determines the user's cache directory, appends 'discordo', creates the directory, and logs any creation errors. ```go func init() { userCacheDir, err := os.UserCacheDir() if err != nil { // Falls back to temp directory userCacheDir = os.TempDir() } cacheDir = filepath.Join(userCacheDir, Name) os.MkdirAll(cacheDir, os.ModePerm) } ``` -------------------------------- ### Thread-Safe Channel Selection Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/11-ui-chat.md Provides methods to get and set the currently selected Discord channel in a thread-safe manner using a mutex. This is crucial for components that need to access or modify the active channel. ```go func (m *Model) SelectedChannel() *discord.Channel func (m *Model) SetSelectedChannel(channel *discord.Channel) ``` -------------------------------- ### Configure Help Panel Display Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Defines how the help panel is displayed. Customize the compactness of key modifiers, padding, and the separator used. ```go type HelpConfig struct { CompactModifiers bool Padding [2]int Separator string } ``` -------------------------------- ### Get Gateway Identify Properties Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/04-http.md Returns gateway identify properties for WebSocket connections, including browser, OS, and version information. These properties are used when establishing a WebSocket connection to the Discord gateway. ```go props := http.IdentifyProperties() gateway.DefaultIdentity = props // Now all gateway connections use these properties ``` -------------------------------- ### Get Cached Profile Image Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/07-notifications.md Checks the local cache for a user's profile image using their avatar hash. If the image is not found, it downloads the image from Discord and caches it locally. Returns the absolute path to the cached image. ```go imagePath, err := getCachedProfileImage(user.Avatar, url) // imagePath: "/home/user/.cache/discordo/avatars/abc123.png" ``` -------------------------------- ### Get Default Log Directory Path Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/05-logger.md Returns the platform-specific default log directory path, typically ending in 'logs.txt' within the user's cache directory. Falls back to the system's temporary directory if the cache directory cannot be determined. ```go func DefaultPath() string ``` ```go logPath := logger.DefaultPath() logFile, err := logger.Load(logPath, slog.LevelDebug) ``` -------------------------------- ### Create QR Code Login UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes a UI model for handling login using QR codes. ```go ui/login/qr.NewModel() *Model ``` -------------------------------- ### Command-line Entry Point Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md The main entry point for the Discordo application, handling command-line arguments and initiating the application's lifecycle. ```APIDOC ## cmd.Run() ### Description This function serves as the primary entry point for the Discordo command-line interface. It is responsible for parsing arguments, initializing the application, and starting the main event loop. ### Method `cmd.Run()` ### Parameters None explicitly documented. ``` -------------------------------- ### Load Configuration Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Loads configuration from a specified file path. Returns a Config object or an error. ```go config.Load(path string) (*Config, error) ``` -------------------------------- ### Run Discordo Application Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/01-cmd.md Initializes and runs the Discordo terminal application. Reads command-line flags for configuration. Returns an error if initialization fails, or nil on successful exit. ```go package main import ( "log" "github.com/ayn2op/discordo/cmd" ) func main() { if err := cmd.Run(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Model Interface Implementation Methods Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/10-ui-root.md Lists the methods required to implement the tview.Model interface for the root UI component. These are delegated to the inner model. ```go func (m *Model) View(screen tcell.Screen) func (m *Model) Update(msg tview.Msg) tview.Cmd func (m *Model) Rect() (int, int, int, int) func (m *Model) SetRect(x, y, width, height int) func (m *Model) Focus(delegate func(tview.Model)) func (m *Model) HasFocus() bool func (m *Model) Blur() ``` -------------------------------- ### Configure Help Panel Display Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/configuration.md Customize the appearance of the help panel, including compact key modifiers, text padding, and the separator between key and description. ```toml [help] compact_modifiers = true padding = [1, 1] separator = " • " ``` -------------------------------- ### Load Logger Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/05-logger.md Initializes the logger and opens a log file for writing. It creates parent directories if they don't exist, creates or truncates the log file, sets up a text handler with the specified log level, and sets it as the default logger. The returned io.Closer must be closed when done. ```APIDOC ## Load Initializes the logger and opens a log file for writing. ### Function Signature ```go func Load(path string, level slog.Level) (io.Closer, error) ``` ### Parameters #### Path Parameters - **path** (string) - Required - Full file path where logs will be written - **level** (slog.Level) - Required - Logging level: `LevelDebug`, `LevelInfo`, `LevelWarn`, `LevelError` ### Return - **io.Closer** - A file handle that must be closed when done. The caller is responsible for deferred close. - **error** - An error if directory creation, file creation/open, or permission operations fail. ### Behavior 1. Creates parent directories if they don't exist. 2. Creates or truncates the log file. 3. Creates a text handler with the specified log level. 4. Sets the logger as the default via `slog.SetDefault()`. ### Example ```go logFile, err := logger.Load("/var/log/discordo/logs.txt", slog.LevelInfo) if err != nil { log.Fatal(err) } defer logFile.Close() // Now all slog calls write to the file slog.Info("application started") slog.Error("something failed", "err", err) ``` ``` -------------------------------- ### Load Logging Configuration Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Loads logging settings from a file path and sets the log level. Returns a closer for the logger or an error. ```go logger.Load(path string, level slog.Level) (io.Closer, error) ``` -------------------------------- ### Root Application Model Type Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/types.md The root application model, managing layers, the tview application instance, and the main UI flex layout. ```Go type Model struct { *layers.Layers app *tview.Application rootFlex *flex.Model inner tview.Model help *help.Model cfg *config.Config } ``` -------------------------------- ### Run Command Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Executes a command and returns an error if it fails. ```go cmd.Run() error ``` -------------------------------- ### Configure Desktop Notifications Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Sets up desktop notification preferences. Control whether notifications are enabled, their display duration, and sound playback. ```go type Notifications struct { Enabled bool Duration int Sound Sound } type Sound struct { Enabled bool OnlyOnPing bool } ``` -------------------------------- ### Create New Markdown Renderer Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/08-markdown.md Creates a new Markdown renderer instance. The renderer is stateful and should not be reused across render calls. It requires application configuration for theme and syntax highlighting. ```Go renderer := markdown.NewRenderer(cfg) ``` -------------------------------- ### Theme Structure Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/types.md Defines the complete theming configuration for the application, encompassing various UI components. ```go type Theme struct { Title TitleTheme Footer FooterTheme Border BorderTheme GuildsTree GuildsTreeTheme ScrollBar ScrollBarTheme MessagesList MessagesListTheme MentionsList MentionsListTheme Dialog DialogTheme Help HelpTheme } ``` -------------------------------- ### Keybinds Structure Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/types.md Defines all keyboard shortcuts for the application, including navigation, picker interactions, and general actions like logout and quit. ```go type Keybinds struct { ToggleGuildsTree Keybind ToggleChannelsPicker Keybind ToggleHelp Keybind Suspend Keybind FocusGuildsTree Keybind FocusMessagesList Keybind FocusMessageInput Keybind FocusPrevious Keybind FocusNext Keybind Picker PickerKeybinds GuildsTree GuildsTreeKeybinds MessagesList MessagesListKeybinds MessageInput MessageInputKeybinds MentionsList MentionsListKeybinds Logout Keybind Quit Keybind } ``` -------------------------------- ### Handle Messages in UI Models Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md This pattern shows how to update a UI component by handling different message types, including initialization, keyboard input, and custom messages. It also demonstrates delegating updates to an inner component. ```go func (m *Model) Update(msg tview.Msg) tview.Cmd { switch msg := msg.(type) { case tview.InitMsg: // Initialize component return startAsyncWork() case tview.KeyMsg: // Handle keyboard input switch msg.Key() { case tcell.KeyEsc: return someCommand() } case customMsg: // Handle custom message from async work return nil } // Delegate to inner component return m.inner.Update(msg) } ``` -------------------------------- ### HTTP Client Constants Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Constants for constructing HTTP client headers, including OS, browser, and build information. ```go const ( OS = "Windows" OSVersion = "10" Browser = "Chrome" BrowserVersion = "143.0.0.0" BrowserUserAgent = "Mozilla/5.0 ..." ClientBuildNumber = 482285 Locale = discord.EnglishUS ) ``` -------------------------------- ### Configuration System Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Provides functionality to load and manage Discordo's configuration settings from TOML files. ```APIDOC ## config.Load() ### Description Loads the TOML configuration file for Discordo. It searches for the configuration file in standard locations or a user-specified path. ### Method `config.Load()` ### Parameters None explicitly documented. ``` ```APIDOC ## config.DefaultPath() ### Description Retrieves the default file path where Discordo expects to find its configuration file. ### Method `config.DefaultPath()` ### Parameters None explicitly documented. ``` -------------------------------- ### Configure Markdown Rendering Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Controls Markdown parsing and rendering options. Enable Markdown support and specify a syntax highlighting theme for code blocks. ```go type MarkdownConfig struct { Enabled bool Theme string } ``` -------------------------------- ### Create QR Code Login Tab Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/12-ui-login.md Initializes the QR code login tab model, which sets up a WebSocket connection for remote authentication, RSA key generation, and QR code display. ```go // In ui/login/qr/model.go func NewModel() *Model ``` -------------------------------- ### Create Configured Discord API Client Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/04-http.md Creates a Discord API client with a custom HTTP transport, browser user agent, and default gateway identify properties. Use this to initialize a client for making authenticated requests to the Discord API. ```go client := http.NewClient(token) // client is now ready for Discord API calls // Automatically includes proper headers and properties ``` -------------------------------- ### Open Channel Picker Modal Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/11-ui-chat.md Shows the channel picker modal with current channels. It adds a layer, focuses the picker, and populates the list. ```go func (m *Model) openPicker() { // Implementation omitted for brevity } ``` -------------------------------- ### Log File Path Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/INDEX.md Constructs the path to the log file. This is used for debugging issues by examining the application's log output. ```go consts.CacheDir()/logs.txt ``` -------------------------------- ### Create Chat UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Initializes the chat UI model, dependent on the TUI application, configuration, and authentication token. ```go ui/chat.NewModel(app *tview.Application, cfg *config.Config, token string) *Model ``` -------------------------------- ### Configure Picker Dimensions Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/configuration.md Set the width and height for the channel search modal. Dimensions are automatically capped to available screen space. ```toml [picker] width = 80 height = 25 ``` -------------------------------- ### Notifications Configuration Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/configuration.md Set up desktop notifications for message mentions. This includes enabling notifications, setting their display duration, and configuring sound alerts, including an option to play sound only on direct mentions. ```toml [notifications] enabled = true duration = 0 [notifications.sound] enabled = true only_on_ping = true ``` -------------------------------- ### Application Name Constant Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/09-clipboard-consts.md Defines the application name as 'discordo'. This constant is used for configuration, cache, and keyring directory names. ```go const Name = "discordo" ``` -------------------------------- ### Discordo Module Organization Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Illustrates the directory structure of the Discordo project, highlighting the organization of internal modules and the command-line entry point. ```tree discordo/ ├── cmd/ # CLI entry point ├── internal/ │ ├── cache/ # Autocomplete cache │ ├── clipboard/ # Clipboard operations │ ├── config/ # Configuration parsing │ ├── consts/ # Application constants │ ├── http/ # Discord API HTTP client │ ├── keyring/ # Token storage │ ├── logger/ # Structured logging │ ├── markdown/ # Markdown rendering │ ├── notifications/ # Desktop notifications │ └── ui/ # Terminal UI components │ ├── chat/ # Chat interface (messages, input, guild tree) │ ├── login/ # Login interface (token + QR) │ │ ├── qr/ # QR code login │ │ └── token/ # Token login │ └── root/ # Root application model ├── main.go # Application entry point ├── go.mod # Dependencies └── go.sum ``` -------------------------------- ### Configure Channel Picker Dimensions Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Sets the dimensions for the channel picker modal. Adjust the width and height of the picker interface. ```go type PickerConfig struct { Width int Height int } ``` -------------------------------- ### QR Login Flow Steps Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/12-ui-login.md Outlines the sequence of events for QR code login, from UI initialization and WebSocket connection to user authentication via the Discord mobile app. ```text 1. UI Init → Connect to Discord Remote Auth Gateway → Receive hello message with heartbeat interval 2. Handshake → Generate RSA private key → Send init message to gateway 3. Nonce Proof → Receive encrypted nonce → Decrypt with private key → Send proof back 4. QR Code → Receive fingerprint → Generate QR code → Display to user → Show "Scan with Discord app" message 5. Authentication → User scans QR code with mobile app → Mobile app authenticates → Gateway sends encrypted token back → Decrypt and use token for login ``` -------------------------------- ### Configure Icons for Channel and Guild Types Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Specifies icons used for various channel and guild types within the application. Assign custom icons for different categories. ```go type Icons struct { GuildCategory string GuildText string GuildVoice string GuildStageVoice string GuildAnnouncementThread string GuildPublicThread string GuildPrivateThread string GuildAnnouncement string GuildForum string GuildStore string } ``` -------------------------------- ### Channel and Guild Icons Configuration Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/types.md Defines Unicode strings used for displaying icons next to channel and guild types in the UI. ```go type Icons struct { GuildCategory string GuildText string GuildVoice string GuildStageVoice string GuildAnnouncementThread string GuildPublicThread string GuildPrivateThread string GuildAnnouncement string GuildForum string GuildStore string } ``` -------------------------------- ### Build Layout Function Signature Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/10-ui-root.md Signature for the buildLayout function, responsible for creating the visual layout of the UI root, including the inner content and help panel. ```go func (m *Model) buildLayout() *flex.Model ``` -------------------------------- ### Configure Sidebar Display Options Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Manages the display of the guild tree in the sidebar. Configure expand/collapse markers and indentation levels for different tree items. ```go type SidebarConfig struct { Markers SidebarMarkersConfig Indents SidebarIndentsConfig } type SidebarMarkersConfig struct { Expanded string Collapsed string Leaf string } type SidebarIndentsConfig struct { Guild int Category int Channel int Forum int GroupDM int DM int } ``` -------------------------------- ### NewClient Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/04-http.md Creates a configured Discord API client for authenticated requests. This client mimics a Discord web client to avoid account restrictions. ```APIDOC ## NewClient ### Description Creates a configured Discord API client for authenticated requests. ### Method `NewClient(token string) *api.Client` ### Parameters #### Path Parameters - **token** (string) - Required - Discord authentication token ### Return Returns `*api.Client` configured with custom HTTP transport (brotli decompression support), browser user agent, and default gateway identify properties. ### Example ```go client := http.NewClient(token) // client is now ready for Discord API calls // Automatically includes proper headers and properties ``` ``` -------------------------------- ### Keybind Unmarshaling Wrapper Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/types.md A wrapper for keybinds to handle TOML unmarshaling, supporting both single string and array of strings for keys. ```go type Keybind struct { keybind.Keybind } ``` -------------------------------- ### Configuration File Path Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/INDEX.md Retrieves the default path for the TOML configuration file. This is useful for users who want to customize application settings. ```go config.DefaultPath() ``` -------------------------------- ### DefaultPath Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Returns the platform-specific default configuration directory path for the config.toml file. ```APIDOC ## DefaultPath ### Description Returns the platform-specific default configuration directory path for the `config.toml` file. ### Function Signature ```go func DefaultPath() string ``` ### Return - `string` - The full path to `config.toml` in the user's config directory. The path is platform-specific: - **Linux/Unix**: `$XDG_CONFIG_HOME/discordo/config.toml` or `$HOME/.config/discordo/config.toml` - **macOS**: `$HOME/Library/Application Support/discordo/config.toml` - **Windows**: `%AppData%/discordo/config.toml` Falls back to the current directory if the user config directory cannot be determined. ### Example ```go path := config.DefaultPath() cfg, err := config.Load(path) ``` ``` -------------------------------- ### Load Configuration Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Loads configuration from a TOML file, merging user settings with embedded defaults. It handles file reading, TOML parsing, and applies post-load defaults. ```APIDOC ## Load Configuration ### Description Loads configuration from a TOML file, merging user settings with embedded defaults. It handles file reading, TOML parsing, and applies post-load defaults. ### Function Signature ```go func Load(path string) (*Config, error) ``` ### Parameters #### Path Parameters - **path** (string) - Required - Full path to the configuration TOML file ### Return - `*Config` - On success, returns the loaded configuration object. - `error` - Returns an error if the file cannot be read, TOML parsing fails, or other loading issues occur. ### Behavior 1. Starts with embedded default configuration. 2. Applies defaults via `applyDefaults()`. 3. If the configuration file does not exist, uses defaults and logs an info message. 4. If the configuration file exists, merges user settings on top of defaults. 5. Applies post-load defaults (e.g., `Editor` expansion from environment variable). ### Errors - File permission errors - TOML parsing errors (invalid syntax) - Errors from embedded default TOML parsing ### Example ```go cfg, err := config.Load("/home/user/.config/discordo/config.toml") if err != nil { log.Fatal(err) } // cfg now contains all configuration with user overrides applied ``` ``` -------------------------------- ### Login Interface Model Type Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/types.md The login interface model, managing tabs, configuration, and error display for the login screen. ```Go type Model struct { *layers.Layers tabs *tabs.Model cfg *config.Config errorModalText string } ``` -------------------------------- ### Create Token Login Tab Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/12-ui-login.md Generates a new model for the token login tab, which includes a password field for token entry and a login button. ```go // In ui/login/token/model.go func NewModel() *Model ``` -------------------------------- ### Config Structure Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Defines the main configuration structure containing all application settings and their fields. ```APIDOC ## Config Structure ### Description Main configuration structure containing all application settings. ### Type Definition ```go type Config struct { AutoFocus bool Mouse bool Editor string Status discord.Status HideBlockedUsers bool ShowAttachmentLinks bool AutocompleteLimit uint8 MessagesLimit uint8 Markdown MarkdownConfig Help HelpConfig Picker PickerConfig Timestamps Timestamps DateSeparator DateSeparator Notifications Notifications TypingIndicator TypingIndicator Sidebar SidebarConfig Icons Icons Keybinds Keybinds Theme Theme } ``` ### Fields | Field | Type | Default | Description | |---|---|---|---| | `AutoFocus` | bool | `true` | Focus message input when channel is selected | | `Mouse` | bool | `true` | Enable mouse support | | `Editor` | string | `"default"` | External text editor (`"default"` uses `$EDITOR`) | | `Status` | discord.Status | `"default"` | Discord presence status | | `HideBlockedUsers` | bool | `true` | Hide blocked users from member list | | `ShowAttachmentLinks` | bool | `true` | Display attachment URLs in messages | | `AutocompleteLimit` | uint8 | `20` | Max members in mention suggestions (0 to disable) | | `MessagesLimit` | uint8 | `50` | Messages to fetch per channel (1-100 range) | | `Markdown` | MarkdownConfig | — | Markdown parsing settings | | `Help` | HelpConfig | — | Help panel styling | | `Picker` | PickerConfig | — | Channel picker dimensions | | `Timestamps` | Timestamps | — | Message timestamp options | | `DateSeparator` | DateSeparator | — | Date separator line options | | `Notifications` | Notifications | — | Desktop notifications settings | | `TypingIndicator` | TypingIndicator | — | Typing indicator options | | `Sidebar` | SidebarConfig | — | Guild tree styling | | `Icons` | Icons | — | Channel/guild icons | | `Keybinds` | Keybinds | — | All keyboard shortcuts | | `Theme` | Theme | — | Terminal colors and styling | ``` -------------------------------- ### Discordo Data Flow Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Visualizes the data flow within the Discordo application, from the command-line entry point through configuration loading, UI model initialization, and state transitions. ```tree cmd.Run() ↓ Load Config → Initialize Logger → Create Screen ↓ root.NewModel() [shows help + manages state] ├─ login.NewModel() [token or QR tabs] │ ├ token.NewModel() [password field] │ └ qr.NewModel() [WebSocket connection] │ └─ chat.NewModel() [main interface when authenticated] ├─ guilds_tree [guild/channel sidebar] ├─ messages_list [message display] ├─ message_input [message composition] └─ channels_picker [search modal] ``` -------------------------------- ### Model Structure Definition Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/10-ui-root.md Defines the structure of the root application model, including embedded layers, application instance, layout components, and configuration. ```go type Model struct { *layers.Layers app *tview.Application rootFlex *flex.Model // inner + help inner tview.Model // login or chat help *help.Model cfg *config.Config } ``` -------------------------------- ### Thread-Safe State Access with RWMutex Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md Illustrates how to protect shared state (like selected channel data) from concurrent access issues using Go's RWMutex. This ensures safe reading and writing operations. ```go // Protected with RWMutex func (m *Model) GetChannel() *discord.Channel { m.selectedChannelMu.RLock() defer m.selectedChannelMu.RUnlock() return m.selectedChannel } func (m *Model) SetChannel(ch *discord.Channel) { m.selectedChannelMu.Lock() m.selectedChannel = ch m.selectedChannelMu.Unlock() } ``` -------------------------------- ### Show Error Dialog Implementation Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/12-ui-login.md Go implementation for displaying an error dialog. It sets the modal text from an error, adds 'Copy' and 'Close' buttons, and adds the modal to the UI layer. ```go func (m *Model) showErrorDialog(err error) tview.Cmd { message := err.Error() m.errorModalText = message modal := tview.NewModal() .SetText(message) .AddButtons([]string{"Copy", "Close"}) // ... styling ... m.AddLayer(modal, /* ... */) } ``` -------------------------------- ### Main Configuration Structure Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/02-config.md Defines the main configuration structure for Discordo, encompassing all application settings. This struct holds all loaded and default configuration values. ```go type Config struct { AutoFocus bool Mouse bool Editor string Status discord.Status HideBlockedUsers bool ShowAttachmentLinks bool AutocompleteLimit uint8 MessagesLimit uint8 Markdown MarkdownConfig Help HelpConfig Picker PickerConfig Timestamps Timestamps DateSeparator DateSeparator Notifications Notifications TypingIndicator TypingIndicator Sidebar SidebarConfig Icons Icons Keybinds Keybinds Theme Theme } ``` -------------------------------- ### Root Application UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md The main UI model for the Discordo application, managing overall state and transitions between different interface views. ```APIDOC ## root.NewModel() ### Description Initializes the root UI model for the Discordo application. This model is responsible for managing the application's state, including user authentication status and transitions between the login and chat interfaces. It also handles the management of the help panel. ### Method `root.NewModel()` ### Parameters None explicitly documented. ``` -------------------------------- ### Keyring Constants Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/06-keyring.md Defines constants for the keyring service and user. Tokens are stored under the service name "discordo" and user "token" to avoid conflicts with other applications. ```go const ( keyringService = consts.Name // "discordo" keyringUser = "token" ) ``` -------------------------------- ### Clipboard Format Constants Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/09-clipboard-consts.md Defines constants for text and image data formats. Use FmtText for text and FmtImage for image data. ```go const ( FmtText Format = clipboard.FmtText FmtImage = clipboard.FmtImage ) ``` -------------------------------- ### Clipboard Formats Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/API-INDEX.md Defines constants for text and image formats used with the clipboard. ```go const ( FmtText = clipboard.FmtText FmtImage = clipboard.FmtImage ) ``` -------------------------------- ### Login Interface UI Model Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/README.md The UI model for the login process, supporting both token-based and QR code authentication flows. ```APIDOC ## login.NewModel() ### Description Initializes the login interface model. This model orchestrates the user login process, supporting both direct token entry and QR code scanning for authentication. It also includes error handling for login failures. ### Method `login.NewModel()` ### Parameters None explicitly documented. ``` -------------------------------- ### QR Code Login Display Source: https://github.com/ayn2op/discordo/blob/main/_autodocs/12-ui-login.md Illustrates the visual representation of the QR code login interface as seen by the user. This includes the QR code itself and instructions for scanning. ```text User sees: ┌──────────────────────────────┐ │ QR Code Login │ ├──────────────────────────────┤ │ │ │ ██████████████████ │ │ ██ ██ ██ ██ │ │ ██ ██████ ██ ██ │ │ ██ ██ ██ ██ │ │ ██████████████████ │ │ │ │ Scan with Discord app │ │ │ └──────────────────────────────┘ User opens Discord mobile app → Settings → Scan QR → Camera scans code → Mobile app authenticates → Token sent back to client → Chat UI opens ```