package app import ( _ "embed" "os" "os/exec" "strings" "git.sr.ht/~rockorager/vaxis" "git.sr.ht/~rockorager/vaxis/widgets/textinput" "git.tilde.town/nbsp/directory/ui" ) //go:embed homepage.txt var homepage []byte type App struct { allUsers []string users ui.List filter textinput.Model searching bool } func New() *App { users := []string{"(home)"} userDirs, _ := os.ReadDir("/home") for _, user := range userDirs { if user.IsDir() { users = append(users, "~"+user.Name()) } } return &App{users: ui.NewList(users, 0), allUsers: users} } func (app *App) Event(state *ui.State, event vaxis.Event) { if key, ok := event.(vaxis.Key); ok && key.EventType == vaxis.EventPress { other := false switch key.String() { case "Ctrl+c", "Ctrl+d": close(ui.Quit) case "Down", "Ctrl+n": app.users.Down() case "Up", "Ctrl+p": app.users.Up() case "End": app.users.End() case "Home": app.users.Home() case "Escape": app.searching = false default: other = true } if other { if !app.searching { switch key.String() { case "q": close(ui.Quit) case "j": app.users.Down() case "k": app.users.Up() case "g": app.users.Home() case "Shift+g": app.users.End() case "/": app.searching = true app.filter.SetContent("") app.users.SetItems(app.allUsers) } } else { app.filter.Update(event) app.users.SetItems(filter(app.allUsers, app.filter.String())) } } } // render sidebar win := state.Window() w, h := win.Size() if len(app.users.Items()) > 0 { app.users.Draw(win.New(0, 0, 20, h-1)) } // render search bar for x := 0; x < w; x++ { setCell(win, x, h-2, '─', vaxis.Style{}) } if app.searching { app.filter.Draw(win.New(0, h-1, w, 1)) } else { win.New(0, h-1, w, 1).Print(vaxis.Segment{Text: "press / to search users", Style: vaxis.Style{Foreground: vaxis.IndexColor(8)}}) } // render page if len(app.users.Items()) == 0 { return } main := win.New(20, 0, w, h-2) if app.users.Items()[app.users.Index()] == "(home)" { // special homepage aligned := win.New(main.Width/2, main.Height/2-8, 47, 15) aligned.Print(vaxis.Segment{Text: string(homepage)}) } else { // user page user := app.users.Items()[app.users.Index()][1:] art, _ := exec.Command("figlet", "-f", "script", user).CombinedOutput() main.Print(vaxis.Segment{Text: string(art)}) } } func setCell(win vaxis.Window, x int, y int, r rune, st vaxis.Style) { win.SetCell(x, y, vaxis.Cell{ Character: vaxis.Character{ Grapheme: string([]rune{r}), }, Style: st, }) } func filter(users []string, query string) []string { var filtered []string for _, s := range users { if strings.Contains(s, query) { filtered = append(filtered, s) } } return filtered }