using System; using System.Reactive; using System.Reactive.Disposables; using System.Threading; using System.Threading.Tasks; using Artemis.UI.Screens.Workshop.Parameters; using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; using Artemis.WebClient.Workshop; using Avalonia.Layout; using AvaloniaEdit.Document; using PropertyChanged.SourceGenerator; using ReactiveUI; using StrawberryShake; namespace Artemis.UI.Screens.Workshop.Library; public partial class SubmissionReleaseViewModel : RoutableScreen { private readonly IWorkshopClient _client; private readonly IRouter _router; private readonly IWindowService _windowService; private readonly INotificationService _notificationService; [Notify] private IGetReleaseById_Release? _release; [Notify] private string? _changelog; [Notify] private bool _hasChanges; public SubmissionReleaseViewModel(IWorkshopClient client, IRouter router, IWindowService windowService, INotificationService notificationService) { _client = client; _router = router; _windowService = windowService; _notificationService = notificationService; this.WhenAnyValue(vm => vm.Changelog, vm => vm.Release, (current, release) => current != release?.Changelog).Subscribe(hasChanges => HasChanges = hasChanges); Discard = ReactiveCommand.Create(ExecuteDiscard, this.WhenAnyValue(vm => vm.HasChanges)); Save = ReactiveCommand.CreateFromTask(ExecuteSave, this.WhenAnyValue(vm => vm.HasChanges)); } public ReactiveCommand Discard { get; set; } public ReactiveCommand Save { get; set; } public override async Task OnNavigating(ReleaseDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken) { IOperationResult result = await _client.GetReleaseById.ExecuteAsync(parameters.ReleaseId, cancellationToken); Release = result.Data?.Release; Changelog = Release?.Changelog; } public override async Task OnClosing(NavigationArguments args) { if (!HasChanges) return; bool confirmed = await _windowService.ShowConfirmContentDialog("You have unsaved changes", "Do you want to discard your unsaved changes?"); if (!confirmed) args.Cancel(); } public async Task DeleteRelease() { if (Release == null) return; bool confirmed = await _windowService.ShowConfirmContentDialog( "Delete release?", "This cannot be undone.\r\n" + "Users that have already downloaded this release will keep it."); if (!confirmed) return; await _client.RemoveRelease.ExecuteAsync(Release.Id); _notificationService.CreateNotification() .WithTitle("Deleted release.") .WithSeverity(NotificationSeverity.Success) .WithHorizontalPosition(HorizontalAlignment.Left) .Show(); HasChanges = false; await Close(); } public async Task Close() { await _router.GoUp(); } private async Task ExecuteSave(CancellationToken cancellationToken) { if (Release == null) return; await _client.UpdateRelease.ExecuteAsync(new UpdateReleaseInput {Id = Release.Id, Changelog = Changelog}, cancellationToken); _notificationService.CreateNotification() .WithTitle("Saved changelog.") .WithSeverity(NotificationSeverity.Success) .WithHorizontalPosition(HorizontalAlignment.Left) .Show(); HasChanges = false; } private void ExecuteDiscard() { Changelog = Release?.Changelog; HasChanges = false; } }