Skip to content

Commit 5a6cd5b

Browse files
feat: update theme and keybindings, enhance UI rendering, bumped up the big V
- Changed default theme from "midnight" to "catppuccin" in configuration. - Added new keybindings for managing plugins, opening plugin directory, toggling strike, and accessing help. - Refactored UI rendering in various components to improve performance and maintain consistency with the new theme. - Introduced a new "Completed" view in the task management system. - Updated styles for better visual hierarchy and user experience across different UI components. - Adjusted keymap configuration to include new keybindings and ensure proper functionality.
1 parent a3dce66 commit 5a6cd5b

16 files changed

Lines changed: 558 additions & 627 deletions

File tree

README.md

Lines changed: 310 additions & 339 deletions
Large diffs are not rendered by default.

VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.1
1+
1.0.2

configs/kairo.example.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[app]
2-
theme = "midnight"
2+
theme = "catppuccin"
33
vim_mode = false
44
show_help = true
55

@@ -44,3 +44,7 @@ view_upcoming = "3"
4444
view_tag = "4"
4545
view_priority = "5"
4646
cycle_theme = "t"
47+
manage_plugins = "p"
48+
open_plugin_dir = "ctrl+g"
49+
toggle_strike = "z"
50+
help = "?"

internal/app/model.go

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -565,11 +565,10 @@ func (m *Model) View() string {
565565
content = m.renderMainUI()
566566
}
567567

568-
return lipgloss.NewStyle().
569-
Width(m.width).
570-
Height(m.height).
571-
Background(m.s.Theme.Bg).
572-
Render(content)
568+
return lipgloss.Place(m.width, m.height, lipgloss.Left, lipgloss.Top, content,
569+
lipgloss.WithWhitespaceChars(" "),
570+
lipgloss.WithWhitespaceBackground(m.s.Theme.Bg),
571+
)
573572
}
574573

