diff --git a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml index 3bb950a0f..b228ebe2f 100644 --- a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml +++ b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml @@ -32,7 +32,7 @@ diff --git a/src/Artemis.UI.Shared/Styles/Button.axaml b/src/Artemis.UI.Shared/Styles/Button.axaml index dbecb197c..12863d150 100644 --- a/src/Artemis.UI.Shared/Styles/Button.axaml +++ b/src/Artemis.UI.Shared/Styles/Button.axaml @@ -43,6 +43,10 @@ + + @@ -104,4 +108,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml index 662a1109f..d2757ca40 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml @@ -66,7 +66,7 @@ @@ -81,7 +81,7 @@ IsVisible="{CompiledBinding IsEventPicker, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dataModelPicker:DataModelPicker}}}"/> - + @@ -90,7 +90,7 @@ diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index fd7f60a06..c1b71c6f2 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -61,9 +61,13 @@ LayoutListView.axaml Code - + SubmissionsDetailView.axaml Code + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Assets/Fonts/RobotoMono-Bold.ttf b/src/Artemis.UI/Assets/Fonts/RobotoMono-Bold.ttf new file mode 100644 index 000000000..8eff26c1e Binary files /dev/null and b/src/Artemis.UI/Assets/Fonts/RobotoMono-Bold.ttf differ diff --git a/src/Artemis.UI/Assets/Fonts/RobotoMono-BoldItalic.ttf b/src/Artemis.UI/Assets/Fonts/RobotoMono-BoldItalic.ttf new file mode 100644 index 000000000..99299640b Binary files /dev/null and b/src/Artemis.UI/Assets/Fonts/RobotoMono-BoldItalic.ttf differ diff --git a/src/Artemis.UI/Assets/Fonts/RobotoMono-Italic.ttf b/src/Artemis.UI/Assets/Fonts/RobotoMono-Italic.ttf new file mode 100644 index 000000000..cf2b5b39c Binary files /dev/null and b/src/Artemis.UI/Assets/Fonts/RobotoMono-Italic.ttf differ diff --git a/src/Artemis.UI/Assets/Fonts/RobotoMono-Regular.ttf b/src/Artemis.UI/Assets/Fonts/RobotoMono-Regular.ttf new file mode 100644 index 000000000..d9371a1bd Binary files /dev/null and b/src/Artemis.UI/Assets/Fonts/RobotoMono-Regular.ttf differ diff --git a/src/Artemis.UI/Assets/Fonts/RobotoMono-SemiBold.ttf b/src/Artemis.UI/Assets/Fonts/RobotoMono-SemiBold.ttf new file mode 100644 index 000000000..06aea97f3 Binary files /dev/null and b/src/Artemis.UI/Assets/Fonts/RobotoMono-SemiBold.ttf differ diff --git a/src/Artemis.UI/Assets/Fonts/RobotoMono-SemiBoldItalic.ttf b/src/Artemis.UI/Assets/Fonts/RobotoMono-SemiBoldItalic.ttf new file mode 100644 index 000000000..72b0fc6d9 Binary files /dev/null and b/src/Artemis.UI/Assets/Fonts/RobotoMono-SemiBoldItalic.ttf differ diff --git a/src/Artemis.UI/MainWindow.axaml b/src/Artemis.UI/MainWindow.axaml index 307ad0b56..70f2b258b 100644 --- a/src/Artemis.UI/MainWindow.axaml +++ b/src/Artemis.UI/MainWindow.axaml @@ -12,6 +12,9 @@ MinWidth="600" MinHeight="400" PointerReleased="InputElement_OnPointerReleased"> + + + - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - - Icon required - - - - - + + + Icon required + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + At least one category is required + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - At least one category is required - - - + + Synchronized scrolling + + - - - - - - - - Markdown supported, a better editor planned - - - - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml.cs index e8155b0de..b3289a3bf 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml.cs @@ -1,34 +1,100 @@ +using System.Linq; +using Artemis.UI.Shared.Extensions; using Avalonia; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Immutable; using Avalonia.ReactiveUI; using AvaloniaEdit.TextMate; +using ReactiveUI; using TextMateSharp.Grammars; namespace Artemis.UI.Screens.Workshop.Entries; public partial class EntrySpecificationsView : ReactiveUserControl { + private ScrollViewer? _editorScrollViewer; + private ScrollViewer? _previewScrollViewer; + private bool _updating; + public EntrySpecificationsView() { InitializeComponent(); + DescriptionEditor.Options.AllowScrollBelowDocument = false; RegistryOptions options = new(ThemeName.Dark); TextMate.Installation? install = DescriptionEditor.InstallTextMate(options); install.SetGrammar(options.GetScopeByExtension(".md")); + + this.WhenActivated(_ => SetupScrollSync()); } - #region Overrides of Visual - - /// protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { if (this.TryFindResource("SystemAccentColorLight3", out object? resource) && resource is Color color) DescriptionEditor.TextArea.TextView.LinkTextForegroundBrush = new ImmutableSolidColorBrush(color); + base.OnAttachedToVisualTree(e); } - #endregion + private void SetupScrollSync() + { + if (_editorScrollViewer != null) + _editorScrollViewer.PropertyChanged -= EditorScrollViewerOnPropertyChanged; + if (_previewScrollViewer != null) + _previewScrollViewer.PropertyChanged -= PreviewScrollViewerOnPropertyChanged; + + _editorScrollViewer = DescriptionEditor.GetVisualChildrenOfType().FirstOrDefault(); + _previewScrollViewer = DescriptionPreview.GetVisualChildrenOfType().FirstOrDefault(); + + if (_editorScrollViewer != null) + _editorScrollViewer.PropertyChanged += EditorScrollViewerOnPropertyChanged; + if (_previewScrollViewer != null) + _previewScrollViewer.PropertyChanged += PreviewScrollViewerOnPropertyChanged; + } + + private void EditorScrollViewerOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property.Name != nameof(ScrollViewer.Offset) || _updating || SynchronizedScrolling.IsChecked != true) + return; + + try + { + _updating = true; + SynchronizeScrollViewers(_editorScrollViewer, _previewScrollViewer); + } + finally + { + _updating = false; + } + } + + private void PreviewScrollViewerOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property.Name != nameof(ScrollViewer.Offset) || _updating || SynchronizedScrolling.IsChecked != true) + return; + + try + { + _updating = true; + SynchronizeScrollViewers(_previewScrollViewer, _editorScrollViewer); + } + finally + { + _updating = false; + } + } + + private void SynchronizeScrollViewers(ScrollViewer? source, ScrollViewer? target) + { + if (source == null || target == null) + return; + + double sourceScrollableHeight = source.Extent.Height - source.Viewport.Height; + double targetScrollableHeight = target.Extent.Height - target.Viewport.Height; + + if (sourceScrollableHeight != 0) + target.Offset = new Vector(target.Offset.X, targetScrollableHeight * (source.Offset.Y / sourceScrollableHeight)); + } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsViewModel.cs index a4b3f439c..af20fa4b4 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsViewModel.cs @@ -5,15 +5,12 @@ using System.Linq; using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; -using System.Threading; using System.Threading.Tasks; using Artemis.UI.Extensions; using Artemis.UI.Screens.Workshop.Categories; -using Artemis.UI.Screens.Workshop.Entries.Windows; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Artemis.WebClient.Workshop; -using Avalonia.Controls; using AvaloniaEdit.Document; using DynamicData; using DynamicData.Aggregation; @@ -35,16 +32,13 @@ public class EntrySpecificationsViewModel : ValidatableViewModelBase private string _name = string.Empty; private string _summary = string.Empty; private Bitmap? _iconBitmap; - private Window? _previewWindow; private TextDocument? _markdownDocument; public EntrySpecificationsViewModel(IWorkshopClient workshopClient, IWindowService windowService) { _windowService = windowService; SelectIcon = ReactiveCommand.CreateFromTask(ExecuteSelectIcon); - OpenMarkdownPreview = ReactiveCommand.Create(ExecuteOpenMarkdownPreview); - // this.WhenAnyValue(vm => vm.Description).Subscribe(d => MarkdownDocument.Text = d); this.WhenActivated(d => { // Load categories @@ -56,7 +50,6 @@ public class EntrySpecificationsViewModel : ValidatableViewModelBase MarkdownDocument.TextChanged += MarkdownDocumentOnTextChanged; Disposable.Create(() => { - _previewWindow?.Close(); MarkdownDocument.TextChanged -= MarkdownDocumentOnTextChanged; MarkdownDocument = null; ClearIcon(); @@ -66,11 +59,10 @@ public class EntrySpecificationsViewModel : ValidatableViewModelBase private void MarkdownDocumentOnTextChanged(object? sender, EventArgs e) { - Description = MarkdownDocument.Text; + Description = MarkdownDocument?.Text ?? string.Empty; } public ReactiveCommand SelectIcon { get; } - public ReactiveCommand OpenMarkdownPreview { get; } public ObservableCollection Categories { get; } = new(); public ObservableCollection Tags { get; } = new(); @@ -139,25 +131,6 @@ public class EntrySpecificationsViewModel : ValidatableViewModelBase IconBitmap = BitmapExtensions.LoadAndResize(result[0], 128); } - private void ExecuteOpenMarkdownPreview() - { - if (_previewWindow != null) - { - _previewWindow.Activate(); - return; - } - - _previewWindow = _windowService.ShowWindow(out MarkdownPreviewViewModel _, this.WhenAnyValue(vm => vm.Description)); - _previewWindow.Closed += PreviewWindowOnClosed; - } - - private void PreviewWindowOnClosed(object? sender, EventArgs e) - { - if (_previewWindow != null) - _previewWindow.Closed -= PreviewWindowOnClosed; - _previewWindow = null; - } - private void ClearIcon() { IconBitmap?.Dispose(); diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewView.axaml deleted file mode 100644 index 8898bef0a..000000000 --- a/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewView.axaml +++ /dev/null @@ -1,43 +0,0 @@ - - - - Markdown Previewer - - In this window you can preview the Markdown you're writing in the main window of the application. - - The preview updates realtime, so it might be a good idea to keep this window visible while you're typing. - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewView.axaml.cs deleted file mode 100644 index ec5b62868..000000000 --- a/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewView.axaml.cs +++ /dev/null @@ -1,12 +0,0 @@ - -using Artemis.UI.Shared; - -namespace Artemis.UI.Screens.Workshop.Entries.Windows; - -public partial class MarkdownPreviewView : ReactiveAppWindow -{ - public MarkdownPreviewView() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewViewModel.cs deleted file mode 100644 index 4e8680d0e..000000000 --- a/src/Artemis.UI/Screens/Workshop/Entries/Windows/MarkdownPreviewViewModel.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Artemis.UI.Shared; - -namespace Artemis.UI.Screens.Workshop.Entries.Windows; - -public class MarkdownPreviewViewModel : ActivatableViewModelBase -{ - public event EventHandler? Closed; - - public IObservable Markdown { get; } - - public MarkdownPreviewViewModel(IObservable markdown) - { - Markdown = markdown; - } - - protected virtual void OnClosed() - { - Closed?.Invoke(this, EventArgs.Empty); - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailView.axaml b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailView.axaml new file mode 100644 index 000000000..4967d463b --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailView.axaml @@ -0,0 +1,50 @@ + + + + + + + + + Management + + + + + + downloads + + + + + Created + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailView.axaml.cs new file mode 100644 index 000000000..729f02a2b --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailView.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.ReactiveUI; + +namespace Artemis.UI.Screens.Workshop.Library; + +public partial class SubmissionDetailView : ReactiveUserControl +{ + public SubmissionDetailView() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs new file mode 100644 index 000000000..869080c80 --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Reactive; +using System.Threading; +using System.Threading.Tasks; +using Artemis.UI.Screens.Workshop.Entries; +using Artemis.UI.Screens.Workshop.Parameters; +using Artemis.UI.Shared.Routing; +using Artemis.UI.Shared.Services; +using Artemis.WebClient.Workshop; +using Avalonia.Media.Imaging; +using ReactiveUI; +using StrawberryShake; + +namespace Artemis.UI.Screens.Workshop.Library; + +public class SubmissionDetailViewModel : RoutableScreen +{ + private readonly IWorkshopClient _client; + private readonly IHttpClientFactory _httpClientFactory; + private readonly Func _getEntrySpecificationsViewModel; + private readonly IWindowService _windowService; + private readonly IRouter _router; + private IGetSubmittedEntryById_Entry? _entry; + private EntrySpecificationsViewModel? _entrySpecificationsViewModel; + + public SubmissionDetailViewModel(IWorkshopClient client, + IHttpClientFactory httpClientFactory, + Func entrySpecificationsViewModel, + IWindowService windowService, + IRouter router) + { + _client = client; + _httpClientFactory = httpClientFactory; + _getEntrySpecificationsViewModel = entrySpecificationsViewModel; + _windowService = windowService; + _router = router; + + CreateRelease = ReactiveCommand.CreateFromTask(ExecuteCreateRelease); + DeleteSubmission = ReactiveCommand.CreateFromTask(ExecuteDeleteSubmission); + } + + public ReactiveCommand CreateRelease { get; } + public ReactiveCommand DeleteSubmission { get; } + + public EntrySpecificationsViewModel? EntrySpecificationsViewModel + { + get => _entrySpecificationsViewModel; + set => RaiseAndSetIfChanged(ref _entrySpecificationsViewModel, value); + } + + public IGetSubmittedEntryById_Entry? Entry + { + get => _entry; + set => RaiseAndSetIfChanged(ref _entry, value); + } + + public override async Task OnNavigating(WorkshopDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken) + { + IOperationResult result = await _client.GetSubmittedEntryById.ExecuteAsync(parameters.EntryId, cancellationToken); + if (result.IsErrorResult()) + return; + + Entry = result.Data?.Entry; + await ApplyFromEntry(cancellationToken); + } + + private async Task ApplyFromEntry(CancellationToken cancellationToken) + { + if (Entry == null) + return; + + EntrySpecificationsViewModel viewModel = _getEntrySpecificationsViewModel(); + + viewModel.IconBitmap = await GetEntryIcon(cancellationToken); + viewModel.Name = Entry.Name; + viewModel.Summary = Entry.Summary; + viewModel.Description = Entry.Description; + viewModel.PreselectedCategories = Entry.Categories.Select(c => c.Id).ToList(); + + viewModel.Tags.Clear(); + foreach (string tag in Entry.Tags.Select(c => c.Name)) + viewModel.Tags.Add(tag); + + EntrySpecificationsViewModel = viewModel; + } + + private async Task GetEntryIcon(CancellationToken cancellationToken) + { + if (Entry == null) + return null; + + HttpClient client = _httpClientFactory.CreateClient(WorkshopConstants.WORKSHOP_CLIENT_NAME); + try + { + HttpResponseMessage response = await client.GetAsync($"entries/{Entry.Id}/icon", cancellationToken); + response.EnsureSuccessStatusCode(); + Stream data = await response.Content.ReadAsStreamAsync(cancellationToken); + return new Bitmap(data); + } + catch (HttpRequestException) + { + // ignored + return null; + } + } + + private Task ExecuteCreateRelease(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + private async Task ExecuteDeleteSubmission(CancellationToken cancellationToken) + { + if (Entry == null) + return; + + bool confirmed = await _windowService.ShowConfirmContentDialog( + "Delete submission?", + "You cannot undo this by yourself.\r\n" + + "Users that have already downloaded your submission will keep it."); + if (!confirmed) + return; + + IOperationResult result = await _client.RemoveEntry.ExecuteAsync(Entry.Id, cancellationToken); + result.EnsureNoErrors(); + await _router.Navigate("workshop/library/submissions"); + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailView.axaml b/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailView.axaml deleted file mode 100644 index ca36904b6..000000000 --- a/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailView.axaml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailView.axaml.cs deleted file mode 100644 index bca7ef914..000000000 --- a/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailView.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.ReactiveUI; - -namespace Artemis.UI.Screens.Workshop.Library; - -public partial class SubmissionsDetailView : ReactiveUserControl -{ - public SubmissionsDetailView() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailViewModel.cs deleted file mode 100644 index 283a490e7..000000000 --- a/src/Artemis.UI/Screens/Workshop/Library/SubmissionsDetailViewModel.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using Artemis.UI.Screens.Workshop.Entries; -using Artemis.UI.Screens.Workshop.Parameters; -using Artemis.UI.Shared.Routing; - -namespace Artemis.UI.Screens.Workshop.Library; - -public class SubmissionsDetailViewModel : RoutableScreen -{ - public EntrySpecificationsViewModel EntrySpecificationsViewModel { get; } - - public SubmissionsDetailViewModel(EntrySpecificationsViewModel entrySpecificationsViewModel) - { - EntrySpecificationsViewModel = entrySpecificationsViewModel; - } - - public override Task OnNavigating(WorkshopDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken) - { - Console.WriteLine(parameters.EntryId); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml b/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml index 0c9eff517..af8f455a4 100644 --- a/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml +++ b/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml @@ -11,7 +11,7 @@ diff --git a/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryViewModel.cs index d9f1a6c99..56abc8ffd 100644 --- a/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryViewModel.cs @@ -15,7 +15,7 @@ public class WorkshopLibraryViewModel : RoutableHostScreen { private readonly IRouter _router; private RouteViewModel? _selectedTab; - private ObservableAsPropertyHelper? _canGoBack; + private ObservableAsPropertyHelper? _viewingDetails; /// public WorkshopLibraryViewModel(IRouter router) @@ -30,8 +30,7 @@ public class WorkshopLibraryViewModel : RoutableHostScreen this.WhenActivated(d => { - // Show back button on details page - _canGoBack = _router.CurrentPath.Select(p => p != null && p.StartsWith("workshop/library/submissions/")).ToProperty(this, vm => vm.CanGoBack).DisposeWith(d); + _viewingDetails = _router.CurrentPath.Select(p => p != null && p.StartsWith("workshop/library/submissions/")).ToProperty(this, vm => vm.ViewingDetails).DisposeWith(d); // Navigate on tab change this.WhenAnyValue(vm => vm.SelectedTab) .WhereNotNull() @@ -40,7 +39,7 @@ public class WorkshopLibraryViewModel : RoutableHostScreen }); } - public bool CanGoBack => _canGoBack?.Value ?? false; + public bool ViewingDetails => _viewingDetails?.Value ?? false; public ObservableCollection Tabs { get; } public RouteViewModel? SelectedTab @@ -58,6 +57,9 @@ public class WorkshopLibraryViewModel : RoutableHostScreen public void GoBack() { - _router.GoBack(); + if (ViewingDetails) + _router.GoBack(); + else + _router.Navigate("workshop"); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml index 5573ca5c1..18e53f90a 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml @@ -21,8 +21,6 @@ - - - + \ No newline at end of file diff --git a/src/Artemis.UI/Styles/Artemis.axaml b/src/Artemis.UI/Styles/Artemis.axaml index a4ac040f9..55109b2d3 100644 --- a/src/Artemis.UI/Styles/Artemis.axaml +++ b/src/Artemis.UI/Styles/Artemis.axaml @@ -15,7 +15,7 @@ @@ -26,6 +26,7 @@ + avares://Artemis.UI/Assets/Fonts#Roboto Mono diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml index 8ddaf5f77..014b2bdb5 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml @@ -25,7 +25,7 @@ Text="{CompiledBinding Converter={StaticResource SKColorToStringConverter}}" VerticalAlignment="Center" HorizontalAlignment="Stretch" - FontFamily="Consolas"/> + FontFamily="{StaticResource RobotoMono}"/> - + diff --git a/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj b/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj index d2838936b..32d841d41 100644 --- a/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj +++ b/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj @@ -38,5 +38,11 @@ MSBuild:GenerateGraphQLCode + + MSBuild:GenerateGraphQLCode + + + MSBuild:GenerateGraphQLCode + diff --git a/src/Artemis.WebClient.Workshop/Queries/GetSubmittedEntryById.graphql b/src/Artemis.WebClient.Workshop/Queries/GetSubmittedEntryById.graphql new file mode 100644 index 000000000..92da65c60 --- /dev/null +++ b/src/Artemis.WebClient.Workshop/Queries/GetSubmittedEntryById.graphql @@ -0,0 +1,17 @@ +query GetSubmittedEntryById($id: UUID!) { + entry(id: $id) { + id + name + summary + entryType + downloads + createdAt + description + categories { + id + } + tags { + name + } + } +} \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/Queries/RemoveEntry.graphql b/src/Artemis.WebClient.Workshop/Queries/RemoveEntry.graphql new file mode 100644 index 000000000..4f46da2c5 --- /dev/null +++ b/src/Artemis.WebClient.Workshop/Queries/RemoveEntry.graphql @@ -0,0 +1,5 @@ +mutation RemoveEntry ($id: UUID!) { + removeEntry(id: $id) { + id + } +} diff --git a/src/Artemis.WebClient.Workshop/schema.graphql b/src/Artemis.WebClient.Workshop/schema.graphql index bed72a4a2..52b3ebb56 100644 --- a/src/Artemis.WebClient.Workshop/schema.graphql +++ b/src/Artemis.WebClient.Workshop/schema.graphql @@ -55,6 +55,7 @@ type Image { type Mutation { addEntry(input: CreateEntryInput!): Entry + removeEntry(id: UUID!): Entry updateEntry(input: UpdateEntryInput!): Entry }