Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workshop - Added release details and reworked installation management #850

Merged
merged 9 commits into from
Apr 14, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ internal interface IRoutableHostScreen : IRoutableScreen
{
bool RecycleScreen { get; }
IRoutableScreen? InternalScreen { get; }
IRoutableScreen? InternalDefaultScreen { get; }
void InternalChangeScreen(IRoutableScreen? screen);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ public bool RecycleScreen
protected set => RaiseAndSetIfChanged(ref _recycleScreen, value);
}

/// <summary>
/// Gets the screen to show when no other screen is active.
/// </summary>
public virtual TScreen? DefaultScreen { get; }

IRoutableScreen? IRoutableHostScreen.InternalScreen => Screen;
IRoutableScreen? IRoutableHostScreen.InternalDefaultScreen => DefaultScreen;

void IRoutableHostScreen.InternalChangeScreen(IRoutableScreen? screen)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ public bool RecycleScreen
protected set => RaiseAndSetIfChanged(ref _recycleScreen, value);
}

/// <summary>
/// Gets the screen to show when no other screen is active.
/// </summary>
public virtual TScreen? DefaultScreen { get; }

IRoutableScreen? IRoutableHostScreen.InternalScreen => Screen;
IRoutableScreen? IRoutableHostScreen.InternalDefaultScreen => DefaultScreen;

void IRoutableHostScreen.InternalChangeScreen(IRoutableScreen? screen)
{
Expand Down
30 changes: 26 additions & 4 deletions src/Artemis.UI.Shared/Routing/Routable/RoutableScreenOfTParam.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ namespace Artemis.UI.Shared.Routing;
/// <typeparam name="TParam">The type of parameters the screen expects. It must have a parameterless constructor.</typeparam>
public abstract class RoutableScreen<TParam> : RoutableScreen, IRoutableScreen where TParam : new()
{
/// <summary>
/// Gets or sets the parameter source of the screen.
/// </summary>
protected ParameterSource ParameterSource { get; set; } = ParameterSource.Segment;

/// <summary>
/// Called while navigating to this screen.
/// </summary>
Expand All @@ -26,15 +31,16 @@ public virtual Task OnNavigating(TParam parameters, NavigationArguments args, Ca
{
return Task.CompletedTask;
}

async Task IRoutableScreen.InternalOnNavigating(NavigationArguments args, CancellationToken cancellationToken)
{
Func<object[], TParam> activator = GetParameterActivator();

if (args.SegmentParameters.Length != _parameterPropertyCount)
throw new ArtemisRoutingException($"Did not retrieve the required amount of parameters, expects {_parameterPropertyCount}, got {args.SegmentParameters.Length}.");
object[] routeParameters = ParameterSource == ParameterSource.Segment ? args.SegmentParameters : args.RouteParameters;
if (routeParameters.Length != _parameterPropertyCount)
throw new ArtemisRoutingException($"Did not retrieve the required amount of parameters, expects {_parameterPropertyCount}, got {routeParameters.Length}.");

TParam parameters = activator(args.SegmentParameters);
TParam parameters = activator(routeParameters);
await OnNavigating(args, cancellationToken);
await OnNavigating(parameters, args, cancellationToken);
}
Expand Down Expand Up @@ -97,4 +103,20 @@ private static Func<object[], TParam> GetParameterActivator()
}

#endregion
}

/// <summary>
/// Enum representing the source of parameters in the RoutableScreen class.
/// </summary>
public enum ParameterSource
{
/// <summary>
/// Represents the source where parameters are obtained from the segment of the route.
/// </summary>
Segment,

/// <summary>
/// Represents the source where parameters are obtained from the entire route.
/// </summary>
Route
}
11 changes: 11 additions & 0 deletions src/Artemis.UI.Shared/Routing/Route/RouteRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ public RouteRegistration(string path)
Route = new Route(path);
}

/// <summary>
/// Initializes a new instance of the <see cref="RouteRegistration{TViewModel}" /> class.
/// </summary>
/// <param name="path">The path of the route.</param>
/// <param name="children">The children of the route.</param>
public RouteRegistration(string path, List<IRouterRegistration> children)
{
Route = new Route(path);
Children = children;
}