575574
func (m *Model) renderMainUI() string {
@@ -601,13 +600,7 @@ func (m *Model) renderMainUI() string {
601600
Background(m.s.Theme.Bg).
602601
Render(body)
603602

604-
// Join vertically and fill entire viewport with background
605-
content := lipgloss.JoinVertical(lipgloss.Left, head, body, foot)
606-
return lipgloss.NewStyle().
607-
Width(m.width).
608-
Height(m.height).
609-
Background(m.s.Theme.Bg).
610-
Render(content)
603+
return lipgloss.JoinVertical(lipgloss.Left, head, body, foot)
611604
}
612605

613606
func (m *Model) rebuildComponentSizes() {

internal/config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@ type KeymapConfig struct {
7171
ViewInbox string `toml:"view_inbox"`
7272
ViewToday string `toml:"view_today"`
7373
ViewUpcoming string `toml:"view_upcoming"`
74+
ViewCompleted string `toml:"view_completed"`
7475
ViewTag string `toml:"view_tag"`
7576
ViewPriority string `toml:"view_priority"`
7677
CycleTheme string `toml:"cycle_theme"`
7778
OpenPluginDir string `toml:"open_plugin_dir"`
7879
ManagePlugins string `toml:"manage_plugins"`
80+
ToggleStrike string `toml:"toggle_strike"`
7981
Help string `toml:"help"`
8082
}
8183

@@ -129,6 +131,7 @@ func Default() Config {
129131
CycleTheme: "t",
130132
OpenPluginDir: "ctrl+g",
131133
ManagePlugins: "p",
134+
ToggleStrike: "z",
132135
Help: "?",
133136
},
134137
}

internal/core/view.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import (
77
type ViewID string
88

99
const (
10-
ViewInbox ViewID = "inbox"
11-
ViewToday ViewID = "today"
12-
ViewUpcoming ViewID = "upcoming"
13-
ViewTag ViewID = "tag"
14-
ViewPriority ViewID = "priority"
10+
ViewInbox ViewID = "inbox"
11+
ViewToday ViewID = "today"
12+
ViewUpcoming ViewID = "upcoming"
13+
ViewCompleted ViewID = "completed"
14+
ViewTag ViewID = "tag"
15+
ViewPriority ViewID = "priority"
1516
)
1617

1718
type View struct {
@@ -101,6 +102,15 @@ func DefaultViews(now time.Time) []View {
101102
Sort: SortDeadline,
102103
},
103104
},
105+
{
106+
ID: ViewCompleted,
107+
Title: "Completed",
108+
Filter: Filter{
109+
Statuses: []Status{StatusDone},
110+
IncludeNilDeadline: true,
111+
Sort: SortUpdated,
112+
},
113+
},
104114
{
105115
ID: ViewTag,
106116
Title: "By Tag",

internal/ui/detail/model.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ func (m *Model) View() string {
109109
return lipgloss.NewStyle().
110110
Width(m.width).
111111
Height(m.height).
112-
Background(m.styles.Theme.Bg).
113112
Render(content)
114113
}
115114

internal/ui/editor/model.go

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -177,76 +177,40 @@ func (m Model) View() string {
177177
}
178178
cardW := min(84, w-6)
179179

180-
title := "NEW TASK"
181-
if m.mode == ModeEdit {
182-
title = "EDIT TASK"
183-
}
184-
185-
header := lipgloss.NewStyle().
186-
Bold(true).
187-
Foreground(m.styles.Theme.Bg).
188-
Background(m.styles.Theme.Accent).
189-
Padding(0, 1).
190-
Render(" " + title + " ")
191-
192-
help := m.styles.Muted.Padding(0, 1).Render("ctrl+s save • esc cancel • tab next")
193-
194-
// Input fields with labels
195180
fields := []string{
196-
m.renderField("TITLE", m.title.View(), m.focus == 0),
197-
m.renderField("TAGS", m.tags.View(), m.focus == 1),
181+
m.renderField("Title", m.title.View(), m.focus == 0),
182+
m.renderField("Tags", m.tags.View(), m.focus == 1),
198183
lipgloss.JoinHorizontal(lipgloss.Left,
199-
m.renderField("PRIORITY", m.priority.View(), m.focus == 2),
200-
m.renderField("STATUS", m.status.View(), m.focus == 4),
184+
m.renderField("Pri", m.priority.View(), m.focus == 2),
185+
m.renderField("Status", m.status.View(), m.focus == 4),
201186
),
202-
m.renderField("DUE", m.deadline.View(), m.focus == 3),
187+
m.renderField("Due", m.deadline.View(), m.focus == 3),
203188
}
204189

205190
if m.deadlineErr != "" {
206-
fields = append(fields, lipgloss.NewStyle().Foreground(m.styles.Theme.Bad).Padding(0, 2).Render(styles.IconError+" ERROR: "+m.deadlineErr))
191+
fields = append(fields, m.styles.Error.Padding(0, 2).Render(m.deadlineErr))
207192
} else if m.deadlinePreview != "" {
208-
fields = append(fields, m.styles.Muted.Padding(0, 2).Render("→ "+m.deadlinePreview))
193+
fields = append(fields, m.styles.Muted.Padding(0, 2).Render(m.deadlinePreview))
209194
}
210195

211196
descView := m.desc.View()
212-
descBox := lipgloss.NewStyle().
213-
Padding(0, 1).
214-
Border(lipgloss.NormalBorder(), false, false, false, true).
215-
BorderLeftForeground(m.styles.Theme.Border)
197+
fields = append(fields, "", lipgloss.NewStyle().Padding(0, 2).Render(descView))
216198

217-
if m.focus == 5 {
218-
descBox = descBox.BorderLeftForeground(m.styles.Theme.Accent)
219-
}
199+
content := lipgloss.JoinVertical(lipgloss.Left, fields...)
220200

221-
fields = append(fields, "\n", lipgloss.NewStyle().Padding(0, 2).Render(descBox.Render(descView)))
222-
223-
content := lipgloss.JoinVertical(lipgloss.Left, append([]string{header, help, ""}, fields...)...)
224-
225-
card := lipgloss.NewStyle().
226-
Width(cardW).
227-
Background(m.styles.Theme.Bg).
228-
Border(lipgloss.RoundedBorder()).
229-
BorderForeground(m.styles.Theme.Accent).
230-
Padding(1, 2).
231-
Render(content)
232-
233-
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, card,
234-
lipgloss.WithWhitespaceChars(" "),
201+
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
202+
m.styles.Overlay.Width(cardW).Render(content),
235203
lipgloss.WithWhitespaceBackground(m.styles.Theme.Bg),
236204
)
237205
}
238206

239207
func (m Model) renderField(label, input string, focused bool) string {
240-
labelStyle := lipgloss.NewStyle().
241-
Foreground(m.styles.Theme.Muted).
242-
Bold(true).
243-
Width(12)
244-
208+
labelStyle := m.styles.Muted.Width(8)
245209
if focused {
246210
labelStyle = labelStyle.Foreground(m.styles.Theme.Accent)
247211
}
248212

249-
return lipgloss.NewStyle().Padding(0, 2).Render(
213+
return lipgloss.NewStyle().Padding(0, 1).Render(
250214
lipgloss.JoinHorizontal(lipgloss.Left, labelStyle.Render(label), input),
251215
)
252216
}

internal/ui/help/model.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ func (m Model) View() string {
5050
}
5151

5252
header := m.styles.Title.Render(" Help & Keybindings ")
53-
// Ensure header fills width with background
54-
header = lipgloss.NewStyle().
55-
Width(cardW).
56-
Background(m.styles.Theme.Bg).
57-
Padding(0, 1).
58-
Render(header)
5953

6054
// Helper to extract keys from binding
6155
getK := func(b key.Binding) string {

internal/ui/keymap/keymap.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ type Keymap struct {
1818
Back key.Binding
1919
Quit key.Binding
2020

21-
ViewInbox key.Binding
22-
ViewToday key.Binding
23-
ViewUpcoming key.Binding
24-
ViewTag key.Binding
25-
ViewPriority key.Binding
21+
ViewInbox key.Binding
22+
ViewToday key.Binding
23+
ViewUpcoming key.Binding
24+
ViewCompleted key.Binding
25+
ViewTag key.Binding
26+
ViewPriority key.Binding
2627

2728
CycleTheme key.Binding
2829
OpenPluginDir key.Binding
2930
ManagePlugins key.Binding
31+
ToggleStrike key.Binding
3032
Help key.Binding
3133
}
3234

@@ -41,15 +43,17 @@ func FromConfig(c config.KeymapConfig) Keymap {
4143
Back: bind(c.Back, "back", "back"),
4244
Quit: bind(c.Quit, "quit", "quit"),
4345

44-
ViewInbox: bind(c.ViewInbox, "inbox", "inbox view"),
45-
ViewToday: bind(c.ViewToday, "today", "today view"),
46-
ViewUpcoming: bind(c.ViewUpcoming, "upcoming", "upcoming view"),
47-
ViewTag: bind(c.ViewTag, "tag", "tag view"),
48-
ViewPriority: bind(c.ViewPriority, "priority", "priority view"),
46+
ViewInbox: bind(c.ViewInbox, "inbox", "inbox view"),
47+
ViewToday: bind(c.ViewToday, "today", "today view"),
48+
ViewUpcoming: bind(c.ViewUpcoming, "upcoming", "upcoming view"),
49+
ViewCompleted: bind(c.ViewCompleted, "completed", "completed view"),
50+
ViewTag: bind(c.ViewTag, "tag", "tag view"),
51+
ViewPriority: bind(c.ViewPriority, "priority", "priority view"),
4952

5053
CycleTheme: bind(c.CycleTheme, "theme", "theme menu"),
5154
OpenPluginDir: bind(c.OpenPluginDir, "plugins-dir", "open plugins folder"),
5255
ManagePlugins: bind(c.ManagePlugins, "manage-plugins", "manage plugins"),
56+
ToggleStrike: bind(c.ToggleStrike, "strike", "toggle completion with animation"),
5357
Help: bind(c.Help, "help", "show help"),
5458
}
5559
}

0 commit comments

Comments
 (0)