1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 13:28:33 +00:00

More default entries UX

This commit is contained in:
Robert 2025-11-30 15:41:21 +01:00
parent 7c435fb037
commit adbf850bff
12 changed files with 103 additions and 34 deletions

View File

@ -35,4 +35,11 @@
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
<Compile Update="Screens\StartupWizard\Steps\WorkshopUnreachableStepView.axaml.cs">
<DependentUpon>WorkshopUnreachableStepView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@ -14,13 +14,13 @@
Width="1050"
Height="735"
WindowStartupLocation="CenterOwner">
<Grid Margin="15" RowDefinitions="Auto,*,Auto" ColumnDefinitions="Auto,*">
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" RowDefinitions="*,*" ColumnDefinitions="Auto,*,Auto">
<Grid Margin="15" RowDefinitions="Auto,*,Auto">
<!-- Header -->
<Grid Grid.Row="0" RowDefinitions="*,*" ColumnDefinitions="Auto,*,Auto">
<Image Grid.Column="0" Grid.RowSpan="2" Width="65" Height="65" VerticalAlignment="Center" Source="/Assets/Images/Logo/bow.png" Margin="0 0 20 0" />
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom">
Artemis 2
</TextBlock>
<StackPanel Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Orientation="Horizontal">
<HyperlinkButton Classes="icon-button" ToolTip.Tip="View website" NavigateUri="https://artemis-rgb.com?mtm_campaign=artemis&amp;mtm_kwd=wizard">
<avalonia:MaterialIcon Kind="Web" />
@ -32,13 +32,11 @@
<avalonia:MaterialIcon Kind="BookOpenOutline" />
</HyperlinkButton>
</StackPanel>
<TextBlock Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Top"
Classes="subtitle"
Text="{CompiledBinding Version}" />
<HyperlinkButton Grid.Row="1"
Grid.Column="2"
VerticalAlignment="Top"
@ -46,19 +44,19 @@
PolyForm Noncommercial License 1.0.0
</HyperlinkButton>
</Grid>
<controls:Frame Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Name="Frame" IsNavigationStackEnabled="False" CacheSize="0">
<!-- Main Content -->
<controls:Frame Grid.Row="1" Name="Frame" IsNavigationStackEnabled="False" CacheSize="0">
<controls:Frame.NavigationPageFactory>
<ui:PageFactory/>
</controls:Frame.NavigationPageFactory>
</controls:Frame>
<Button Grid.Row="2" Grid.Column="0" Command="{CompiledBinding SkipOrFinishWizard}" IsVisible="{CompiledBinding !Screen.ShowFinish}">Skip &amp; close</Button>
<StackPanel Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal" Spacing="5" Margin="0 15 0 0">
<Button Command="{CompiledBinding Screen.GoBack}" IsEnabled="{CompiledBinding Screen.ShowGoBack}">Back</Button>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding !Screen.ShowFinish}" Width="80">Continue</Button>
<Button Command="{CompiledBinding SkipOrFinishWizard}" IsVisible="{CompiledBinding Screen.ShowFinish}" Width="80">Finish</Button>
</StackPanel>
<!-- Buttons Panel -->
<DockPanel Grid.Row="2" LastChildFill="False" IsVisible="{CompiledBinding !Screen.HideAllButtons}" HorizontalSpacing="10">
<Button Command="{CompiledBinding SkipOrFinishWizard}" IsVisible="{CompiledBinding !Screen.ShowFinish}" DockPanel.Dock="Left">Skip &amp; close</Button>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding !Screen.ShowFinish}" Width="80" DockPanel.Dock="Right">Continue</Button>
<Button Command="{CompiledBinding Screen.GoBack}" IsEnabled="{CompiledBinding Screen.ShowGoBack}" DockPanel.Dock="Right">Back</Button>
<Button Command="{CompiledBinding SkipOrFinishWizard}" IsVisible="{CompiledBinding Screen.ShowFinish}" Width="80" DockPanel.Dock="Right">Finish</Button>
</DockPanel>
</Grid>
</Window>

View File

