Skip to content

Commit

Permalink
Add an about screen + numeric navigation on menus (#6)
Browse files Browse the repository at this point in the history
* Add an about screen + numeric navigation on menus

* Update menus.go

* version.txt
  • Loading branch information
g026r authored Sep 27, 2024
1 parent 11f7e07 commit 045b709
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@
*.zip
*.gz
/build.sh
/pkg/ui/version.txt
33 changes: 21 additions & 12 deletions pkg/ui/menus.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
goio "io"
"runtime"
"strconv"
"strings"
"time"

Expand All @@ -21,6 +22,7 @@ const (
lib menuKey = iota
thumbs
config
about
save
quit
add
Expand Down Expand Up @@ -67,6 +69,7 @@ var (
menuItem{"Library", lib},
menuItem{"Thumbnails", thumbs},
menuItem{"Settings", config},
menuItem{"About", about},
menuItem{"Save & Quit", save},
menuItem{"Quit", quit}}
libraryOptions = []list.Item{
Expand Down Expand Up @@ -179,24 +182,16 @@ var (
// def consists of the default actions when nothing else is to be done
def = map[screen]func(m *Model, msg tea.Msg) (*Model, tea.Cmd){
MainMenu: func(m *Model, msg tea.Msg) (*Model, tea.Cmd) {
var cmd tea.Cmd
m.mainMenu, cmd = m.mainMenu.Update(msg)
return m, cmd
return defaultAction(MainMenu, &m.mainMenu, m, msg)
},
LibraryMenu: func(m *Model, msg tea.Msg) (*Model, tea.Cmd) {
var cmd tea.Cmd
m.subMenu, cmd = m.subMenu.Update(msg)
return m, cmd
return defaultAction(LibraryMenu, &m.subMenu, m, msg)
},
ThumbMenu: func(m *Model, msg tea.Msg) (*Model, tea.Cmd) {
var cmd tea.Cmd
m.subMenu, cmd = m.subMenu.Update(msg)
return m, cmd
return defaultAction(ThumbMenu, &m.subMenu, m, msg)
},
ConfigMenu: func(m *Model, msg tea.Msg) (*Model, tea.Cmd) {
var cmd tea.Cmd
m.configMenu, cmd = m.configMenu.Update(msg)
return m, cmd
return defaultAction(ConfigMenu, &m.configMenu, m, msg)
},
EditList: func(m *Model, msg tea.Msg) (*Model, tea.Cmd) {
var cmd tea.Cmd
Expand All @@ -216,6 +211,20 @@ var (
}
)

// defaulAction is a default action for sub menus allowing numeric navigation.
// It's not easily doable for game list menus as there may be too many items to handle key-presses without storing the previous press & waiting to process it.
func defaultAction(scr screen, menu *list.Model, m *Model, msg tea.Msg) (*Model, tea.Cmd) {
if k, ok := msg.(tea.KeyMsg); ok {
if i, err := strconv.Atoi(k.String()); err == nil && i >= 1 && i <= len(menu.Items()) {
menu.Select(i - 1)
return enter[scr](m, msg)
}
}
var cmd tea.Cmd
*menu, cmd = menu.Update(msg)
return m, cmd
}

// pop is the ESC action for basically everything but main menu
// It removes the latest item from the stack, allowing the rendering to go up one level
func pop(m *Model, _ tea.Msg) (*Model, tea.Cmd) {
Expand Down
45 changes: 34 additions & 11 deletions pkg/ui/model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ui

import (
_ "embed"
"encoding/binary"
"encoding/hex"
"fmt"
Expand All @@ -22,6 +23,9 @@ import (
"github.com/g026r/pocket-toolkit/pkg/util"
)

//go:embed version.txt
var version string

type errMsg struct {
err error
fatal bool
Expand Down Expand Up @@ -78,7 +82,7 @@ func NewModel() tea.Model {

return &Model{
stack: stack{[]screen{Initializing}},
spinner: spinner.New(spinner.WithSpinner(spinner.MiniDot)),
spinner: spinner.New(spinner.WithSpinner(spinner.MiniDot), spinner.WithStyle(itemStyle.Foreground(blue))),
progress: progress.New(opt),
Config: &config,
mainMenu: *NewMainMenu(),
Expand All @@ -101,14 +105,14 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.anyKey = true
}
case tea.KeyMsg:
if msg.String() == "ctrl+c" {
return m, tea.Quit
}
if m.anyKey {
m.anyKey = false
m.percent = 0.0
return pop(m, msg)
}
if msg.String() == "ctrl+c" {
return m, tea.Quit
}
case spinner.TickMsg:
if m.initialized {
break // initialized gets set as the last step of initialization. If it's true, we can stop the spinner.
Expand Down Expand Up @@ -162,12 +166,9 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m *Model) View() (s string) {
switch m.Peek() {
case Initializing:
s = fmt.Sprintf(" %s Loading your Pocket library. Please wait.", m.spinner.View())
s = fmt.Sprintf("%s %s", m.spinner.View(), "Loading your Pocket library. Please wait.")
case Waiting:
s = fmt.Sprintf("\n %s\n\n %s", m.wait, m.progress.ViewAs(m.percent))
if m.anyKey {
s = fmt.Sprintf("%s\n\n Press any key to continue.", s)
}
s = fmt.Sprintf("\n%s\n\n%s", itemStyle.Render(m.wait), itemStyle.Render(m.progress.ViewAs(m.percent)))
case Saving:
s = fmt.Sprintf("\n Saving your Pocket library\n\n %s", m.progress.ViewAs(m.percent))
case FatalError:
Expand All @@ -181,16 +182,34 @@ func (m *Model) View() (s string) {
case RemoveList, EditList, GenerateList:
s = m.gameList.View()
case EditScreen:
s = m.inputView("Edit Game")
s = m.inputView(fmt.Sprintf("Edit Game > %s", m.gameList.SelectedItem().(models.Entry).Name))
case AddScreen:
s = m.inputView("Add Game")
case AboutScreen:
s = aboutView()
default:
panic("Panic! At the View() call")
}

if m.anyKey {
s = fmt.Sprintf("%s\n\n%s", s, itemStyle.Render("Press any key to continue."))
}

return
}

func aboutView() string {
s := fmt.Sprintf(" %s", titleStyle.Render("Unofficial Analogue Pocket library toolkit"))

v := strings.Split(version, ",")
s = fmt.Sprintf("%s\n\n%s", s, itemStyle.Render("Version:", v[0]))
s = fmt.Sprintf("%s\n%s", s, itemStyle.Render("Built:", v[1]))
s = fmt.Sprintf("%s\n\n%s", s, itemStyle.Render("Bug reports, feature requests, & new versions:"))
s = fmt.Sprintf("%s\n%s", s, selectedItemStyle.PaddingLeft(6).Render("https://github.com/g026r/pocket-library-toolkit"))

return s
}

// initSystem loads all our data from disk
func (m *Model) initSystem() tea.Msg {
var d string
Expand Down Expand Up @@ -491,7 +510,7 @@ func (m *Model) genSingle(e models.Entry) tea.Cmd {
}

func (m *Model) inputView(title string) string {
s := fmt.Sprintf(" %s", titleStyle.MarginLeft(2).Render(fmt.Sprintf("Main > Library > %s", title)))
s := fmt.Sprintf(" %s", titleStyle.Render(fmt.Sprintf("Main > Library > %s", title)))
s = fmt.Sprintf("%s\n\n%s\n%s\n", s, m.gameInput[name].View(), errorStyle.Render(m.gameInput[name].error()))
if m.AdvancedEditing || m.Peek() == AddScreen {
s = fmt.Sprintf("%s%s\n%s\n", s, m.gameInput[system].View(), errorStyle.Render(m.gameInput[system].error()))
Expand Down Expand Up @@ -723,6 +742,10 @@ func (m *Model) processMenuItem(key menuKey) (*Model, tea.Cmd) {
case config:
m.configMenu.ResetSelected()
m.Push(ConfigMenu)
case about:
m.Push(AboutScreen)
m.anyKey = true
// TODO: Add a basic about screen
case quit:
return m, tea.Quit
case save:
Expand Down
1 change: 1 addition & 0 deletions pkg/ui/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
Waiting
Initializing
FatalError
AboutScreen
)

// stack is a simple struct for keeping track of the screen we are currently on & the ones that came before it.
Expand Down
Empty file added pkg/ui/version.txt
Empty file.

0 comments on commit 045b709

Please sign in to comment.