176 lines
5.3 KiB
Go
176 lines
5.3 KiB
Go
package ui
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"fyne.io/fyne/v2"
|
||
"fyne.io/fyne/v2/container"
|
||
"fyne.io/fyne/v2/widget"
|
||
|
||
"gitea.unprism.ru/KRBL/FemaInstaller/internal/updater"
|
||
"gitea.unprism.ru/KRBL/FemaInstaller/pkg/config"
|
||
)
|
||
|
||
// UpdaterWindow represents the main window for the updater application
|
||
type UpdaterWindow struct {
|
||
Window fyne.Window
|
||
ConfigDisplay *widget.Label
|
||
UpdateButton *widget.Button
|
||
StatusLabel *widget.Label
|
||
ProgressBar *widget.ProgressBar
|
||
StageLabel *widget.Label
|
||
TimeRemainingLabel *widget.Label
|
||
UpdateMethodRadio *widget.RadioGroup
|
||
Updater *updater.Updater
|
||
}
|
||
|
||
// NewUpdaterWindow creates a new window for the updater application
|
||
func NewUpdaterWindow(app fyne.App, config *config.UpdaterConfig, femaUpdater *updater.Updater) *UpdaterWindow {
|
||
window := app.NewWindow("Обновление ПО Фема")
|
||
|
||
// Create update method radio
|
||
updateMethodRadio := widget.NewRadioGroup(
|
||
[]string{"Использовать встроенную версию", "Загрузить с сервера по URL"},
|
||
func(selected string) {
|
||
if selected == "Использовать встроенную версию" {
|
||
femaUpdater.SetUpdateMethod(updater.UpdateMethodEmbedded)
|
||
} else {
|
||
femaUpdater.SetUpdateMethod(updater.UpdateMethodDirectDownload)
|
||
}
|
||
},
|
||
)
|
||
// Default to embedded method
|
||
updateMethodRadio.SetSelected("Использовать встроенную версию")
|
||
|
||
// Create updater window
|
||
updaterWindow := &UpdaterWindow{
|
||
Window: window,
|
||
ConfigDisplay: widget.NewLabel(config.String()),
|
||
StatusLabel: widget.NewLabel(""),
|
||
ProgressBar: widget.NewProgressBar(),
|
||
StageLabel: widget.NewLabel(""),
|
||
TimeRemainingLabel: widget.NewLabel(""),
|
||
UpdateMethodRadio: updateMethodRadio,
|
||
Updater: femaUpdater,
|
||
}
|
||
|
||
// Hide progress elements initially
|
||
updaterWindow.ProgressBar.Hide()
|
||
updaterWindow.StageLabel.Hide()
|
||
updaterWindow.TimeRemainingLabel.Hide()
|
||
|
||
// Create update button
|
||
updaterWindow.UpdateButton = widget.NewButton("Обновить ПО", func() {
|
||
updaterWindow.StatusLabel.SetText("Начало обновления...")
|
||
updaterWindow.UpdateButton.Disable()
|
||
updaterWindow.UpdateMethodRadio.Disable()
|
||
|
||
// Show progress elements
|
||
updaterWindow.ProgressBar.Show()
|
||
updaterWindow.StageLabel.Show()
|
||
updaterWindow.TimeRemainingLabel.Show()
|
||
|
||
// Reset progress
|
||
updaterWindow.ProgressBar.SetValue(0)
|
||
updaterWindow.StageLabel.SetText("Подготовка...")
|
||
updaterWindow.TimeRemainingLabel.SetText("")
|
||
|
||
go func() {
|
||
// Create progress callback
|
||
progressCallback := func(progress updater.ProgressInfo) {
|
||
// Update UI from the main thread
|
||
window.Canvas().Refresh(updaterWindow.ProgressBar)
|
||
|
||
updaterWindow.ProgressBar.SetValue(progress.Percentage / 100)
|
||
updaterWindow.StageLabel.SetText(progress.Stage)
|
||
|
||
// Format time remaining
|
||
if progress.EstimatedTimeRemaining > 0 {
|
||
minutes := int(progress.EstimatedTimeRemaining.Minutes())
|
||
seconds := int(progress.EstimatedTimeRemaining.Seconds()) % 60
|
||
|
||
if minutes > 0 {
|
||
updaterWindow.TimeRemainingLabel.SetText(
|
||
fmt.Sprintf("Осталось примерно: %d мин %d сек", minutes, seconds))
|
||
} else {
|
||
updaterWindow.TimeRemainingLabel.SetText(
|
||
fmt.Sprintf("Осталось примерно: %d сек", seconds))
|
||
}
|
||
} else {
|
||
updaterWindow.TimeRemainingLabel.SetText("")
|
||
}
|
||
}
|
||
|
||
err := femaUpdater.Update(progressCallback)
|
||
if err != nil {
|
||
updaterWindow.StatusLabel.SetText("Ошибка обновления: " + err.Error())
|
||
} else {
|
||
updaterWindow.StatusLabel.SetText("Обновление успешно завершено!")
|
||
}
|
||
|
||
// Wait a moment to show 100% completion
|
||
time.Sleep(500 * time.Millisecond)
|
||
|
||
// Hide progress elements after completion
|
||
updaterWindow.ProgressBar.Hide()
|
||
updaterWindow.StageLabel.Hide()
|
||
updaterWindow.TimeRemainingLabel.Hide()
|
||
|
||
updaterWindow.UpdateButton.Enable()
|
||
updaterWindow.UpdateMethodRadio.Enable()
|
||
}()
|
||
})
|
||
|
||
// Create title
|
||
title := widget.NewLabel("Программа обновления ПО Фема")
|
||
title.Alignment = fyne.TextAlignCenter
|
||
title.TextStyle = fyne.TextStyle{Bold: true}
|
||
|
||
// Create config section title
|
||
configTitle := widget.NewLabel("Текущая конфигурация:")
|
||
configTitle.TextStyle = fyne.TextStyle{Bold: true}
|
||
|
||
// Create progress section
|
||
progressSection := container.NewVBox(
|
||
updaterWindow.StageLabel,
|
||
updaterWindow.ProgressBar,
|
||
updaterWindow.TimeRemainingLabel,
|
||
)
|
||
|
||
// Create update method section title
|
||
updateMethodTitle := widget.NewLabel("Метод обновления:")
|
||
updateMethodTitle.TextStyle = fyne.TextStyle{Bold: true}
|
||
|
||
// Create layout
|
||
content := container.NewVBox(
|
||
title,
|
||
widget.NewSeparator(),
|
||
configTitle,
|
||
updaterWindow.ConfigDisplay,
|
||
widget.NewSeparator(),
|
||
updateMethodTitle,
|
||
updaterWindow.UpdateMethodRadio,
|
||
widget.NewSeparator(),
|
||
updaterWindow.UpdateButton,
|
||
updaterWindow.StatusLabel,
|
||
progressSection,
|
||
)
|
||
|
||
// Set window content and size
|
||
window.SetContent(content)
|
||
window.Resize(fyne.NewSize(500, 400))
|
||
|
||
return updaterWindow
|
||
}
|
||
|
||
// Show displays the updater window
|
||
func (w *UpdaterWindow) Show() {
|
||
w.Window.Show()
|
||
}
|
||
|
||
// ShowAndRun displays the updater window and starts the application
|
||
func (w *UpdaterWindow) ShowAndRun() {
|
||
w.Window.ShowAndRun()
|
||
}
|