package pages import ( "log/slog" "tasksquire/common" "tasksquire/components/picker" "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) type ProjectPickerPage struct { common *common.Common picker *picker.Picker } func NewProjectPickerPage(common *common.Common, activeProject string) *ProjectPickerPage { p := &ProjectPickerPage{ common: common, } projects := common.TW.GetProjects() items := []list.Item{picker.NewItem("(none)")} for _, proj := range projects { items = append(items, picker.NewItem(proj)) } onSelect := func(item list.Item) tea.Cmd { return func() tea.Msg { return projectSelectedMsg{item: item} } } p.picker = picker.New(common, "Projects", items, onSelect) // Set active project if activeProject == "" { activeProject = "(none)" } p.picker.SelectItemByFilterValue(activeProject) p.SetSize(common.Width(), common.Height()) return p } func (p *ProjectPickerPage) SetSize(width, height int) { p.common.SetSize(width, height) // Set list size with some padding/limits to look like a picker listWidth := width - 4 if listWidth > 40 { listWidth = 40 } listHeight := height - 6 if listHeight > 20 { listHeight = 20 } p.picker.SetSize(listWidth, listHeight) } func (p *ProjectPickerPage) Init() tea.Cmd { return p.picker.Init() } type projectSelectedMsg struct { item list.Item } func (p *ProjectPickerPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { case tea.WindowSizeMsg: p.SetSize(msg.Width, msg.Height) case projectSelectedMsg: proj := msg.item.(picker.Item).Title() if proj == "(none)" { proj = "" } model, err := p.common.PopPage() if err != nil { slog.Error("page stack empty") return nil, tea.Quit } return model, func() tea.Msg { return UpdateProjectMsg(proj) } case tea.KeyMsg: switch { case key.Matches(msg, p.common.Keymap.Back): model, err := p.common.PopPage() if err != nil { slog.Error("page stack empty") return nil, tea.Quit } return model, BackCmd } } _, cmd = p.picker.Update(msg) return p, cmd } func (p *ProjectPickerPage) View() string { width := p.common.Width() - 4 if width > 40 { width = 40 } content := p.picker.View() styledContent := lipgloss.NewStyle().Width(width).Render(content) return lipgloss.Place( p.common.Width(), p.common.Height(), lipgloss.Center, lipgloss.Center, p.common.Styles.Base.Render(styledContent), ) } func (p *ProjectPickerPage) updateProjectCmd() tea.Msg { return nil } type UpdateProjectMsg string