Files
arinera-minecraft-tool/model.go
chenxiangtong 3ff2454c63 feat: 重构
2026-05-28 17:37:57 +08:00

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 ""
}