switch back to qt
Some checks failed
CloudSave/pipeline/head There was a failure building this commit

This commit is contained in:
2025-09-13 15:32:37 +02:00
parent 1239c5ed6b
commit 1c89df0673
7 changed files with 0 additions and 514 deletions

View File

@@ -1,46 +0,0 @@
package main
import (
"cloudsave/cmd/gui/window/mainwindow"
"cloudsave/pkg/data"
"cloudsave/pkg/repository"
"fmt"
"os"
"path/filepath"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/dialog"
)
func main() {
a := app.NewWithID("com.thelilfrog.CloudSave")
roaming, err := os.UserConfigDir()
if err != nil {
panic("failed to get user config path: " + err.Error())
}
datastorepath := filepath.Join(roaming, "cloudsave", "data")
err = os.MkdirAll(datastorepath, 0740)
if err != nil {
d := dialog.NewError(fmt.Errorf("cannot make the datastore: %w", err), a.NewWindow("CloudSave"))
d.Show()
d.SetOnClosed(func() {
os.Exit(1)
})
}
repo, err := repository.NewLazyRepository(datastorepath)
if err != nil {
d := dialog.NewError(fmt.Errorf("cannot make the datastore: %w", err), a.NewWindow("CloudSave"))
d.Show()
d.SetOnClosed(func() {
os.Exit(1)
})
}
s := data.NewService(repo)
w := mainwindow.Make(a, s)
w.ShowAndRun()
}

View File

@@ -1,32 +0,0 @@
package about
import (
"cloudsave/pkg/constants"
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
)
func Make(a fyne.App) fyne.Window {
w := a.NewWindow("About CloudSave")
w.Resize(fyne.NewSize(400, 200))
w.CenterOnScreen()
w.SetFixedSize(true)
title := canvas.NewText("CloudSave", color.Black)
title.Alignment = fyne.TextAlignCenter
title.TextSize = 32
version := canvas.NewText("v"+constants.Version, color.Black)
version.Alignment = fyne.TextAlignCenter
version.TextSize = 18
c := container.New(layout.NewVBoxLayout(), title, version)
centered := container.New(layout.NewHBoxLayout(), layout.NewSpacer(), c, layout.NewSpacer())
w.SetContent(container.New(layout.NewVBoxLayout(), centered))
return w
}

View File

@@ -1,53 +0,0 @@
package credential
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
)
type (
CredentialDialog struct {
*dialog.FormDialog
inputUsername *widget.Entry
inputPassword *widget.Entry
}
)
func Make(remoteHostname string, callback func(ok bool, username, password string), w fyne.Window) *CredentialDialog {
label := canvas.NewText(remoteHostname, color.Black)
inputUsername := widget.NewEntry()
inputUsername.SetPlaceHolder("Username")
inputPassword := widget.NewEntry()
inputPassword.Password = true
inputPassword.SetPlaceHolder("Password")
formItems := []*widget.FormItem{
{
Text: "Connexion to ",
Widget: label,
},
{
Text: "Username",
Widget: inputUsername,
},
{
Text: "Password",
Widget: inputPassword,
},
}
d := &CredentialDialog{
inputUsername: inputUsername,
inputPassword: inputPassword,
}
d.FormDialog = dialog.NewForm("Syncing", "Connexion", "Cancel", formItems, func(b bool) {
callback(b, d.inputUsername.Text, d.inputPassword.Text)
}, w)
return d
}

View File

@@ -1,24 +0,0 @@
package loading
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
func Make(msg string, w fyne.Window) *dialog.CustomDialog {
title := canvas.NewText(msg, color.Black)
title.Alignment = fyne.TextAlignCenter
pg := widget.NewProgressBarInfinite()
c := container.New(layout.NewVBoxLayout(), title, pg)
d := dialog.NewCustomWithoutButtons("Loading", c, w)
return d
}

View File

