1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00

Add default entries wizard step

This commit is contained in:
Robert 2025-08-19 09:01:21 +02:00
parent f05faa440c
commit 20fb6b7662
6 changed files with 180 additions and 3 deletions

View File

@ -0,0 +1,32 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:steps="clr-namespace:Artemis.UI.Screens.StartupWizard.Steps"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.StartupWizard.Steps.DefaultEntriesStepView"
x:DataType="steps:DefaultEntriesStepViewModel">
<Border Classes="card">
<Grid RowDefinitions="Auto,Auto,Auto,Auto,*">
<StackPanel Grid.Row="0">
<TextBlock TextWrapping="Wrap">
Installing default plugins and profiles, these will provide you with a basic setup to get started with Artemis.
</TextBlock>
</StackPanel>
<TextBlock Grid.Row="2">
<Run Text="Installed"/>
<Run Text="{CompiledBinding InstalledEntries}"/>
<Run Text=" of "/>
<Run Text="{CompiledBinding TotalEntries}"/>
<Run Text=" entries."/>
</TextBlock>
<ProgressBar Grid.Row="3" Minimum="0" Maximum="{CompiledBinding TotalEntries}" IsIndeterminate="{CompiledBinding FetchingDefaultEntries}" Value="{CompiledBinding InstalledEntries}" />
<StackPanel Grid.Row="4" Orientation="Vertical" IsVisible="{CompiledBinding CurrentEntry, Converter={x:Static ObjectConverters.IsNotNull}}" Margin="0 10">
<TextBlock Text="{CompiledBinding CurrentEntry.Name, StringFormat='Currently installing: {0}'}" />
<ProgressBar Minimum="0" Maximum="100" Value="{CompiledBinding InstallProgress}" />
</StackPanel>
</Grid>
</Border>
</UserControl>

View File

@ -0,0 +1,14 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.StartupWizard.Steps;
public partial class DefaultEntriesStepView : ReactiveUserControl<DefaultEntriesStepViewModel>
{
public DefaultEntriesStepView()
{
InitializeComponent();
}
}

View File

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core.Services;
using Artemis.UI.Extensions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Utilities;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
using Artemis.WebClient.Workshop.Services;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
using StrawberryShake;
namespace Artemis.UI.Screens.StartupWizard.Steps;
public partial class DefaultEntriesStepViewModel : WizardStepViewModel
{
[Notify] private bool _workshopReachable;
[Notify] private bool _fetchingDefaultEntries;
[Notify] private int _totalEntries;
[Notify] private int _installedEntries;
[Notify] private int _installProgress;
[Notify] private IEntrySummary? _currentEntry;
private readonly IWorkshopService _workshopService;
private readonly IWorkshopClient _client;
private readonly IWindowService _windowService;
private readonly Progress<StreamProgress> _currentEntryProgress = new();
public DefaultEntriesStepViewModel(IWorkshopService workshopService, IDeviceService deviceService, IWorkshopClient client, IWindowService windowService)
{
_workshopService = workshopService;
_client = client;
_windowService = windowService;
_currentEntryProgress.ProgressChanged += (_, f) => InstallProgress = f.ProgressPercentage;
Continue = ReactiveCommand.Create(() => Wizard.ChangeScreen<SettingsStepViewModel>());
GoBack = ReactiveCommand.Create(() =>
{
if (deviceService.EnabledDevices.Count == 0)
Wizard.ChangeScreen<DevicesStepViewModel>();
else
Wizard.ChangeScreen<SurfaceStepViewModel>();
});
this.WhenActivatedAsync(async d =>
{
WorkshopReachable = await _workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
if (WorkshopReachable)
{
await InstallDefaultEntries(d.AsCancellationToken());
}
});
}
public async Task<bool> InstallDefaultEntries(CancellationToken cancellationToken)
{
FetchingDefaultEntries = true;
TotalEntries = 0;
InstalledEntries = 0;
if (!WorkshopReachable)
return false;
IOperationResult<IGetDefaultEntriesResult> result = await _client.GetDefaultEntries.ExecuteAsync(100, null, cancellationToken);
List<IEntrySummary> entries = result.Data?.EntriesV2?.Edges?.Select(e => e.Node).Cast<IEntrySummary>().ToList() ?? [];
while (result.Data?.EntriesV2?.PageInfo is {HasNextPage: true})
{
result = await _client.GetDefaultEntries.ExecuteAsync(100, result.Data.EntriesV2.PageInfo.EndCursor, cancellationToken);
if (result.Data?.EntriesV2?.Edges != null)
entries.AddRange(result.Data.EntriesV2.Edges.Select(e => e.Node));
}
await Task.Delay(1000);
FetchingDefaultEntries = false;
TotalEntries = entries.Count;
if (entries.Count == 0)
return false;
foreach (IEntrySummary entry in entries)
{
if (cancellationToken.IsCancellationRequested)
return false;
CurrentEntry = entry;
// Skip entries without a release and entries that are already installed
if (entry.LatestRelease == null || _workshopService.GetInstalledEntry(entry.Id) != null)
{
InstalledEntries++;
continue;
}
EntryInstallResult installResult = await _workshopService.InstallEntry(entry, entry.LatestRelease, _currentEntryProgress, cancellationToken);
// Unlikely as default entries do nothing fancy
if (!installResult.IsSuccess)
{
await _windowService.CreateContentDialog().WithTitle("Failed to install entry")
.WithContent($"Failed to install entry '{entry.Name}' ({entry.Id}): {installResult.Message}")
.WithCloseButtonText("Skip and continue")
.ShowAsync();
}
InstalledEntries++;
}
return true;
}
}

View File

@ -22,7 +22,7 @@ public class DevicesStepViewModel : WizardStepViewModel
Continue = ReactiveCommand.Create(() =>
{
if (deviceService.EnabledDevices.Count == 0)
Wizard.ChangeScreen<SettingsStepViewModel>();
Wizard.ChangeScreen<DefaultEntriesStepViewModel>();
else
Wizard.ChangeScreen<LayoutsStepViewModel>();
});

View File

@ -19,7 +19,7 @@ public class SurfaceStepViewModel : WizardStepViewModel
_deviceService = deviceService;
SelectLayout = ReactiveCommand.Create<string>(ExecuteSelectLayout);
Continue = ReactiveCommand.Create(() => Wizard.ChangeScreen<SettingsStepViewModel>());
Continue = ReactiveCommand.Create(() => Wizard.ChangeScreen<DefaultEntriesStepViewModel>());
GoBack = ReactiveCommand.Create(() => Wizard.ChangeScreen<LayoutsStepViewModel>());
}
@ -30,6 +30,6 @@ public class SurfaceStepViewModel : WizardStepViewModel
// TODO: Implement the layout
_deviceService.AutoArrangeDevices();
Wizard.ChangeScreen<SettingsStepViewModel>();
Wizard.ChangeScreen<DefaultEntriesStepViewModel>();
}
}

View File

@ -18,4 +18,20 @@ query GetPopularEntries {
popularEntries {
...entrySummary
}
}
query GetDefaultEntries($first: Int $after: String) {
entriesV2(where: {isDefault: {eq: true}} first: $first after: $after) {
totalCount
pageInfo {
hasNextPage
endCursor
}
edges {
cursor
node {
...entrySummary
}
}
}
}