376 lines
8.7 KiB
C#
376 lines
8.7 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using SpotXInstaller.Models;
|
|
using SpotXInstaller.Services;
|
|
|
|
namespace SpotXInstaller.ViewModels;
|
|
|
|
public partial class MainViewModel : ViewModelBase
|
|
{
|
|
private readonly InstallerService _installer = new();
|
|
|
|
private CancellationTokenSource? _cts;
|
|
|
|
// ---------------------------------------------------------
|
|
// SCREEN STATES
|
|
// ---------------------------------------------------------
|
|
|
|
[ObservableProperty]
|
|
private bool _isStepLoading = true;
|
|
|
|
[ObservableProperty]
|
|
private bool _isStepHome;
|
|
|
|
[ObservableProperty]
|
|
private bool _isStepSettings;
|
|
|
|
[ObservableProperty]
|
|
private bool _isStepProgress;
|
|
|
|
// ---------------------------------------------------------
|
|
// POPUP
|
|
// ---------------------------------------------------------
|
|
|
|
[ObservableProperty]
|
|
private bool _showPopup;
|
|
|
|
[ObservableProperty]
|
|
private string _popupTitle = "";
|
|
|
|
[ObservableProperty]
|
|
private string _popupMessage = "";
|
|
|
|
[ObservableProperty]
|
|
private string _popupColor = "#8B5CF6";
|
|
|
|
// ---------------------------------------------------------
|
|
// SETTINGS
|
|
// ---------------------------------------------------------
|
|
|
|
[ObservableProperty]
|
|
private bool _blockUpdates = true;
|
|
|
|
[ObservableProperty]
|
|
private bool _hidePodcasts = true;
|
|
|
|
[ObservableProperty]
|
|
private bool _hidePremium = true;
|
|
|
|
[ObservableProperty]
|
|
private bool _clearCache;
|
|
|
|
// ---------------------------------------------------------
|
|
// PROGRESS
|
|
// ---------------------------------------------------------
|
|
|
|
[ObservableProperty]
|
|
private double _progressValue;
|
|
|
|
[ObservableProperty]
|
|
private string _progressStatus = "Подготовка...";
|
|
|
|
[ObservableProperty]
|
|
private string _miniLog = "";
|
|
|
|
// ---------------------------------------------------------
|
|
// STATE
|
|
// ---------------------------------------------------------
|
|
|
|
[ObservableProperty]
|
|
private bool _isInstalling;
|
|
|
|
public MainViewModel()
|
|
{
|
|
_ = BootAsync();
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// BOOT
|
|
// ---------------------------------------------------------
|
|
|
|
private async Task BootAsync()
|
|
{
|
|
await Task.Delay(3000);
|
|
|
|
SwitchTo(home: true);
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// NAVIGATION
|
|
// ---------------------------------------------------------
|
|
|
|
private void SwitchTo(
|
|
bool loading = false,
|
|
bool home = false,
|
|
bool settings = false,
|
|
bool progress = false)
|
|
{
|
|
IsStepLoading = loading;
|
|
IsStepHome = home;
|
|
IsStepSettings = settings;
|
|
IsStepProgress = progress;
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void GoToSettings()
|
|
{
|
|
if (IsInstalling)
|
|
return;
|
|
|
|
SwitchTo(settings: true);
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void GoBackToHome()
|
|
{
|
|
if (IsInstalling)
|
|
return;
|
|
|
|
SwitchTo(home: true);
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void ClosePopup()
|
|
{
|
|
ShowPopup = false;
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// INSTALL
|
|
// ---------------------------------------------------------
|
|
|
|
[RelayCommand]
|
|
private async Task StartInstallAsync()
|
|
{
|
|
await RunInstallerAsync(isUninstall: false);
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// UNINSTALL
|
|
// ---------------------------------------------------------
|
|
|
|
[RelayCommand]
|
|
private async Task StartUninstallAsync()
|
|
{
|
|
await RunInstallerAsync(isUninstall: true);
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// CANCEL BUTTON
|
|
// ---------------------------------------------------------
|
|
|
|
[RelayCommand]
|
|
private async Task CancelInstallAsync()
|
|
{
|
|
if (!IsInstalling)
|
|
return;
|
|
|
|
ProgressStatus = "Отмена установки...";
|
|
|
|
try
|
|
{
|
|
_cts?.Cancel();
|
|
}
|
|
catch
|
|
{
|
|
// Ignore.
|
|
}
|
|
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// WINDOW CLOSE
|
|
// ---------------------------------------------------------
|
|
|
|
public async Task CancelInstallationAsync()
|
|
{
|
|
if (!IsInstalling)
|
|
return;
|
|
|
|
try
|
|
{
|
|
ProgressStatus = "Завершение процессов...";
|
|
|
|
_cts?.Cancel();
|
|
|
|
// Даём process tree время корректно завершиться.
|
|
await Task.Delay(150);
|
|
}
|
|
catch
|
|
{
|
|
// Ignore.
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// MAIN INSTALLER
|
|
// ---------------------------------------------------------
|
|
|
|
private async Task RunInstallerAsync(bool isUninstall)
|
|
{
|
|
if (IsInstalling)
|
|
return;
|
|
|
|
ProgressValue = 0;
|
|
MiniLog = "";
|
|
|
|
ProgressStatus = isUninstall
|
|
? "Подготовка восстановления..."
|
|
: "Подготовка установки...";
|
|
|
|
SwitchTo(progress: true);
|
|
|
|
_cts?.Dispose();
|
|
_cts = new CancellationTokenSource();
|
|
|
|
IsInstalling = true;
|
|
|
|
var progress =
|
|
new Progress<(int Percent, string Status)>(
|
|
p =>
|
|
{
|
|
ProgressValue = p.Percent;
|
|
ProgressStatus = p.Status;
|
|
});
|
|
|
|
var log =
|
|
new Progress<string>(
|
|
line =>
|
|
{
|
|
MiniLog = line;
|
|
});
|
|
|
|
try
|
|
{
|
|
int code;
|
|
|
|
if (isUninstall)
|
|
{
|
|
code = await _installer.UninstallAsync(
|
|
progress,
|
|
log,
|
|
_cts.Token);
|
|
}
|
|
else
|
|
{
|
|
code = await _installer.InstallAsync(
|
|
new InstallOptions(
|
|
BlockUpdates,
|
|
HidePodcasts,
|
|
HidePremium,
|
|
ClearCache),
|
|
progress,
|
|
log,
|
|
_cts.Token);
|
|
}
|
|
|
|
IsInstalling = false;
|
|
|
|
SwitchTo(home: true);
|
|
|
|
if (code == 0)
|
|
{
|
|
ShowNotification(
|
|
isUninstall
|
|
? "ГОТОВО"
|
|
: "УСПЕХ",
|
|
|
|
isUninstall
|
|
? "Оригинальный клиент Spotify восстановлен."
|
|
: "SpotX успешно установлен.",
|
|
|
|
isUninstall
|
|
? "#8B5CF6"
|
|
: "#00E676");
|
|
}
|
|
else
|
|
{
|
|
string errorText =
|
|
MiniLog.Length > 500
|
|
? MiniLog[..500]
|
|
: MiniLog;
|
|
|
|
ShowNotification(
|
|
"ОШИБКА",
|
|
$"Скрипт завершился с кодом {code}.\n\n{errorText}",
|
|
"#FF3B30");
|
|
}
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
IsInstalling = false;
|
|
|
|
SwitchTo(home: true);
|
|
|
|
ShowNotification(
|
|
"ОТМЕНЕНО",
|
|
"Установка была отменена.",
|
|
"#FFB300");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
IsInstalling = false;
|
|
|
|
SwitchTo(home: true);
|
|
|
|
ShowNotification(
|
|
"ОШИБКА",
|
|
ex.Message,
|
|
"#FF3B30");
|
|
}
|
|
finally
|
|
{
|
|
IsInstalling = false;
|
|
|
|
_cts?.Dispose();
|
|
_cts = null;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// POPUP
|
|
// ---------------------------------------------------------
|
|
|
|
private void ShowNotification(
|
|
string title,
|
|
string message,
|
|
string hexColor)
|
|
{
|
|
PopupTitle = title;
|
|
PopupMessage = message;
|
|
PopupColor = hexColor;
|
|
ShowPopup = true;
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// DISPOSE
|
|
// ---------------------------------------------------------
|
|
|
|
public async Task DisposeAsync()
|
|
{
|
|
if (!IsInstalling)
|
|
return;
|
|
|
|
try
|
|
{
|
|
_cts?.Cancel();
|
|
|
|
await Task.Delay(150);
|
|
}
|
|
catch
|
|
{
|
|
// Ignore.
|
|
}
|
|
|
|
_cts?.Dispose();
|
|
_cts = null;
|
|
|
|
IsInstalling = false;
|
|
}
|
|
}
|
|
|