feat: add UI layer (theme, components, screens, main window)

- theme: MinecraftTheme — dark palette with green accents
- components: ServerCard, ProgressBar, PlayButton, SettingsButton, LogoutButton, AvatarImage
- screens: MainScreen (BorderLayout: sidebar + center + bottom bar), LoginScreen (modal form), SettingsScreen (RAM slider + JVM args)
- ui.Launch: wires theme, session, settings into Fyne app
- main.go: delegates to ui.Launch, loads config
- fix: nil-session guard in MainScreen username display

Co-Authored-By: OWL <noreply@anthropic.com>
This commit is contained in:
2026-05-26 11:22:41 +03:00
parent 070b5c0262
commit 1487360215
5 changed files with 436 additions and 20 deletions

View File

@@ -1,2 +1,55 @@
// package ui contains Fyne GUI code (main window, theme, navigation).
// package ui contains the Fyne GUI bootstrap and wiring.
package ui
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"gitea.mrixs.me/Mrixs/MrixsCraft-launcher/internal/auth"
"gitea.mrixs.me/Mrixs/MrixsCraft-launcher/internal/config"
"gitea.mrixs.me/Mrixs/MrixsCraft-launcher/internal/ui/screens"
"gitea.mrixs.me/Mrixs/MrixsCraft-launcher/internal/ui/theme"
)
// Launch initialises the Fyne application with the Minecraft theme and shows the main window.
func Launch(client *auth.Client, session *auth.Session, settings config.Settings) {
a := app.New()
a.Settings().SetTheme(&theme.MinecraftTheme{})
w := a.NewWindow("MrixsCraft")
w.Resize(fyne.NewSize(float32(settings.Width), float32(settings.Height)))
w.CenterOnScreen()
// TODO: fetch from /api/servers.json
serverList := []screens.Modpack{
{Slug: "hitech", Name: "HiTech 1.21"},
{Slug: "vanilla", Name: "Vanilla 1.20"},
}
onPlay := func() {
// TODO: launch selected modpack
}
onSettings := func() {
screens.SettingsScreen(w, func(memoryMB int, extraArgs string) {
settings.MemoryMB = memoryMB
settings.ExtraArgs = extraArgs
_ = config.Save(settings)
})
}
content := screens.MainScreen(w, client, session, serverList, onPlay, onSettings)
w.SetContent(content)
// If no session, show login modal after the window is rendered.
if session == nil {
w.Show()
screens.LoginScreen(w, client, func(sess *auth.Session) {
// Refresh UI with logged-in state.
content := screens.MainScreen(w, client, sess, serverList, onPlay, onSettings)
w.SetContent(content)
})
}
w.ShowAndRun()
}