Files
pitodo/app.go
T
2026-11-04 16:33:26 +01:00

70 lines
1.6 KiB
Go

package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
tea "github.com/charmbracelet/bubbletea"
)
type model struct {
project string
todosDir string
count int
}
func newModel(project string) (model, error) {
absolute, err := filepath.Abs(project)
if err != nil {
return model{}, fmt.Errorf("resolve project directory %q: %w", project, err)
}
info, err := os.Stat(absolute)
if err != nil {
return model{}, fmt.Errorf("project directory %q: %w", absolute, err)
}
if !info.IsDir() {
return model{}, fmt.Errorf("project path %q is not a directory", absolute)
}
dir := filepath.Join(absolute, ".pi", "todos")
entries, err := os.ReadDir(dir)
if errors.Is(err, os.ErrNotExist) {
return model{project: absolute, todosDir: dir}, nil
}
if err != nil {
return model{}, fmt.Errorf("read todo directory %q: %w", dir, err)
}
count := 0
for _, entry := range entries {
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".md") {
count++
}
}
return model{project: absolute, todosDir: dir, count: count}, nil
}
func (m model) Init() tea.Cmd { return nil }
func (m model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
if key, ok := message.(tea.KeyMsg); ok {
switch key.String() {
case "q", "ctrl+c":
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() string {
var state string
if m.count == 0 {
state = "No todos yet. Pi stores todo items in this directory."
} else {
state = fmt.Sprintf("Found %d todo file(s). Browsing is coming in the next ticket.", m.count)
}
return fmt.Sprintf("TodoApp\n\nProject: %s\nTodos: %s\n\n%s\n\nPress q or Ctrl+C to quit.\n", m.project, m.todosDir, state)
}