/// <inheritdoc />
public override string ToString()
{
Expand Down
6 changes: 6 additions & 0 deletions src/Artemis.UI.Shared/Routing/Router/IRouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ public interface IRouter
/// </summary>
/// <returns>A task containing a boolean value which indicates whether there was a forward path to go back to.</returns>
Task<bool> GoForward();

/// <summary>
/// Asynchronously navigates upwards to the parent route.
/// </summary>
/// <returns></returns>
Task<bool> GoUp();

/// <summary>
/// Clears the navigation history.
Expand Down
7 changes: 3 additions & 4 deletions src/Artemis.UI.Shared/Routing/Router/Navigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,11 @@ private async Task NavigateResolution(RouteResolution resolution, NavigationArgu
// Navigate the child too
if (resolution.Child != null)
await NavigateResolution(resolution.Child, args, childScreen);
// Make sure there is no child
else if (childScreen.InternalScreen != null)
childScreen.InternalChangeScreen(null);
// Without a resolution, navigate to the default screen (which may be null)
else if (childScreen.InternalScreen != childScreen.InternalDefaultScreen)
childScreen.InternalChangeScreen(childScreen.InternalDefaultScreen);
}


Completed = true;
}

Expand Down
49 changes: 48 additions & 1 deletion src/Artemis.UI.Shared/Routing/Router/Router.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
using Artemis.Core;
Expand Down Expand Up @@ -72,7 +73,13 @@ private bool PathEquals(string path, RouterNavigationOptions options)
/// <inheritdoc />
public async Task Navigate(string path, RouterNavigationOptions? options = null)
{
path = path.ToLower().Trim(' ', '/', '\\');
if (path.StartsWith('/') && _currentRouteSubject.Value != null)
path = _currentRouteSubject.Value + path;
if (path.StartsWith("../") && _currentRouteSubject.Value != null)
path = NavigateUp(_currentRouteSubject.Value, path);
else
path = path.ToLower().Trim(' ', '/', '\\');

options ??= new RouterNavigationOptions();

// Routing takes place on the UI thread with processing heavy tasks offloaded by the router itself
Expand Down Expand Up @@ -161,6 +168,28 @@ public async Task<bool> GoForward()
return true;
}

/// <inheritdoc />
public async Task<bool> GoUp()
{
string? currentPath = _currentRouteSubject.Value;

// Keep removing segments until we find a parent route that resolves
while (currentPath != null && currentPath.Contains('/'))
{
string parentPath = currentPath[..currentPath.LastIndexOf('/')];
RouteResolution resolution = Resolve(parentPath);
if (resolution.Success)
{
await Navigate(parentPath, new RouterNavigationOptions {AddToHistory = false});
return true;
}

currentPath = parentPath;
}

return false;
}

/// <inheritdoc />
public void ClearHistory()
{
Expand Down Expand Up @@ -194,6 +223,24 @@ public void Dispose()

_logger.Debug("Router disposed, should that be? Stacktrace: \r\n{StackTrace}", Environment.StackTrace);
}


private string NavigateUp(string current, string path)
{
string[] pathParts = current.Split('/');
string[] navigateParts = path.Split('/');
int upCount = navigateParts.TakeWhile(part => part == "..").Count();

if (upCount >= pathParts.Length)
{
throw new InvalidOperationException("Cannot navigate up beyond the root");
}

IEnumerable<string> remainingCurrentPathParts = pathParts.Take(pathParts.Length - upCount);
IEnumerable<string> remainingNavigatePathParts = navigateParts.Skip(upCount);

return string.Join("/", remainingCurrentPathParts.Concat(remainingNavigatePathParts));
}