@ -13,8 +13,10 @@
Below is a list of default features that can be installed to get you started with Artemis. You can always install or uninstall features later via the Workshop.
</TextBlock>
<ProgressBar Grid.Row="1" IsVisible="{CompiledBinding FetchingDefaultEntries}" IsIndeterminate="True" />
<StackPanel Grid.Row="1" IsVisible="{CompiledBinding FetchingDefaultEntries}" HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
<ProgressBar IsIndeterminate="True" Width="400" />
<TextBlock TextAlignment="Center">Fetching default features from the Artemis workshop...</TextBlock>
</StackPanel>
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock Classes="card-title" IsVisible="{CompiledBinding DeviceProviderEntryViewModels.Count}">
@ -58,9 +60,10 @@
<TextBlock Classes="card-title">
Currently installing
</TextBlock>
<ContentControl Content="{CompiledBinding CurrentEntry}"/>
<ProgressBar ShowProgressText="True" ProgressTextFormat="{}{0}/{3} Features Installed ({1:0}%)" Minimum="0" Maximum="{CompiledBinding TotalEntries}" Value="{CompiledBinding InstalledEntries}"/>
<ContentControl Content="{CompiledBinding CurrentEntry}" />
<ProgressBar ShowProgressText="True" ProgressTextFormat="{}{0}/{3} Features Installed ({1:0}%)" Minimum="0" Maximum="{CompiledBinding TotalEntries}"
Value="{CompiledBinding InstalledEntries}" />
</StackPanel>
</Panel>
</UserControl>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core.Services;
@ -18,8 +19,7 @@ namespace Artemis.UI.Screens.StartupWizard.Steps;
public partial class DefaultEntriesStepViewModel : WizardStepViewModel
{
[Notify] private bool _workshopReachable;
[Notify] private bool _fetchingDefaultEntries;
[Notify] private bool _fetchingDefaultEntries = true;
[Notify] private int _installedEntries;
[Notify] private int _totalEntries = 1;
[Notify] private DefaultEntryItemViewModel? _currentEntry;
@ -44,16 +44,16 @@ public partial class DefaultEntriesStepViewModel : WizardStepViewModel
{
await Install(ct);
ExecuteContinue();
});
}, this.WhenAnyValue(vm => vm.FetchingDefaultEntries).Select(b => !b));
GoBack = ReactiveCommand.Create(() => Wizard.ChangeScreen<WelcomeStepViewModel>());
this.WhenActivatedAsync(async d =>
{
WorkshopReachable = await workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
if (WorkshopReachable)
{
CancellationToken ct = d.AsCancellationToken();
if (await workshopService.ValidateWorkshopStatus(false, ct))
await GetDefaultEntries(d.AsCancellationToken());
}
else if (!ct.IsCancellationRequested)
Wizard.ChangeScreen<WorkshopUnreachableStepViewModel>();
});
}
@ -95,9 +95,6 @@ public partial class DefaultEntriesStepViewModel : WizardStepViewModel
private async Task GetDefaultEntries(CancellationToken cancellationToken)
{
if (!WorkshopReachable)
return;
FetchingDefaultEntries = true;
IOperationResult<IGetDefaultEntriesResult> result = await _client.GetDefaultEntries.ExecuteAsync(100, null, cancellationToken);

View File

@ -0,0 +1,30 @@
<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"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.StartupWizard.Steps.WorkshopUnreachableStepView"
x:DataType="steps:WorkshopUnreachableStepViewModel">
<StackPanel>
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextAlignment" Value="Center"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">Could not reach the workshop</TextBlock>
<TextBlock MaxWidth="600" Classes="subtitle">This unfortunately means the setup wizard cannot continue.</TextBlock>
<avalonia:MaterialIcon Kind="LanDisconnect" Width="120" Height="120" Margin="0 60"></avalonia:MaterialIcon>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Please ensure you are connected to the internet.</TextBlock>
<TextBlock Margin="0 5" Classes="subtitle">If this keeps occuring, hit us up on Discord</TextBlock>
<Button HorizontalAlignment="Center" Margin="0 20" Command="{CompiledBinding Retry}">Retry</Button>
<Button HorizontalAlignment="Center" Command="{CompiledBinding Skip}">Try again on next launch</Button>
</StackPanel>
</UserControl>

View File

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

View File

@ -0,0 +1,19 @@
namespace Artemis.UI.Screens.StartupWizard.Steps;
public class WorkshopUnreachableStepViewModel : WizardStepViewModel
{
public WorkshopUnreachableStepViewModel()
{
HideAllButtons = true;
}
public void Retry()
{
Wizard.ChangeScreen<DefaultEntriesStepViewModel>();
}
public void Skip()
{
Wizard.Close(false);
}
}

View File

@ -15,6 +15,7 @@ public abstract partial class WizardStepViewModel : ValidatableViewModelBase
[Notify] private bool _showFinish;
[Notify] private bool _showGoBack = true;
[Notify] private bool _showHeader = true;
[Notify] private bool _hideAllButtons;
public StartupWizardViewModel Wizard { get; set; } = null!;
}

View File

@ -41,7 +41,7 @@ public partial class WorkshopHomeViewModel : RoutableScreen
this.WhenActivatedAsync(async d =>
{
WorkshopReachable = await workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
WorkshopReachable = await workshopService.ValidateWorkshopStatus(true, d.AsCancellationToken());
IOperationResult<IGetPopularEntriesResult> popularResult = await client.GetPopularEntries.ExecuteAsync();
popular.Edit(p =>

View File

@ -63,7 +63,7 @@ public partial class SubmissionsTabViewModel : RoutableScreen
this.WhenActivatedAsync(async d =>
{
WorkshopReachable = await workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
WorkshopReachable = await workshopService.ValidateWorkshopStatus(true, d.AsCancellationToken());
if (WorkshopReachable)
await GetEntries(d.AsCancellationToken());
});

View File

@ -54,9 +54,10 @@ public interface IWorkshopService
/// <summary>
/// Validates the status of the workshop.
/// </summary>
/// <param name="navigateIfUnreachable">Whether to navigate to the offline page if the workshop is unreachable.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A boolean indicating whether the workshop is reachable.</returns>
Task<bool> ValidateWorkshopStatus(CancellationToken cancellationToken);
Task<bool> ValidateWorkshopStatus(bool navigateIfUnreachable, CancellationToken cancellationToken);
/// <summary>
/// Navigates to a specific entry.

View File

@ -130,10 +130,10 @@ public class WorkshopService : IWorkshopService
}
/// <inheritdoc />
public async Task<bool> ValidateWorkshopStatus(CancellationToken cancellationToken)
public async Task<bool> ValidateWorkshopStatus(bool navigateIfUnreachable, CancellationToken cancellationToken)
{
IWorkshopService.WorkshopStatus status = await GetWorkshopStatus(cancellationToken);
if (!status.IsReachable && !cancellationToken.IsCancellationRequested)
if (navigateIfUnreachable && !status.IsReachable && !cancellationToken.IsCancellationRequested)
await _router.Navigate($"workshop/offline/{status.Message}");
return status.IsReachable;
}