138 lines
2.6 KiB
Go
138 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/charmbracelet/bubbles/list"
|
|
"github.com/charmbracelet/bubbles/progress"
|
|
"github.com/charmbracelet/bubbles/spinner"
|
|
"github.com/charmbracelet/bubbles/textinput"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
)
|
|
|
|
type page int
|
|
|
|
const (
|
|
pageVersionSelect page = iota
|
|
pageMainMenu
|
|
pageCodeInput
|
|
pageExecuting
|
|
)
|
|
|
|
type model struct {
|
|
currentPage page
|
|
exeDir string
|
|
versionDir string
|
|
versionName string
|
|
width int
|
|
height int
|
|
|
|
versionList list.Model
|
|
menuList list.Model
|
|
codeInput textinput.Model
|
|
|
|
spinner spinner.Model
|
|
progress progress.Model
|
|
actions []Action
|
|
actionIdx int
|
|
logLines []string
|
|
execErr error
|
|
execDone bool
|
|
|
|
choosingMirror bool
|
|
mirrorList list.Model
|
|
pendingAction *Action
|
|
backupDir string
|
|
|
|
progressCh chan float64
|
|
}
|
|
|
|
func newModel(exeDir string) model {
|
|
s := spinner.New()
|
|
s.Spinner = spinner.Dot
|
|
|
|
ti := textinput.New()
|
|
ti.Placeholder = "0000"
|
|
ti.CharLimit = 4
|
|
ti.Width = 10
|
|
ti.Validate = func(s string) error {
|
|
for _, r := range s {
|
|
if r < '0' || r > '9' {
|
|
return errNotDigit
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
delegate := list.NewDefaultDelegate()
|
|
vl := list.New(nil, delegate, 80, 20)
|
|
vl.Title = "选择 Minecraft 版本"
|
|
vl.SetFilteringEnabled(false)
|
|
vl.SetShowStatusBar(false)
|
|
|
|
ml := list.New(nil, delegate, 80, 20)
|
|
ml.Title = "主菜单"
|
|
ml.SetFilteringEnabled(false)
|
|
ml.SetShowStatusBar(false)
|
|
|
|
return model{
|
|
currentPage: pageVersionSelect,
|
|
exeDir: exeDir,
|
|
spinner: s,
|
|
progress: progress.New(progress.WithDefaultGradient()),
|
|
codeInput: ti,
|
|
versionList: vl,
|
|
menuList: ml,
|
|
}
|
|
}
|
|
|
|
func (m model) Init() tea.Cmd {
|
|
return scanVersions(m.exeDir)
|
|
}
|
|
|
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
if msg.String() == "ctrl+c" {
|
|
return m, tea.Quit
|
|
}
|
|
case tea.WindowSizeMsg:
|
|
m.width = msg.Width
|
|
m.height = msg.Height
|
|
h := msg.Height - 4
|
|
if h < 5 {
|
|
h = 5
|
|
}
|
|
m.versionList.SetSize(msg.Width, h)
|
|
m.menuList.SetSize(msg.Width, h)
|
|
m.progress.Width = msg.Width - 8
|
|
if m.progress.Width > 80 {
|
|
m.progress.Width = 80
|
|
}
|
|
}
|
|
|
|
switch m.currentPage {
|
|
case pageVersionSelect:
|
|
return updateVersionSelect(m, msg)
|
|
case pageMainMenu:
|
|
return updateMainMenu(m, msg)
|
|
case pageCodeInput:
|
|
return updateCodeInput(m, msg)
|
|
case pageExecuting:
|
|
return updateExecuting(m, msg)
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
func (m model) View() string {
|
|
switch m.currentPage {
|
|
case pageVersionSelect:
|
|
return viewVersionSelect(m)
|
|
case pageMainMenu:
|
|
return viewMainMenu(m)
|
|
case pageCodeInput:
|
|
return viewCodeInput(m)
|
|
case pageExecuting:
|
|
return viewExecuting(m)
|
|
}
|
|
return ""
|
|
}
|