private void MainWindowServiceOnMainWindowOpened(object? sender, EventArgs e)
{
Expand Down
10 changes: 10 additions & 0 deletions src/Artemis.UI.Shared/Styles/Skeleton.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</Grid.RowDefinitions>
<Grid Margin="20" Grid.Column="0">
<StackPanel>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">TitleTextBlockStyle</TextBlock>
<TextBlock Classes="h1">This is heading 1</TextBlock>
<TextBlock Classes="h2">This is heading 2</TextBlock>
<TextBlock Classes="h3">This is heading 3</TextBlock>
Expand All @@ -22,6 +23,7 @@

<Grid Margin="20" Grid.Column="1">
<StackPanel>
<Border Width="400" Classes="skeleton-text title"></Border>
<Border Width="400" Classes="skeleton-text h1"></Border>
<Border Width="400" Classes="skeleton-text h2"></Border>
<Border Width="400" Classes="skeleton-text h3"></Border>
Expand All @@ -39,6 +41,7 @@
<Setter Property="Background" Value="#55ff0000"></Setter>
</Style>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">TitleTextBlockStyle</TextBlock>
<TextBlock Classes="h1">This is heading 1</TextBlock>
<TextBlock Classes="h2">This is heading 2</TextBlock>
<TextBlock Classes="h3">This is heading 3</TextBlock>
Expand All @@ -51,6 +54,7 @@

<Grid Margin="20" Grid.Column="0" Row="1">
<StackPanel Spacing="2">
<Border Width="400" Classes="skeleton-text title no-margin"></Border>
<Border Width="400" Classes="skeleton-text h1 no-margin"></Border>
<Border Width="400" Classes="skeleton-text h2 no-margin"></Border>
<Border Width="400" Classes="skeleton-text h3 no-margin"></Border>
Expand All @@ -68,6 +72,7 @@
<Setter Property="Background" Value="#55ff0000"></Setter>
</Style>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">TitleTextBlockStyle</TextBlock>
<TextBlock Classes="h1 no-margin">This is heading 1</TextBlock>
<TextBlock Classes="h2 no-margin">This is heading 2</TextBlock>
<TextBlock Classes="h3 no-margin">This is heading 3</TextBlock>
Expand Down Expand Up @@ -125,6 +130,11 @@
</Style.Animations>
</Style>

<Style Selector="Border.skeleton-text.title">
<Setter Property="Height" Value="28" />
<Setter Property="Margin" Value="0 5 0 5" />
<Setter Property="CornerRadius" Value="8" />
</Style>
<Style Selector="Border.skeleton-text.h1">
<Setter Property="Height" Value="65" />
<Setter Property="Margin" Value="0 10 0 20" />
Expand Down
22 changes: 22 additions & 0 deletions src/Artemis.UI/Artemis.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,27 @@
<DependentUpon>DeviceSelectionDialogView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Screens\Workshop\Layout\LayoutListView.axaml.cs">
<DependentUpon>LayoutListView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Screens\Workshop\Plugins\PluginListView.axaml.cs">
<DependentUpon>LayoutListView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Screens\Workshop\Profile\ProfileListView.axaml.cs">
<DependentUpon>LayoutListView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Screens\Workshop\EntryReleases\EntryReleasesView.axaml.cs">
<DependentUpon>EntryReleasesView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>

<ItemGroup>
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\PluginListView.axaml" />
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\ProfileListView.axaml" />
<UpToDateCheckInput Remove="Screens\Workshop\Plugins\Dialogs\PluginDialogView.axaml" />
</ItemGroup>
</Project>
51 changes: 51 additions & 0 deletions src/Artemis.UI/Controls/SplitMarkdownEditor.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<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:avaloniaEdit="https://github.com/avaloniaui/avaloniaedit"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
xmlns:fa="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Controls.SplitMarkdownEditor">
<Grid RowDefinitions="Auto,*">
<Grid Row="0" ColumnDefinitions="Auto,*">
<Label Grid.Column="0" Name="DescriptionEditorLabel" Target="DescriptionEditor" Margin="0 28 0 0" />
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<CheckBox Name="SynchronizedScrolling" IsChecked="True" VerticalAlignment="Bottom">Synchronized scrolling</CheckBox>
<fa:HyperlinkButton
Margin="0 0 0 -20"
Content="Markdown supported"
NavigateUri="https://wiki.artemis-rgb.com/guides/user/markdown?mtm_campaign=artemis&amp;mtm_kwd=markdown-editor"
HorizontalAlignment="Right" />
</StackPanel>
</Grid>

<Grid Grid.Row="1" Grid.Column="0" ColumnDefinitions="*,Auto,*">
<Border Grid.Column="0" BorderThickness="1"
BorderBrush="{DynamicResource TextControlBorderBrush}"
CornerRadius="{DynamicResource ControlCornerRadius}"
Background="{DynamicResource TextControlBackground}"
Padding="{DynamicResource TextControlThemePadding}">
<avaloniaEdit:TextEditor
FontFamily="{StaticResource RobotoMono}"
FontSize="13"
Name="DescriptionEditor"
TextChanged="DescriptionEditor_OnTextChanged"
WordWrap="True" />
</Border>

<GridSplitter Grid.Column="1" Margin="5 0"></GridSplitter>
<Border Grid.Column="2" Classes="card-condensed">
<mdxaml:MarkdownScrollViewer Margin="5 0"
Name="DescriptionPreview"
Markdown="{CompiledBinding Document.Text, Mode=OneWay, ElementName=DescriptionEditor}"
MarkdownStyleName="FluentAvalonia"
SaveScrollValueWhenContentUpdated="True">
<mdxaml:MarkdownScrollViewer.Styles>
<StyleInclude Source="/Styles/Markdown.axaml" />
</mdxaml:MarkdownScrollViewer.Styles>
</mdxaml:MarkdownScrollViewer>
</Border>
</Grid>
</Grid>
</UserControl>
Loading