-
Notifications
You must be signed in to change notification settings - Fork 106
Support responsive height in Lyrics and Themes views #215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
af9d0ec
4c5c229
c1016b1
3d6591f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,7 +3,10 @@ package model | |||||||||||||||
| import ( | ||||||||||||||||
| "strings" | ||||||||||||||||
|
|
||||||||||||||||
| "charm.land/lipgloss/v2" | ||||||||||||||||
|
|
||||||||||||||||
| "cliamp/theme" | ||||||||||||||||
| "cliamp/ui" | ||||||||||||||||
| ) | ||||||||||||||||
|
|
||||||||||||||||
| // openThemePicker re-loads themes from disk (picking up new user files) | ||||||||||||||||
|
|
@@ -15,6 +18,8 @@ func (m *Model) openThemePicker() { | |||||||||||||||
| // Position cursor on the currently active theme. | ||||||||||||||||
| // Picker list: 0 = Default, 1..N = themes[0..N-1] | ||||||||||||||||
| m.themePicker.cursor = m.themeIdx + 1 | ||||||||||||||||
| m.themePicker.scroll = 0 | ||||||||||||||||
| m.themePickerMaybeAdjustScroll(m.themePickerVisible()) | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // themePickerApply applies the theme under the cursor for live preview. | ||||||||||||||||
|
|
@@ -45,6 +50,54 @@ func (m *Model) themePickerCancel() { | |||||||||||||||
| m.themePicker.visible = false | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| func (m *Model) themePickerHelpLine() string { | ||||||||||||||||
| return helpKey("↓↑", "Scroll ") + helpKey("Enter", "Select ") + helpKey("Esc", "Close") | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+53
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win Help line omits the new keys you just wired up.
♻️ Suggested footer hint additions func (m *Model) themePickerHelpLine() string {
- return helpKey("↓↑", "Scroll ") + helpKey("Enter", "Select ") + helpKey("Esc", "Close")
+ return helpKey("↓↑", "Scroll ") + helpKey("PgUp/Dn", "Page ") +
+ helpKey("Ctrl+X", "Expand ") + helpKey("Enter", "Select ") + helpKey("Esc", "Close")
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| func (m *Model) themePickerVisible() int { | ||||||||||||||||
| probeSections := []string{ | ||||||||||||||||
| titleStyle.Render("T H E M E S"), | ||||||||||||||||
| "", | ||||||||||||||||
| "x", // 1-line list placeholder | ||||||||||||||||
| "", | ||||||||||||||||
| dimStyle.Render(" 0/0 themes"), | ||||||||||||||||
| "", | ||||||||||||||||
| m.themePickerHelpLine(), | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| probeFrame := ui.FrameStyle.Render(strings.Join(probeSections, "\n")) | ||||||||||||||||
| fixedHeight := lipgloss.Height(probeFrame) - 1 | ||||||||||||||||
|
|
||||||||||||||||
| limit := maxPlVisible | ||||||||||||||||
| if m.heightExpanded { | ||||||||||||||||
| limit = m.height | ||||||||||||||||
| } | ||||||||||||||||
| return max(3, min(limit, m.height-fixedHeight)) | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| func (m *Model) themePickerMaybeAdjustScroll(visible int) { | ||||||||||||||||
| if visible <= 0 { | ||||||||||||||||
| return | ||||||||||||||||
| } | ||||||||||||||||
| count := len(m.themes) + 1 | ||||||||||||||||
| if m.themePicker.cursor < 0 { | ||||||||||||||||
| m.themePicker.cursor = 0 | ||||||||||||||||
| } | ||||||||||||||||
| if m.themePicker.cursor >= count && count > 0 { | ||||||||||||||||
| m.themePicker.cursor = count - 1 | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| if m.themePicker.cursor < m.themePicker.scroll { | ||||||||||||||||
| m.themePicker.scroll = m.themePicker.cursor | ||||||||||||||||
| } else if m.themePicker.cursor >= m.themePicker.scroll+visible { | ||||||||||||||||
| m.themePicker.scroll = m.themePicker.cursor - visible + 1 | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| if m.themePicker.scroll+visible > count && count > 0 { | ||||||||||||||||
| m.themePicker.scroll = max(0, count-visible) | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+53
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff Theme-picker visibility/scroll helpers are correct but largely duplicate the keymap & file browser pattern.
Not blocking — just worth keeping in mind as the next overlay is added. 🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| // openPlaylistManager loads playlist metadata and opens the manager overlay. | ||||||||||||||||
| func (m *Model) openPlaylistManager() { | ||||||||||||||||
| m.plMgrResetFilter() | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Helper looks correct; just verify the overhead constant stays in sync with the renderer.
max(3, min(limit, m.height-4))mirrors the structure used bykeymapVisible/fbVisible/themePickerVisible. The hard-coded4corresponds to the renderer's "title (1) + blank (1) + blank (1) + helpKey footer (1)" overhead. That's currently correct (renderLyricsOverlayinview_overlays.goopens withtitleStyle…+""and closes with""+ helpKey), but it's an implicit coupling — if anyone adds, say, a subtitle line to the header the overhead drifts silently.Two small things to consider:
lyricsOverheadLines = 4) shared with the renderer, or compute it via the samelipgloss.Height(probeFrame)probe pattern the other overlays use.m Model) whilelyricsArtistTitle/lyricsSyncablein the same file use pointer receivers. Minor, but(m *Model)would avoid copying the model on every render call.🤖 Prompt for AI Agents