From 0c9ca13eeca5b19f2e69f6cf8499ff20b5f73b7b Mon Sep 17 00:00:00 2001 From: drew Date: Sun, 7 Dec 2025 13:15:12 +0400 Subject: [PATCH] fix: fixed bug with attachments, small UI changes --- README.md | 13 +++++++--- fetcher/fetcher.go | 59 ++++++++++++++++++++++++++++++++++++------ main.go | 2 +- public/assets/logo.txt | 55 +++++++++++++++++++++++++++++++++++++++ tui/choice.go | 2 +- tui/composer.go | 4 +-- tui/email_view.go | 16 +++++++++--- tui/email_view_test.go | 10 +++---- tui/filepicker.go | 4 +-- tui/inbox.go | 2 +- tui/styles.go | 26 ++++++++++++++----- 11 files changed, 159 insertions(+), 34 deletions(-) create mode 100644 public/assets/logo.txt diff --git a/README.md b/README.md index a46f2881dbd2d91ef0e1ae84671319f112fc8dcb..d4e70fef95002679d6a7c73cbe9d2f364798cd80 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,16 @@ -# Matcha 🍵 -
--- + +``` + __ __ + ____ ___ ____ _/ /______/ /_ ____ _ + / __ '__ \/ __ '/ __/ ___/ __ \/ __ '/ + / / / / / / /_/ / /_/ /__/ / / / /_/ / +/_/ /_/ /_/\__,_/\__/\___/_/ /_/\__,_/ +``` --- @@ -31,7 +37,6 @@ A beautiful and functional email client for your terminal, built with Go and the charming Bubble Tea TUI library. Never leave your command line to check your inbox or send an email again! -![Main Menu Screenshot](assets/preview.png)
@@ -101,4 +106,4 @@ Matcha is written in **Go**. To build it manually: ## License 📄 -This project is distributed under the MIT License. See the `LICENSE` file for more information. \ No newline at end of file +This project is distributed under the MIT License. See the `LICENSE` file for more information. diff --git a/fetcher/fetcher.go b/fetcher/fetcher.go index 23de3e7c802b05dcfeece617bdfbe8532d38a546..8576842f2cab31685465ed91e9d852bea01b1a7b 100644 --- a/fetcher/fetcher.go +++ b/fetcher/fetcher.go @@ -221,22 +221,65 @@ func FetchEmailBody(cfg *config.Config, uid uint32) (string, []Attachment, error var textPartID string var attachments []Attachment + var checkPart func(part *imap.BodyStructure, partID string) + checkPart = func(part *imap.BodyStructure, partID string) { + // Check for text content + if part.MIMEType == "text" && (part.MIMESubType == "plain" || part.MIMESubType == "html") && textPartID == "" { + textPartID = partID + } + + // Check for attachments using multiple methods + filename := "" + // First try the Filename() method which handles various cases + if fn, err := part.Filename(); err == nil && fn != "" { + filename = fn + } + // Fallback: check DispositionParams + if filename == "" { + if fn, ok := part.DispositionParams["filename"]; ok && fn != "" { + filename = fn + } + } + // Fallback: check Params (for name parameter) + if filename == "" { + if fn, ok := part.Params["name"]; ok && fn != "" { + filename = fn + } + } + // Fallback: check Params for filename + if filename == "" { + if fn, ok := part.Params["filename"]; ok && fn != "" { + filename = fn + } + } + + // Add as attachment if it has a disposition or a filename (and not just plain text) + if filename != "" && (part.Disposition == "attachment" || part.Disposition == "inline" || part.MIMEType != "text") { + attachments = append(attachments, Attachment{Filename: filename, PartID: partID}) + } + } + var findParts func(*imap.BodyStructure, string) findParts = func(bs *imap.BodyStructure, prefix string) { + // If this is a non-multipart message, check the body structure itself + if len(bs.Parts) == 0 { + partID := prefix + if partID == "" { + partID = "1" + } + checkPart(bs, partID) + return + } + + // Iterate through parts for i, part := range bs.Parts { partID := fmt.Sprintf("%d", i+1) if prefix != "" { partID = fmt.Sprintf("%s.%d", prefix, i+1) } - if part.MIMEType == "text" && (part.MIMESubType == "plain" || part.MIMESubType == "html") && textPartID == "" { - textPartID = partID - } - if part.Disposition == "attachment" || part.Disposition == "inline" { - if filename, ok := part.Params["filename"]; ok { - attachments = append(attachments, Attachment{Filename: filename, PartID: partID}) - } - } + checkPart(part, partID) + if len(part.Parts) > 0 { findParts(part, partID) } diff --git a/main.go b/main.go index 5ae0204d5d87331b0ce72befc5968cc39790d927..eeffda5d2ad6014f00a851ba7730e31b74422990 100644 --- a/main.go +++ b/main.go @@ -167,7 +167,7 @@ func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.emails[msg.Index].Body = msg.Body m.emails[msg.Index].Attachments = msg.Attachments - emailView := tui.NewEmailView(m.emails[msg.Index], m.width, m.height) + emailView := tui.NewEmailView(m.emails[msg.Index], msg.Index, m.width, m.height) m.current = emailView return m, m.current.Init() diff --git a/public/assets/logo.txt b/public/assets/logo.txt new file mode 100644 index 0000000000000000000000000000000000000000..830c8c3a77fbcacc511c6566107953659505634a --- /dev/null +++ b/public/assets/logo.txt @@ -0,0 +1,55 @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##%******%#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*****#@@***@%**#%**#@@%*****@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*****@@@@@@@**#*#@@%***#@@@@@@%*****#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#*#%@%%%##%@@@@%##*****###%@@@@%##%%%@%###@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@#**%%###*#@@@@@@@@@@%@@@@@@@@@@@@@@%***##%%*##@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@***#%@@#%@****#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@###**#@##@@@****@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@%*++**#%@@@@%%%%%@@@%###++++++++++++**+++++*##%%@@@%%%%@@@@@%#*+++*#@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@#***#%+*#@@@@@@@@@@#*+====%%%%%%%%%%%%%%%%%%%#===++*#@@@@@@@@@@#**%#***#@@@@@@@@@@@@@ +@@@@@@@@@@@@@@+**#%#*###@@@@@@@*+===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@+====#%@@@@@@##**%@#***%@@@@@@@@@@@ +@@@@@@@@@@@@@@+*#%**##%@@@@%*+=++*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*++=**%@@@@%##**%#**%@@@@@@@@@@@ +@@@@@@@@@@@@@@*##**#%@@@@%*=###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%##*=*#@@@@%#**#%#@@@@@@@@@@@@ +@@@@@@@@@@@@%##%@@@@@@@%==*@@@@@@@@@@@#*****+++=====*%@@@@@@@@@@@@@@@@@@@@@+=+%@@@@@@@@##%@@@@@@@@@@ +@@@@@@@@@@@@##@@@@@@@@*-=#@@@@@@@@@#****+++++++++++++=--+%@%+=#@@@@@@@@@@@@@%==#@@@@@@@@#%@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@%==+@@#=+++@@@#*********++++++++++++++@@@#+*@@@@@@@@@@@@@@*=+%@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@%@@%@@@%*+=#@@#*#%%#***+##*+++++*#++++++++++##+++++#%@@@@@@@@@@@@@@@*=+#%@@@%@@%@@@@@@@@@ +@@@@@@@@#**@%##%@@*==%@@@#*#@%#++*@*=-----:--%#++++++*%--------+@@@@@@@@@@@@@@@@%==+@@@##%@#*#@@@@@@ +@@@@@@%#*#@##*#%@*=*@@@@@@%#***+#%=-:::-------+@++++##=----------%@@@@@@@@@@@@@@@@+=#@%**##@#*#@@@@@ +@@@@@@%*#%@***@@#-=#@@@@@@@@#**+#%=--:::-===-:+@++++%#=-----*@*=-%@@@@@@@@@@@@@@@@*==%@%#*#@%#*%@@@@ +@@@@@#**%%%##%@#+-#@@@@@@@@@***+#%=---::-@@@#-+@++++##=----+@@@#-%@@@@%*++**++++++%%=*#@@###@@**#@@@ +@@@@@#*@###@@@@#==%@@@@@@@%****+#%==-:---@@@@-+@=++++*@=-::----+%@@@@%*#=---=---+%+==+*@@@@###%*#@@@ +@@@@@##@%%@@@@#++@@@@@@@@@%**++++*%*==------=##*@@@@@%*%#+++++%@@@@@@%=-**+=-==**==+@++#@@@@%%@*#@@@ +@@@@@%%@@@@@@@*++@@@@@@@@@%**++++++###############@@@%*##%####**@@%*@%===++****+===+@+=#@@@@@@@%%@@@ +@@@@@@@@@@@@@%*++@@@@@@@@@%**+++++++*#####*++%#+=======@%+++++=+@++@@#+*=======-=#++@++#@@@@@@@@@@@@ +@*++++*%+*@@@%*++@@@@@@@@@%**++++++++++++++++%#++*%@@%*%#++++==*@=+%@@%*++++++++++%@@++#@@@*++++*#+# +@*****##***@@@*++@@@@@@@@@%***++++++++++++++++*%@#-%*=%+++++=-=*@#*=#%@@@%###@@@@@@@@++#@@%*****##** +@*#%*******@@@*++@@@@@@@@@%****+++++++++++++++++@@@@@%++++++++-+@@%=*%@@@%=%@@@@@@@@@++#@@@*%%****** +@@@@@@@@@@@@@@*++@@@@@@@@@%****+++++++++++++++++****++++++++++-+@#*=%@@@++@@@@@@@@@@@++#@@@@@@@@@@@@ +@#%@####%%*@@@*++@@@@@@@@@%*****+++++++++++++++++++++++++++++++*@**@@@@@@@@@@@@@@@@@@++#@@@#@@####%# +@%@@%%%%@@%@@@*++@@@@@@@@@%*****+++++++++++++=======*#########%%########@@@@@@@@@@@@@+=#@@@%@@%%%%@% +@@@@@@@@@@@@@@*=+@@@@@@@@@%*****++++++++++++=======%*++#################+++%@@@@@@@@@+=#@@@@@@@@@@@@ +@@@@@@@@@@@@@%*++@@@@@@@@@%******+++++++++++=====+%=+####**************####==@@@@@@@@+=#%@@@@@@@@@@@ +@@@@@##@@@@@@@*++@@@@@@@@@%******+++++++++=======+@=+***++========+**+=****=+@@@@@@@@+=#%@@@@@@*#@@@ +@@@@@**@##%@@@@#==%@@@@@@@%*****+++++++++####+===*@%*++==+++++++++++++==+++**@@@@@@%=+*@@@@%##@*#@@@ +@@@@@#*#%#*#%@@%*=%@@@@@@@%******++++++====++%@%%@@@%%%#***************+***%@@@@@@@%=*%@@%**%%**#@@@ +@@@@@@%+%@@#**@@#=-*@@@@@#********++++*++=======----*@%%#****************#@+==%@@@+-=%@@**#@@%+%@@@@ +@@@@@@%**%@#**%%%#++#@@@@%********++++%###*=======+*%@%##**************+*#@*++%@%#==#@@#**#@#**%@@@@ +@@@@@@@@#*#%#*+#@@#+=+%@@%********++++*###%%%%%%%%%@@%%##**************+*##%%%@#+=+*@@%+*#%#*#@@@@@@ +@@@@@@@@@@@*%%*%@@@%#=#@@#********++++++***********@@@%%%%************+**#@@@@@*=#@@@@%*%#*@@@@@@@@@ +@@@@@@@@@@@@%%@@@@@@@+==#**********++++++=+*********#@@%%%%####*******##@@@@@#==*@@@@@@@%%@@@@@@@@@@ +@@@@@@@@@@@@%#@@@@@@@%*+-=+*********+++++========+***##@@@@@%%%%%%%%%%@@@@@*+=+#%@@@@@@@#%@@@@@@@@@@ +@@@@@@@@@@@@#+****%@@@@%*+==********+++++=========+****##@####%%#####%@@@%+=+#%@@@@%++**+%@@@@@@@@@@ +@@@@@@@@@@@@@%+**+++*@@@@%*====*******+++===========******@@@@@@@@@@@@%+===*#@@@%*+++**+%@@@@@@@@@@@ +@@@@@@@@@@@@@%***%#*++#@@@%##+==+*******+++==========+**********#@@%%*==+*#@@@@#++*#%***%@@@@@@@@@@@ +@@@@@@@@@@@@@@%#**#%%+*#@@@@@@%#*+==++*****+============++******+++=+*%%@@@@@%*+*%##***@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@%*++*#%##@@@@@@@@@@@#*+==========================***@@@@@@@@@@%*#%#*++*#@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@%#**+*%@@@@@@%#*%@@@@@#**********************###@@@@@%*#@@@@@@@#*+*##@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@%%%%%#%@@%%%##***#%@@@@@@@@@@@@@@@@@@@@@@@@@@%****##%#%@@%%%%%%@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@%@@@#*#%%###*@@@@@@@%%########%@@@@@@@%*###%%**%@@@%@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**#@@@@*#@@@@@##%*****#%*#@@@@@##@@@@#*#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*#***@@%%@@@#**@%##%%#*#@@@%%%%***##%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%@@##%###%##%*#@@%####%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#********%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/tui/choice.go b/tui/choice.go index 58f6c3cf6320173cd9b9259d908f566f43dd1ec6..1011ff71ec39362dbb5e03dcd1a92143e428e32f 100644 --- a/tui/choice.go +++ b/tui/choice.go @@ -14,7 +14,7 @@ var ( titleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FFFDF5")).Background(lipgloss.Color("#25A065")).Padding(0, 1) listHeader = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).PaddingBottom(1) itemStyle = lipgloss.NewStyle().PaddingLeft(2) - selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205")) + selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("42")) ) type Choice struct { diff --git a/tui/composer.go b/tui/composer.go index 9d88861afdce8e2ba4db5995ccb0972989b06845..85278301606bbb5bbf23afc42e51a7f5c17dfa90 100644 --- a/tui/composer.go +++ b/tui/composer.go @@ -12,14 +12,14 @@ import ( // Styles for the UI var ( - focusedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) + focusedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("42")) blurredStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240")) cursorStyle = focusedStyle.Copy() noStyle = lipgloss.NewStyle() helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")) focusedButton = focusedStyle.Copy().Render("[ Send ]") blurredButton = blurredStyle.Copy().Render("[ Send ]") - emailRecipientStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true) + emailRecipientStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true) attachmentStyle = lipgloss.NewStyle().PaddingLeft(4).Foreground(lipgloss.Color("240")) // This was the missing style ) diff --git a/tui/email_view.go b/tui/email_view.go index 1396481989ab334f2086972480ebe8ff1beb885e..908cd959adca0595f7631c65a641a1dcf3de3009 100644 --- a/tui/email_view.go +++ b/tui/email_view.go @@ -19,11 +19,12 @@ var ( type EmailView struct { viewport viewport.Model email fetcher.Email + emailIndex int attachmentCursor int focusOnAttachments bool } -func NewEmailView(email fetcher.Email, width, height int) *EmailView { +func NewEmailView(email fetcher.Email, emailIndex, width, height int) *EmailView { // Pass the styles from the tui package to the view package body, err := view.ProcessBody(email.Body, H1Style, H2Style, BodyStyle) if err != nil { @@ -42,8 +43,9 @@ func NewEmailView(email fetcher.Email, width, height int) *EmailView { vp.SetContent(body) return &EmailView{ - viewport: vp, - email: email, + viewport: vp, + email: email, + emailIndex: emailIndex, } } @@ -79,8 +81,14 @@ func (m *EmailView) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "enter": if len(m.email.Attachments) > 0 { selected := m.email.Attachments[m.attachmentCursor] + idx := m.emailIndex return m, func() tea.Msg { - return DownloadAttachmentMsg{Filename: selected.Filename, Data: selected.Data} + return DownloadAttachmentMsg{ + Index: idx, + Filename: selected.Filename, + PartID: selected.PartID, + Data: selected.Data, + } } } case "tab": diff --git a/tui/email_view_test.go b/tui/email_view_test.go index 6572bc1653095c0ad5eed4dd2aa16e3a14caf0d5..cefcc825733ce327d5813dd137a1c12ac3dc3a69 100644 --- a/tui/email_view_test.go +++ b/tui/email_view_test.go @@ -28,7 +28,7 @@ func TestEmailViewUpdate(t *testing.T) { } t.Run("Focus on attachments", func(t *testing.T) { - emailView := NewEmailView(emailWithAttachments, 80, 24) + emailView := NewEmailView(emailWithAttachments, 0, 80, 24) if emailView.focusOnAttachments { t.Error("focusOnAttachments should be initially false") } @@ -50,7 +50,7 @@ func TestEmailViewUpdate(t *testing.T) { }) t.Run("No focus on attachments when there are none", func(t *testing.T) { - emailView := NewEmailView(emailWithoutAttachments, 80, 24) + emailView := NewEmailView(emailWithoutAttachments, 0, 80, 24) if emailView.focusOnAttachments { t.Error("focusOnAttachments should be initially false") } @@ -63,7 +63,7 @@ func TestEmailViewUpdate(t *testing.T) { }) t.Run("Navigate attachments", func(t *testing.T) { - emailView := NewEmailView(emailWithAttachments, 80, 24) + emailView := NewEmailView(emailWithAttachments, 0, 80, 24) // Focus on attachments model, _ := emailView.Update(tea.KeyMsg{Type: tea.KeyTab}) emailView = model.(*EmailView) @@ -95,7 +95,7 @@ func TestEmailViewUpdate(t *testing.T) { }) t.Run("Download attachment", func(t *testing.T) { - emailView := NewEmailView(emailWithAttachments, 80, 24) + emailView := NewEmailView(emailWithAttachments, 0, 80, 24) // Focus on attachments model, _ := emailView.Update(tea.KeyMsg{Type: tea.KeyTab}) emailView = model.(*EmailView) @@ -121,7 +121,7 @@ func TestEmailViewUpdate(t *testing.T) { }) t.Run("Reply to email", func(t *testing.T) { - emailView := NewEmailView(emailWithAttachments, 80, 24) + emailView := NewEmailView(emailWithAttachments, 0, 80, 24) _, cmd := emailView.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("r")}) if cmd == nil { diff --git a/tui/filepicker.go b/tui/filepicker.go index 6756942fcf0231b046b111ed576f2787497be9cc..115cbd2f615a05f59b9ded1ba4eb5f1ce7aad730 100644 --- a/tui/filepicker.go +++ b/tui/filepicker.go @@ -13,8 +13,8 @@ import ( var ( filePickerItemStyle = lipgloss.NewStyle().PaddingLeft(2) - filePickerSelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205")) - directoryStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("99")) + filePickerSelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("42")) + directoryStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("34")) ) type FilePicker struct { diff --git a/tui/inbox.go b/tui/inbox.go index 86b9dc45f2e71cfd2a770648c976f4048c2633b1..f1ce8e7dd094f19e048308d870334e8845bdca6f 100644 --- a/tui/inbox.go +++ b/tui/inbox.go @@ -70,7 +70,7 @@ func NewInbox(emails []fetcher.Email) *Inbox { l.Title = "Inbox" l.SetShowStatusBar(true) l.SetFilteringEnabled(true) - l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true) + l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true) l.Styles.PaginationStyle = paginationStyle l.Styles.HelpStyle = inboxHelpStyle l.SetStatusBarItemName("email", "emails") diff --git a/tui/styles.go b/tui/styles.go index 253e7f5aa5f31302d412683aca05c27042874e8e..530c499823cd86d2de4535e1be4cf763fc376a8d 100644 --- a/tui/styles.go +++ b/tui/styles.go @@ -8,10 +8,19 @@ import ( "github.com/charmbracelet/lipgloss" ) +// ASCII logo for Matcha displayed during loading screens +const asciiLogo = ` + __ __ + ____ ___ ____ _/ /______/ /_ ____ _ + / __ '__ \/ __ '/ __/ ___/ __ \/ __ '/ + / / / / / / /_/ / /_/ /__/ / / / /_/ / +/_/ /_/ /_/\__,_/\__/\___/_/ /_/\__,_/ +` + var ( DialogBoxStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). - BorderForeground(lipgloss.Color("#874BFD")). + BorderForeground(lipgloss.Color("#25A065")). Padding(1, 0). BorderTop(true). BorderLeft(true). @@ -20,15 +29,15 @@ var ( HelpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240")) SuccessStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true) - InfoStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true) + InfoStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true) H1Style = lipgloss.NewStyle(). - Foreground(lipgloss.Color("205")). + Foreground(lipgloss.Color("42")). Bold(true). Align(lipgloss.Center) H2Style = lipgloss.NewStyle(). - Foreground(lipgloss.Color("205")). + Foreground(lipgloss.Color("42")). Bold(false). // Less bold Align(lipgloss.Center) @@ -47,7 +56,7 @@ type Status struct { func NewStatus(msg string) Status { s := spinner.New() s.Spinner = spinner.Dot - s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) + s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("42")) return Status{spinner: s, message: msg} } @@ -60,5 +69,10 @@ func (m Status) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } func (m Status) View() string { - return fmt.Sprintf("\n\n %s %s\n\n", m.spinner.View(), m.message) + logoStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("42")) + styledLogo := logoStyle.Render(asciiLogo) + + spinnerLine := fmt.Sprintf(" %s %s", m.spinner.View(), m.message) + + return fmt.Sprintf("%s\n%s\n\n", styledLogo, spinnerLine) }