@@ -1,285 +0,0 @@
package mainwindow
import (
"cloudsave/cmd/gui/window/about"
"cloudsave/cmd/gui/window/credential"
"cloudsave/cmd/gui/window/loading"
"cloudsave/cmd/gui/window/properties"
syncdialog "cloudsave/cmd/gui/window/sync"
"cloudsave/pkg/data"
"cloudsave/pkg/remote"
"cloudsave/pkg/remote/client"
"cloudsave/pkg/repository"
"cloudsave/pkg/sync"
"cloudsave/pkg/tools/iterator"
"fmt"
"os"
"path/filepath"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
type (
ExtraLabel struct {
*widget.Label
id string
}
)
func (e *ExtraLabel) SetID(id string) {
e.id = id
}
func Make(a fyne.App, d *data.Service) fyne.Window {
w := a.NewWindow("CloudSave")
w.Resize(fyne.NewSize(1200, 700))
w.CenterOnScreen()
w.SetFixedSize(true)
defer func() {
if r := recover(); r != nil {
d := dialog.NewError(fmt.Errorf("the application crashed: %s", r), w)
d.Show()
d.SetOnClosed(func() {
os.Exit(1)
})
}
}()
games, err := d.AllGames()
if err != nil {
d := dialog.NewError(fmt.Errorf("failed to load datastore: %w", err), w)
d.Show()
d.SetOnClosed(func() {
os.Exit(1)
})
}
list := widget.NewList(
func() int {
return len(games)
},
func() fyne.CanvasObject {
return &ExtraLabel{Label: widget.NewLabel("")}
},
func(i widget.ListItemID, o fyne.CanvasObject) {
o.(*ExtraLabel).SetText(games[i].Name)
o.(*ExtraLabel).SetID(games[i].ID)
})
list.OnSelected = func(id widget.ListItemID) {
properties.Make(a, games[id]).Show()
}
toolbar := widget.NewToolbar(
makeNewButton(d, w, func() {
games, err = d.AllGames()
if err != nil {
fyne.Do(func() {
d := dialog.NewError(fmt.Errorf("failed to load datastore: %w", err), w)
d.Show()
})
return
}
fyne.Do(func() {
list.Refresh()
})
}),
widget.NewToolbarSeparator(),
widget.NewToolbarAction(theme.UploadIcon(), func() {
doSync(d, w)
}),
makeScanButton(d, w),
widget.NewToolbarSpacer(),
widget.NewToolbarAction(theme.HelpIcon(), func() {
aboutWindow := about.Make(a)
aboutWindow.Show()
}),
)
content := container.NewBorder(toolbar, nil, nil, nil, list)
w.SetContent(content)
return w
}
func doSync(d *data.Service, w fyne.Window) {
rs, err := remote.All()
if err != nil {
d := dialog.NewError(fmt.Errorf("failed to load datastore: %w", err), w)
d.Show()
return
}
it := iterator.New(rs)
if it.IsEmpty() {
dialog.NewInformation("Sync", "no remote configured", w).Show()
return
}
dialog := credential.Make(it.Value().URL, syncing(it, d, w), w)
dialog.Show()
}
func syncing(it *iterator.Iterator[remote.Remote], d *data.Service, w fyne.Window) func(bool, string, string) {
return func(b bool, username, password string) {
if b {
r := it.Value()
cli := client.New(r.URL, username, password)
if err := cli.Ping(); err != nil {
dialog.NewError(fmt.Errorf("failed to connect to the server: %w", err), w).Show()
return
}
syncDialog := syncdialog.Make(0, w)
syncDialog.Show()
s := sync.NewSyncer(cli, d)
var errg error
s.SetStateCallback(func(s sync.State, g repository.Metadata) {
switch s {
case sync.FetchingMetdata:
fyne.Do(func() {
syncDialog.UpdateLabel(fmt.Sprintf("%s: fetching metadata from repository", g.Name))
})
case sync.Pushing:
fyne.Do(func() {
syncDialog.UpdateLabel(fmt.Sprintf("%s: pushing data to the server", g.Name))
})
case sync.Pulling:
fyne.Do(func() {
syncDialog.UpdateLabel(fmt.Sprintf("%s: pull data from the server", g.Name))
})
case sync.UpToDate:
fyne.Do(func() {
syncDialog.UpdateLabel(fmt.Sprintf("%s: already up-to-date", g.Name))
})
case sync.Pushed:
fyne.Do(func() {
syncDialog.UpdateLabel(fmt.Sprintf("%s: pushed", g.Name))
})
case sync.Pulled:
fyne.Do(func() {
syncDialog.UpdateLabel(fmt.Sprintf("%s: pulled", g.Name))
})
case sync.Done:
fyne.Do(func() {
syncDialog.Dismiss()
if errg == nil {
dialog.NewInformation("Sync", "The sync ended sucessfully!", w).Show()
}
})
}
})
s.SetErrorCallback(func(err error, g repository.Metadata) {
errg = err
fyne.Do(func() {
dialog.NewError(err, w).Show()
})
})
go s.Sync()
}
}
}
func makeNewButton(d *data.Service, w fyne.Window, callback func()) *widget.ToolbarAction {
return widget.NewToolbarAction(theme.FolderNewIcon(), func() {
folderSelection := dialog.NewFolderOpen(func(lu fyne.ListableURI, err error) {
if err != nil {
d := dialog.NewError(fmt.Errorf("failed to open window: %w", err), w)
d.Show()
return
}
if lu == nil {
return
}
confirmDialog := dialog.NewConfirm("Add", "Do you want to add and scan '"+lu.Path()+"'?", func(accepted bool) {
if !accepted {
return
}
name := filepath.Base(lu.Path())
loadingDialog := loading.Make("Scanning directory", w)
loadingDialog.Show()
go func() {
gameID, err := d.Add(name, lu.Path(), "")
if err != nil {
fyne.Do(func() {
d := dialog.NewError(fmt.Errorf("failed to create metadata the directory: %w", err), w)
d.Show()
loadingDialog.Hide()
})
return
}
_, err = d.Scan(gameID)
if err != nil {
fyne.Do(func() {
d := dialog.NewError(fmt.Errorf("failed to scan the directory: %w", err), w)
d.Show()
loadingDialog.Hide()
})
return
}
loadingDialog.Hide()
callback()
}()
}, w)
confirmDialog.Show()
}, w)
folderSelection.Show()
})
}
func makeScanButton(d *data.Service, w fyne.Window) *widget.ToolbarAction {
return widget.NewToolbarAction(theme.SearchIcon(), func() {
loadingDialog := loading.Make("Scanning directory", w)
loadingDialog.Show()
go func() {
datastore, err := d.AllGames()
if err != nil {
fyne.Do(func() {
dialog.NewError(fmt.Errorf("failed to load datastore: %w", err), w)
loadingDialog.Hide()
})
}
updated := 0
for _, metadata := range datastore {
changed, err := d.Scan(metadata.ID)
if err != nil {
fyne.Do(func() {
dialog.NewError(fmt.Errorf("failed to load datastore: %w", err), w)
loadingDialog.Hide()
})
return
}
if changed {
updated++
}
}
fyne.Do(func() {
loadingDialog.Hide()
if updated == 0 {
dialog.NewInformation("Scan", "Everything is up to date", w).Show()
} else {
dialog.NewInformation("Scan", fmt.Sprintf("%d game updated", updated), w).Show()
}
})
}()
})
}

View File

@@ -1,33 +0,0 @@
package properties
import (
"cloudsave/pkg/repository"
"image/color"
"strconv"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
)
func Make(a fyne.App, g repository.Metadata) fyne.Window {
w := a.NewWindow(g.Name)
w.Resize(fyne.NewSize(800, 300))
w.CenterOnScreen()
w.SetFixedSize(true)
title := canvas.NewText(g.Name, color.Black)
title.Alignment = fyne.TextAlignCenter
title.TextSize = 32
version := canvas.NewText("Version "+strconv.Itoa(g.Version), color.Black)
version.Alignment = fyne.TextAlignCenter
version.TextSize = 18
c := container.New(layout.NewVBoxLayout(), title, version)
centered := container.New(layout.NewHBoxLayout(), layout.NewSpacer(), c, layout.NewSpacer())
w.SetContent(container.New(layout.NewVBoxLayout(), centered))
return w
}

View File

@@ -1,41 +0,0 @@
package sync
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
type (
SyncDialog struct {
*dialog.CustomDialog
label *canvas.Text
pg *widget.ProgressBarInfinite
}
)
func Make(total int, w fyne.Window) *SyncDialog {
title := canvas.NewText("Warming up...", color.Black)
title.Alignment = fyne.TextAlignCenter
pg := widget.NewProgressBarInfinite()
c := container.New(layout.NewVBoxLayout(), title, pg)
d := &SyncDialog{
CustomDialog: dialog.NewCustomWithoutButtons("Syncing", c, w),
label: title,
pg: pg,
}
return d
}
func (s *SyncDialog) UpdateLabel(msg string) {
s.label.Text = msg
s.label.Refresh()
}