188 lines
4.8 KiB
Go
188 lines
4.8 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"epochsilicon/pkg/debug"
|
|
"epochsilicon/pkg/utils"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
// ShowUpdateDialog displays an enhanced update dialog with download and install options
|
|
func ShowUpdateDialog(updateInfo *utils.UpdateInfo, currentVersion string, myWindow fyne.Window) {
|
|
latestVersion := strings.TrimPrefix(updateInfo.TagName, "v")
|
|
|
|
// Find the DMG asset
|
|
var dmgAsset *utils.Asset
|
|
for _, asset := range updateInfo.Assets {
|
|
if strings.HasSuffix(asset.Name, ".dmg") {
|
|
dmgAsset = &asset
|
|
break
|
|
}
|
|
}
|
|
|
|
if dmgAsset == nil {
|
|
dialog.ShowError(fmt.Errorf("no DMG file found in the latest release"), myWindow)
|
|
return
|
|
}
|
|
|
|
// Create content for the update dialog
|
|
titleLabel := widget.NewLabel(fmt.Sprintf("Update Available: v%s", latestVersion))
|
|
titleLabel.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
currentVersionLabel := widget.NewLabel(fmt.Sprintf("Current version: v%s", currentVersion))
|
|
|
|
// Format file size
|
|
fileSize := formatFileSize(dmgAsset.Size)
|
|
fileSizeLabel := widget.NewLabel(fmt.Sprintf("Download size: %s", fileSize))
|
|
|
|
// Release notes
|
|
notesLabel := widget.NewLabel("Release notes:")
|
|
notesLabel.TextStyle = fyne.TextStyle{Bold: true}
|
|
notesText := widget.NewRichTextFromMarkdown(updateInfo.Body)
|
|
notesScroll := container.NewScroll(notesText)
|
|
notesScroll.SetMinSize(fyne.NewSize(480, 120))
|
|
|
|
// Progress bar (initially hidden)
|
|
progressBar := widget.NewProgressBar()
|
|
progressBar.Hide()
|
|
|
|
progressLabel := widget.NewLabel("")
|
|
progressLabel.Hide()
|
|
|
|
// Checkbox for suppressing this version
|
|
suppressCheck := widget.NewCheck("Don't show this update again", nil)
|
|
|
|
content := container.NewVBox(
|
|
titleLabel,
|
|
currentVersionLabel,
|
|
fileSizeLabel,
|
|
widget.NewSeparator(),
|
|
notesLabel,
|
|
notesScroll,
|
|
widget.NewSeparator(),
|
|
progressBar,
|
|
progressLabel,
|
|
suppressCheck,
|
|
)
|
|
|
|
// Create custom dialog
|
|
d := dialog.NewCustom("New Update Available", "", content, myWindow)
|
|
d.Resize(fyne.NewSize(550, 400))
|
|
|
|
// Download and install function
|
|
downloadAndInstall := func() {
|
|
// Show progress elements
|
|
progressBar.Show()
|
|
progressLabel.Show()
|
|
progressLabel.SetText("Starting download...")
|
|
|
|
// Disable dialog closing during download
|
|
d.SetButtons([]fyne.CanvasObject{})
|
|
|
|
go func() {
|
|
// Download with progress
|
|
downloadPath, err := utils.DownloadUpdate(dmgAsset.BrowserDownloadURL, func(downloaded, total int64) {
|
|
// Update progress on UI thread
|
|
fyne.NewAnimation(
|
|
time.Millisecond*50,
|
|
func(float32) {
|
|
if total > 0 {
|
|
progress := float64(downloaded) / float64(total)
|
|
progressBar.SetValue(progress)
|
|
progressLabel.SetText(fmt.Sprintf("Downloaded: %s / %s (%.1f%%)",
|
|
formatFileSize(downloaded), formatFileSize(total), progress*100))
|
|
}
|
|
},
|
|
).Curve = fyne.AnimationLinear
|
|
})
|
|
|
|
if err != nil {
|
|
progressLabel.SetText(fmt.Sprintf("Download failed: %v", err))
|
|
debug.Printf("Download failed: %v", err)
|
|
|
|
// Re-enable close button
|
|
d.SetButtons([]fyne.CanvasObject{
|
|
widget.NewButton("Close", func() { d.Hide() }),
|
|
})
|
|
return
|
|
}
|
|
|
|
progressLabel.SetText("Installing update...")
|
|
progressBar.SetValue(1.0)
|
|
|
|
// Install update
|
|
err = utils.InstallUpdate(downloadPath)
|
|
if err != nil {
|
|
progressLabel.SetText(fmt.Sprintf("Installation failed: %v", err))
|
|
debug.Printf("Installation failed: %v", err)
|
|
|
|
// Re-enable close button
|
|
d.SetButtons([]fyne.CanvasObject{
|
|
widget.NewButton("Close", func() { d.Hide() }),
|
|
})
|
|
return
|
|
}
|
|
|
|
// Success - show restart dialog
|
|
progressLabel.SetText("Update installed successfully!")
|
|
|
|
restartDialog := dialog.NewConfirm(
|
|
"Update Complete",
|
|
"The update has been installed successfully and will require a restart. Would you like to close the application now?",
|
|
func(restart bool) {
|
|
d.Hide()
|
|
if restart {
|
|
utils.RestartApp()
|
|
fyne.CurrentApp().Quit()
|
|
}
|
|
},
|
|
myWindow,
|
|
)
|
|
restartDialog.Show()
|
|
}()
|
|
}
|
|
|
|
// Set dialog buttons
|
|
d.SetButtons([]fyne.CanvasObject{
|
|
widget.NewButton("Download & Install", downloadAndInstall),
|
|
widget.NewButton("Later", func() {
|
|
if suppressCheck.Checked {
|
|
// Save suppressed version
|
|
prefs, _ := utils.LoadPrefs()
|
|
prefs.SuppressedUpdateVersion = latestVersion
|
|
utils.SavePrefs(prefs)
|
|
}
|
|
d.Hide()
|
|
}),
|
|
})
|
|
|
|
d.Show()
|
|
}
|
|
|
|
// formatFileSize formats a file size in bytes to a human-readable string
|
|
func formatFileSize(bytes int64) string {
|
|
const (
|
|
KB = 1024
|
|
MB = KB * 1024
|
|
GB = MB * 1024
|
|
)
|
|
|
|
switch {
|
|
case bytes >= GB:
|
|
return fmt.Sprintf("%.1f GB", float64(bytes)/float64(GB))
|
|
case bytes >= MB:
|
|
return fmt.Sprintf("%.1f MB", float64(bytes)/float64(MB))
|
|
case bytes >= KB:
|
|
return fmt.Sprintf("%.1f KB", float64(bytes)/float64(KB))
|
|
default:
|
|
return fmt.Sprintf("%d bytes", bytes)
|
|
}
|
|
}
|