add updating to the ui

This commit is contained in:
olebeck 2023-05-04 16:00:51 +02:00
parent e13856a4ff
commit f2c45d379d
15 changed files with 202 additions and 32 deletions

View File

@ -12,6 +12,7 @@ import (
"time"
"github.com/bedrock-tool/bedrocktool/locale"
"github.com/bedrock-tool/bedrocktool/ui/messages"
"github.com/bedrock-tool/bedrocktool/utils"
"gopkg.in/square/go-jose.v2/json"
@ -80,17 +81,6 @@ func main() {
logrus.Infof(locale.Loc("bedrocktool_version", locale.Strmap{"Version": utils.Version}))
}
go func() {
newVersion, err := utils.Updater.UpdateAvailable()
if err != nil {
logrus.Error(err)
}
if newVersion != "" && utils.Version != "" {
logrus.Infof(locale.Loc("update_available", locale.Strmap{"Version": newVersion}))
}
}()
ctx, cancel := context.WithCancel(context.Background())
flag.StringVar(&utils.RealmsEnv, "realms-env", "", "realms env")
@ -116,6 +106,23 @@ func main() {
ui = &CLI{}
}
utils.CurrentUI = ui
if utils.Version != "" {
go func() {
newVersion, err := utils.Updater.UpdateAvailable()
if err != nil {
logrus.Error(err)
}
if newVersion != "" {
logrus.Infof(locale.Loc("update_available", locale.Strmap{"Version": newVersion}))
utils.UpdateAvailable = newVersion
ui.Message(messages.UpdateAvailable{Version: newVersion})
}
}()
}
// exit cleanup
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

2
go.mod
View File

@ -34,6 +34,7 @@ require (
golang.design/x/lockfree v0.0.1
golang.org/x/crypto v0.8.0
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91
golang.org/x/oauth2 v0.7.0
golang.org/x/text v0.9.0
gopkg.in/square/go-jose.v2 v2.6.0
@ -69,7 +70,6 @@ require (
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91 // indirect
golang.org/x/image v0.7.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.9.0 // indirect

View File

@ -45,6 +45,10 @@ func (c *SkinCMD) Execute(ctx context.Context, ui utils.UI) error {
OnClientConnect: func(conn minecraft.IConn) {
ui.Message(messages.SetUIState(messages.UIStateConnecting))
},
OnServerConnect: func() (cancel bool) {
ui.Message(messages.SetUIState(messages.UIStateMain))
return false
},
})
if proxy.WithClient {

View File

@ -55,7 +55,6 @@ func (c *WorldCMD) Execute(ctx context.Context, ui utils.UI) error {
SaveImage: c.SaveImage,
}))
ui.Message(messages.SetUIState(messages.UIStateConnect))
err = proxy.Run(ctx, serverAddress, hostname)
if err != nil {
return err

View File

@ -17,6 +17,7 @@ import (
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/packs"
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/settings"
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/skins"
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/update"
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/worlds"
"github.com/bedrock-tool/bedrocktool/ui/messages"
"github.com/bedrock-tool/bedrocktool/utils"
@ -75,6 +76,7 @@ func (g *GUI) Start(ctx context.Context, cancel context.CancelFunc) (err error)
g.router.Register("worlds", worlds.New(&g.router))
g.router.Register("skins", skins.New(&g.router))
g.router.Register("packs", packs.New(&g.router))
g.router.Register("update", update.New(&g.router))
g.router.SwitchTo("Settings")

16
ui/gui/icons/main.go Normal file
View File

@ -0,0 +1,16 @@
package icons
import (
"gioui.org/widget"
"golang.org/x/exp/shiny/materialdesign/icons"
)
func mustIcon(data []byte) widget.Icon {
ic, err := widget.NewIcon(data)
if err != nil {
panic(err)
}
return *ic
}
var ActionUpdate = mustIcon(icons.ActionUpdate)

View File

@ -96,7 +96,6 @@ func drawPackIcon(gtx C, hasImage bool, imageOp paint.ImageOp, bounds image.Poin
}
return D{Size: bounds}
})
}
func MulAlpha(c color.NRGBA, alpha uint8) color.NRGBA {

View File

@ -8,9 +8,12 @@ import (
"gioui.org/layout"
"gioui.org/op/paint"
"gioui.org/widget"
"gioui.org/widget/material"
"gioui.org/x/component"
"github.com/bedrock-tool/bedrocktool/ui/messages"
"github.com/bedrock-tool/bedrocktool/utils"
"github.com/sirupsen/logrus"
)
type HandlerFunc = func(data interface{}) messages.MessageResponse
@ -39,6 +42,8 @@ type Router struct {
*component.AppBar
*component.ModalLayer
NonModalDrawer, BottomBar bool
UpdateButton *widget.Clickable
}
func NewRouter(ctx context.Context, invalidate func(), th *material.Theme) Router {
@ -63,6 +68,8 @@ func NewRouter(ctx context.Context, invalidate func(), th *material.Theme) Route
ModalNavDrawer: modalNav,
AppBar: bar,
NavAnim: na,
UpdateButton: &widget.Clickable{},
}
}
@ -90,6 +97,10 @@ func (r *Router) SwitchTo(tag string) {
}
func (r *Router) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions {
if r.UpdateButton.Clicked() {
r.SwitchTo("update")
}
for _, event := range r.AppBar.Events(gtx) {
switch event := event.(type) {
case component.AppBarNavigationClicked:
@ -141,6 +152,18 @@ func (r *Router) Handler(data interface{}) messages.MessageResponse {
return messages.MessageResponse{}
}
func (r *Router) Execute(cmd utils.Command) {
r.Wg.Add(1)
go func() {
defer r.Wg.Done()
err := cmd.Execute(r.Ctx, utils.CurrentUI)
if err != nil {
logrus.Error(err)
}
}()
}
var Pages = map[string]func(*Router) Page{}
func Register(name string, fun func(*Router) Page) {

View File

@ -9,6 +9,7 @@ import (
"gioui.org/widget"
"gioui.org/widget/material"
"gioui.org/x/component"
"github.com/bedrock-tool/bedrocktool/ui/gui/icons"
"github.com/bedrock-tool/bedrocktool/ui/gui/pages"
"github.com/bedrock-tool/bedrocktool/ui/gui/settings"
"github.com/bedrock-tool/bedrocktool/ui/messages"
@ -33,6 +34,8 @@ type Page struct {
}
startButton widget.Clickable
actions []component.AppBarAction
}
func New(router *pages.Router) *Page {
@ -50,6 +53,10 @@ func New(router *pages.Router) *Page {
p.cmdMenu.items = make(map[string]*widget.Clickable, len(utils.ValidCMDs))
options := make([]func(layout.Context) layout.Dimensions, 0, len(utils.ValidCMDs))
for _, name := range cmdNames {
if _, ok := settings.Settings[name]; !ok {
continue
}
item := &widget.Clickable{}
p.cmdMenu.items[name] = item
options = append(options, component.MenuItem(router.Theme, item, name).Layout)
@ -70,7 +77,7 @@ func New(router *pages.Router) *Page {
var _ pages.Page = &Page{}
func (p *Page) Actions() []component.AppBarAction {
return []component.AppBarAction{}
return p.actions
}
func (p *Page) Overflow() []component.OverflowAction {
@ -97,16 +104,7 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
}
p.Router.SwitchTo(p.cmdMenu.selected)
p.Router.Wg.Add(1)
go func() {
defer p.Router.Wg.Done()
err := cmd.Execute(p.Router.Ctx, utils.CurrentUI)
if err != nil {
logrus.Error(err)
}
}()
p.Router.Execute(cmd)
}
}
@ -173,7 +171,17 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
})
}
func (p *Page) Handler(any) messages.MessageResponse {
func (p *Page) Handler(m any) messages.MessageResponse {
switch m.(type) {
case messages.UpdateAvailable:
p.actions = []component.AppBarAction{
component.SimpleIconAction(p.Router.UpdateButton, &icons.ActionUpdate, component.OverflowAction{}),
}
p.Router.AppBar.SetActions(p.actions, nil)
p.Router.Invalidate()
}
return messages.MessageResponse{
Ok: false,
Data: nil,

View File

@ -0,0 +1,107 @@
package update
import (
"fmt"
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
"gioui.org/x/component"
"github.com/bedrock-tool/bedrocktool/ui/gui/pages"
"github.com/bedrock-tool/bedrocktool/ui/messages"
"github.com/bedrock-tool/bedrocktool/utils"
)
type (
C = layout.Context
D = layout.Dimensions
)
type Page struct {
*pages.Router
State messages.UIState
startButton widget.Clickable
err error
updating bool
}
func New(router *pages.Router) *Page {
return &Page{
Router: router,
State: messages.UIStateMain,
}
}
var _ pages.Page = &Page{}
func (p *Page) Actions() []component.AppBarAction {
return []component.AppBarAction{}
}
func (p *Page) Overflow() []component.OverflowAction {
return []component.OverflowAction{}
}
func (p *Page) NavItem() component.NavItem {
return component.NavItem{
Name: "Update",
//Icon: icon.OtherIcon,
}
}
func (p *Page) Layout(gtx C, th *material.Theme) D {
if p.startButton.Clicked() && !p.updating {
p.updating = true
go func() {
p.err = utils.Updater.Update()
if p.err == nil {
p.State = messages.UIStateFinished
}
p.updating = false
p.Router.Invalidate()
}()
}
return layout.Inset{
Top: unit.Dp(25),
Bottom: unit.Dp(25),
Right: unit.Dp(35),
Left: unit.Dp(35),
}.Layout(gtx, func(gtx C) D {
if p.err != nil {
return layout.Center.Layout(gtx, material.H1(th, p.err.Error()).Layout)
}
if p.updating {
return layout.Center.Layout(gtx, material.H3(th, "Updating...").Layout)
}
switch p.State {
case messages.UIStateMain:
// show the main ui
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(material.Label(th, 20, fmt.Sprintf("Current: %s\nNew: %s", utils.Version, utils.UpdateAvailable)).Layout),
layout.Rigid(material.Button(th, &p.startButton, "Do Update").Layout),
)
case messages.UIStateFinished:
return layout.Center.Layout(gtx, func(gtx C) D {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(material.H3(th, "Update Finished").Layout),
layout.Rigid(func(gtx C) D {
return layout.Center.Layout(gtx, material.Label(th, th.TextSize, "restart the app").Layout)
}),
)
})
}
return D{}
})
}
func (p *Page) Handler(data interface{}) messages.MessageResponse {
r := messages.MessageResponse{
Ok: false,
Data: nil,
}
return r
}

View File

@ -41,7 +41,7 @@ func (m *Map) HandlePointerEvent(e pointer.Event) {
case pointer.Release:
m.grabbed = false
case pointer.Scroll:
scaleFactor := -float32(math.Pow(1.01, float64(e.Scroll.Y)))
scaleFactor := float32(math.Pow(1.01, float64(e.Scroll.Y)))
m.transform = m.transform.Scale(e.Position.Sub(m.center), f32.Pt(scaleFactor, scaleFactor))
m.scaleFactor *= scaleFactor
}
@ -122,8 +122,7 @@ func (m *Map) Update(u *messages.UpdateMap) {
}
} else {
for _, pos := range u.UpdatedTiles {
tile := u.Tiles[pos]
drawTile(m.MapImage, m.BoundsMin, pos, tile)
drawTile(m.MapImage, m.BoundsMin, pos, u.Tiles[pos])
}
}

View File

@ -91,9 +91,7 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
return layout.Center.Layout(gtx, material.Label(th, 100, "Connecting").Layout)
case messages.UIStateMain:
// show the main ui
return layout.Flex{
Axis: layout.Vertical,
}.Layout(gtx,
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
//layout.Rigid(material.Label(th, th.TextSize, p.worldName).Layout),
layout.Flexed(1, func(gtx C) D {
return layout.Center.Layout(gtx, p.worldMap.Layout)

View File

@ -96,3 +96,7 @@ type DownloadedPack struct {
type FinishedDownloadingPacks struct {
Packs []*DownloadedPack
}
type UpdateAvailable struct {
Version string
}

View File

@ -15,6 +15,7 @@ import (
"time"
"github.com/bedrock-tool/bedrocktool/locale"
"github.com/bedrock-tool/bedrocktool/ui/messages"
"github.com/repeale/fp-go"
"github.com/sandertv/gophertunnel/minecraft"
"github.com/sandertv/gophertunnel/minecraft/protocol"
@ -390,6 +391,7 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
var cdp *login.ClientData = nil
if p.WithClient && !isReplay {
CurrentUI.Message(messages.SetUIState(messages.UIStateConnect))
err = p.connectClient(ctx, serverAddress, &cdp)
if err != nil {
return err

View File

@ -15,6 +15,8 @@ import (
var Version string
var CmdName = "bedrocktool"
var UpdateAvailable string
const updateServer = "https://updates.yuv.pink/"
type trequester struct {