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() }