mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 21:38:38 +00:00
Workshop - Revert voting changes, was fun to try but not useful enough
This commit is contained in:
parent
1e8c68bbeb
commit
ec5fbba87c
@ -1,65 +0,0 @@
|
|||||||
<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:entries="clr-namespace:Artemis.UI.Screens.Workshop.Entries"
|
|
||||||
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.Workshop.Entries.EntryVoteView"
|
|
||||||
x:DataType="entries:EntryVoteViewModel">
|
|
||||||
<UserControl.Styles>
|
|
||||||
<Styles>
|
|
||||||
<Style Selector="Button.vote-button avalonia|MaterialIcon">
|
|
||||||
<Setter Property="Transitions">
|
|
||||||
<Transitions>
|
|
||||||
<BrushTransition Property="Foreground" Duration="0:0:0.2" Easing="CubicEaseOut" />
|
|
||||||
</Transitions>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
<Style Selector="Button.vote-button.upvote:pointerover avalonia|MaterialIcon">
|
|
||||||
<Setter Property="Foreground" Value="#F57634"></Setter>
|
|
||||||
</Style>
|
|
||||||
<Style Selector="Button.vote-button.downvote:pointerover avalonia|MaterialIcon">
|
|
||||||
<Setter Property="Foreground" Value="#7193FF"></Setter>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style Selector="TextBlock.upvoted">
|
|
||||||
<Setter Property="Foreground" Value="#F57634"></Setter>
|
|
||||||
</Style>
|
|
||||||
<Style Selector="TextBlock.downvoted">
|
|
||||||
<Setter Property="Foreground" Value="#7193FF"></Setter>
|
|
||||||
</Style>
|
|
||||||
</Styles>
|
|
||||||
</UserControl.Styles>
|
|
||||||
|
|
||||||
<!-- Voting -->
|
|
||||||
<StackPanel Spacing="4" VerticalAlignment="Center">
|
|
||||||
<Button IsEnabled="{CompiledBinding IsLoggedIn^}"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Theme="{StaticResource TransparentButton}"
|
|
||||||
Classes="vote-button upvote"
|
|
||||||
Command="{CompiledBinding CastVote}"
|
|
||||||
CommandParameter="{x:True}">
|
|
||||||
<Panel>
|
|
||||||
<avalonia:MaterialIcon Kind="ArrowUp" IsVisible="{CompiledBinding !Upvoted}" />
|
|
||||||
<avalonia:MaterialIcon Kind="ArrowUpThick" IsVisible="{CompiledBinding Upvoted}" Foreground="#F57634" />
|
|
||||||
</Panel>
|
|
||||||
</Button>
|
|
||||||
<TextBlock Text="{CompiledBinding Score, FallbackValue=0}"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
TextAlignment="Center"
|
|
||||||
Classes.upvoted="{CompiledBinding Upvoted}"
|
|
||||||
Classes.downvoted="{CompiledBinding Downvoted}" />
|
|
||||||
<Button IsEnabled="{CompiledBinding IsLoggedIn^}"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Theme="{StaticResource TransparentButton}"
|
|
||||||
Classes="vote-button downvote"
|
|
||||||
Command="{CompiledBinding CastVote}"
|
|
||||||
CommandParameter="{x:False}">
|
|
||||||
<Panel>
|
|
||||||
<avalonia:MaterialIcon Kind="ArrowDown" IsVisible="{CompiledBinding !Downvoted}" />
|
|
||||||
<avalonia:MaterialIcon Kind="ArrowDownThick" IsVisible="{CompiledBinding Downvoted}" Foreground="#7193FF" />
|
|
||||||
</Panel>
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</UserControl>
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using Avalonia.ReactiveUI;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Workshop.Entries;
|
|
||||||
|
|
||||||
public partial class EntryVoteView : ReactiveUserControl<EntryVoteViewModel>
|
|
||||||
{
|
|
||||||
public EntryVoteView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reactive.Disposables;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Artemis.UI.Shared;
|
|
||||||
using Artemis.UI.Shared.Services;
|
|
||||||
using Artemis.UI.Shared.Services.Builders;
|
|
||||||
using Artemis.WebClient.Workshop;
|
|
||||||
using Artemis.WebClient.Workshop.Services;
|
|
||||||
using PropertyChanged.SourceGenerator;
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Workshop.Entries;
|
|
||||||
|
|
||||||
public partial class EntryVoteViewModel : ActivatableViewModelBase
|
|
||||||
{
|
|
||||||
private readonly IEntrySummary _entry;
|
|
||||||
private readonly INotificationService _notificationService;
|
|
||||||
private readonly IVoteClient _voteClient;
|
|
||||||
private bool _voting;
|
|
||||||
|
|
||||||
[Notify] private int _score;
|
|
||||||
[Notify] private bool _upvoted;
|
|
||||||
[Notify] private bool _downvoted;
|
|
||||||
|
|
||||||
public EntryVoteViewModel(IEntrySummary entry, IAuthenticationService authenticationService, INotificationService notificationService, IVoteClient voteClient)
|
|
||||||
{
|
|
||||||
_entry = entry;
|
|
||||||
_notificationService = notificationService;
|
|
||||||
_voteClient = voteClient;
|
|
||||||
|
|
||||||
IsLoggedIn = authenticationService.IsLoggedIn;
|
|
||||||
Score = entry.UpvoteCount - entry.DownvoteCount;
|
|
||||||
this.WhenActivated(d => IsLoggedIn.Subscribe(l => _ = GetVoteStatus(l)).DisposeWith(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
public IObservable<bool> IsLoggedIn { get; }
|
|
||||||
|
|
||||||
public async Task CastVote(bool upvote)
|
|
||||||
{
|
|
||||||
// Could use a ReactiveCommand to achieve the same thing but that disables the button
|
|
||||||
// while executing which grays it out for a fraction of a second and looks bad
|
|
||||||
if (_voting)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_voting = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IVoteCount? result;
|
|
||||||
// If the vote was removed, reset the upvote/downvote state
|
|
||||||
if ((Upvoted && upvote) || (Downvoted && !upvote))
|
|
||||||
{
|
|
||||||
result = await _voteClient.ClearVote(_entry.Id);
|
|
||||||
Upvoted = false;
|
|
||||||
Downvoted = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = await _voteClient.CastVote(_entry.Id, upvote);
|
|
||||||
Upvoted = upvote;
|
|
||||||
Downvoted = !upvote;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
Score = result.UpvoteCount - result.DownvoteCount;
|
|
||||||
else
|
|
||||||
_notificationService.CreateNotification().WithTitle("Failed to cast vote").WithMessage("Please try again later.").WithSeverity(NotificationSeverity.Error).Show();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_voting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task GetVoteStatus(bool isLoggedIn)
|
|
||||||
{
|
|
||||||
if (!isLoggedIn)
|
|
||||||
{
|
|
||||||
Upvoted = false;
|
|
||||||
Downvoted = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool? vote = await _voteClient.GetVote(_entry.Id);
|
|
||||||
if (vote != null)
|
|
||||||
{
|
|
||||||
Upvoted = vote.Value;
|
|
||||||
Downvoted = !vote.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -21,7 +21,6 @@
|
|||||||
<ComboBoxItem>Recently updated</ComboBoxItem>
|
<ComboBoxItem>Recently updated</ComboBoxItem>
|
||||||
<ComboBoxItem>Recently added</ComboBoxItem>
|
<ComboBoxItem>Recently added</ComboBoxItem>
|
||||||
<ComboBoxItem>Download count</ComboBoxItem>
|
<ComboBoxItem>Download count</ComboBoxItem>
|
||||||
<ComboBoxItem>Score</ComboBoxItem>
|
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock Grid.Column="3" VerticalAlignment="Center" Margin="5 0 0 0" MinWidth="75" TextAlignment="Right">
|
<TextBlock Grid.Column="3" VerticalAlignment="Center" Margin="5 0 0 0" MinWidth="75" TextAlignment="Right">
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||||
xmlns:entries1="clr-namespace:Artemis.UI.Screens.Workshop.Entries"
|
|
||||||
xmlns:il="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
xmlns:il="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||||
xmlns:list="clr-namespace:Artemis.UI.Screens.Workshop.Entries.List"
|
xmlns:list="clr-namespace:Artemis.UI.Screens.Workshop.Entries.List"
|
||||||
@ -21,12 +20,9 @@
|
|||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
Command="{CompiledBinding NavigateToEntry}"
|
Command="{CompiledBinding NavigateToEntry}"
|
||||||
IsVisible="{CompiledBinding Entry, Converter={x:Static ObjectConverters.IsNotNull}}">
|
IsVisible="{CompiledBinding Entry, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||||
<Grid ColumnDefinitions="Auto, Auto,*,Auto" RowDefinitions="*, Auto">
|
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="*, Auto">
|
||||||
<!-- Score -->
|
|
||||||
<ContentControl Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Width="40" Margin="0 0 10 0" Content="{CompiledBinding VoteViewModel}"/>
|
|
||||||
|
|
||||||
<!-- Icon -->
|
<!-- Icon -->
|
||||||
<Border Grid.Column="1"
|
<Border Grid.Column="0"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
CornerRadius="6"
|
CornerRadius="6"
|
||||||
@ -39,7 +35,7 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<Grid Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto">
|
<Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto">
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
<TextBlock Margin="0 0 0 5" TextTrimming="CharacterEllipsis">
|
<TextBlock Margin="0 0 0 5" TextTrimming="CharacterEllipsis">
|
||||||
<Run Classes="h5" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" />
|
<Run Classes="h5" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" />
|
||||||
@ -82,7 +78,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Info -->
|
<!-- Info -->
|
||||||
<StackPanel Grid.Column="3" Grid.Row="0" Margin="0 0 4 0" HorizontalAlignment="Right">
|
<StackPanel Grid.Column="2" Grid.Row="0" Margin="0 0 4 0" HorizontalAlignment="Right">
|
||||||
<TextBlock TextAlignment="Right" Text="{CompiledBinding Entry.CreatedAt, FallbackValue=01-01-1337, Converter={StaticResource DateTimeConverter}}" />
|
<TextBlock TextAlignment="Right" Text="{CompiledBinding Entry.CreatedAt, FallbackValue=01-01-1337, Converter={StaticResource DateTimeConverter}}" />
|
||||||
<TextBlock TextAlignment="Right">
|
<TextBlock TextAlignment="Right">
|
||||||
<avalonia:MaterialIcon Kind="Downloads" />
|
<avalonia:MaterialIcon Kind="Downloads" />
|
||||||
@ -92,7 +88,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Install state -->
|
<!-- Install state -->
|
||||||
<StackPanel Grid.Column="3" Grid.Row="1" Margin="0 0 4 0" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsVisible="{CompiledBinding IsInstalled}">
|
<StackPanel Grid.Column="2" Grid.Row="1" Margin="0 0 4 0" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsVisible="{CompiledBinding IsInstalled}">
|
||||||
<TextBlock TextAlignment="Right" IsVisible="{CompiledBinding !UpdateAvailable}">
|
<TextBlock TextAlignment="Right" IsVisible="{CompiledBinding !UpdateAvailable}">
|
||||||
<avalonia:MaterialIcon Kind="CheckCircle" Foreground="{DynamicResource SystemAccentColorLight1}" Width="20" Height="20" />
|
<avalonia:MaterialIcon Kind="CheckCircle" Foreground="{DynamicResource SystemAccentColorLight1}" Width="20" Height="20" />
|
||||||
<Run>installed</Run>
|
<Run>installed</Run>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Reactive;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
@ -17,12 +18,12 @@ public partial class EntryListItemViewModel : ActivatableViewModelBase
|
|||||||
[Notify] private bool _isInstalled;
|
[Notify] private bool _isInstalled;
|
||||||
[Notify] private bool _updateAvailable;
|
[Notify] private bool _updateAvailable;
|
||||||
|
|
||||||
public EntryListItemViewModel(IEntrySummary entry, IRouter router, IWorkshopService workshopService, Func<IEntrySummary, EntryVoteViewModel> getEntryVoteViewModel)
|
public EntryListItemViewModel(IEntrySummary entry, IRouter router, IWorkshopService workshopService)
|
||||||
{
|
{
|
||||||
_router = router;
|
_router = router;
|
||||||
|
|
||||||
Entry = entry;
|
Entry = entry;
|
||||||
VoteViewModel = getEntryVoteViewModel(entry);
|
NavigateToEntry = ReactiveCommand.CreateFromTask(ExecuteNavigateToEntry);
|
||||||
|
|
||||||
this.WhenActivated((CompositeDisposable _) =>
|
this.WhenActivated((CompositeDisposable _) =>
|
||||||
{
|
{
|
||||||
@ -33,9 +34,9 @@ public partial class EntryListItemViewModel : ActivatableViewModelBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IEntrySummary Entry { get; }
|
public IEntrySummary Entry { get; }
|
||||||
public EntryVoteViewModel VoteViewModel { get; }
|
public ReactiveCommand<Unit, Unit> NavigateToEntry { get; }
|
||||||
|
|
||||||
public async Task NavigateToEntry()
|
private async Task ExecuteNavigateToEntry()
|
||||||
{
|
{
|
||||||
switch (Entry.EntryType)
|
switch (Entry.EntryType)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -137,9 +137,6 @@ public partial class EntryListViewModel : RoutableScreen
|
|||||||
if (InputViewModel.SortBy == 2)
|
if (InputViewModel.SortBy == 2)
|
||||||
return new[] {new EntrySortInput {Downloads = SortEnumType.Desc}};
|
return new[] {new EntrySortInput {Downloads = SortEnumType.Desc}};
|
||||||
|
|
||||||
// Sort by score
|
|
||||||
if (InputViewModel.SortBy == 3)
|
|
||||||
return new[] {new EntrySortInput {Score = SortEnumType.Desc}};
|
|
||||||
|
|
||||||
// Sort by latest release, then by created at
|
// Sort by latest release, then by created at
|
||||||
return new[]
|
return new[]
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
x:DataType="tabs:InstalledTabItemViewModel">
|
x:DataType="tabs:InstalledTabItemViewModel">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<converters:EntryIconUriConverter x:Key="EntryIconUriConverter" />
|
<converters:EntryIconUriConverter x:Key="EntryIconUriConverter" />
|
||||||
|
<converters:DateTimeConverter x:Key="DateTimeConverter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Button MinHeight="110"
|
<Button MinHeight="110"
|
||||||
MaxHeight="140"
|
MaxHeight="140"
|
||||||
@ -18,12 +19,9 @@
|
|||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
Command="{CompiledBinding ViewWorkshopPage}">
|
Command="{CompiledBinding ViewWorkshopPage}">
|
||||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto,Auto" RowDefinitions="*, Auto">
|
<Grid ColumnDefinitions="Auto,*,Auto,Auto" RowDefinitions="*, Auto">
|
||||||
<!-- Score -->
|
|
||||||
<ContentControl Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Width="40" Margin="0 0 10 0" Content="{CompiledBinding VoteViewModel}"/>
|
|
||||||
|
|
||||||
<!-- Icon -->
|
<!-- Icon -->
|
||||||
<Border Grid.Column="1"
|
<Border Grid.Column="0"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
CornerRadius="6"
|
CornerRadius="6"
|
||||||
@ -36,7 +34,7 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<Grid Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto">
|
<Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto">
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
<TextBlock Margin="0 0 0 5" TextTrimming="CharacterEllipsis">
|
<TextBlock Margin="0 0 0 5" TextTrimming="CharacterEllipsis">
|
||||||
<Run Classes="h5" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" />
|
<Run Classes="h5" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" />
|
||||||
@ -78,7 +76,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Info -->
|
<!-- Info -->
|
||||||
<StackPanel Grid.Column="3" Grid.Row="0" Margin="0 0 4 0" HorizontalAlignment="Right">
|
<StackPanel Grid.Column="2" Grid.Row="0" Margin="0 0 4 0" HorizontalAlignment="Right">
|
||||||
<TextBlock TextAlignment="Right">
|
<TextBlock TextAlignment="Right">
|
||||||
<avalonia:MaterialIcon Kind="Harddisk" />
|
<avalonia:MaterialIcon Kind="Harddisk" />
|
||||||
<Run Text="{CompiledBinding Entry.ReleaseVersion}" />
|
<Run Text="{CompiledBinding Entry.ReleaseVersion}" />
|
||||||
@ -86,7 +84,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Install state -->
|
<!-- Install state -->
|
||||||
<StackPanel Grid.Column="3" Grid.Row="1" Margin="0 0 4 0" HorizontalAlignment="Right" VerticalAlignment="Bottom">
|
<StackPanel Grid.Column="2" Grid.Row="1" Margin="0 0 4 0" HorizontalAlignment="Right" VerticalAlignment="Bottom">
|
||||||
<TextBlock TextAlignment="Right" IsVisible="{CompiledBinding UpdateAvailable}">
|
<TextBlock TextAlignment="Right" IsVisible="{CompiledBinding UpdateAvailable}">
|
||||||
<avalonia:MaterialIcon Kind="Update" Foreground="{DynamicResource SystemAccentColorLight1}" Width="20" Height="20" />
|
<avalonia:MaterialIcon Kind="Update" Foreground="{DynamicResource SystemAccentColorLight1}" Width="20" Height="20" />
|
||||||
<Run>update available</Run>
|
<Run>update available</Run>
|
||||||
@ -94,7 +92,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Management -->
|
<!-- Management -->
|
||||||
<Border Grid.Column="4" Grid.Row="0" Grid.RowSpan="2" BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="1 0 0 0" Margin="10 0 0 0" Padding="10 0 0 0">
|
<Border Grid.Column="3" Grid.Row="0" Grid.RowSpan="2" BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="1 0 0 0" Margin="10 0 0 0" Padding="10 0 0 0">
|
||||||
<StackPanel VerticalAlignment="Center">
|
<StackPanel VerticalAlignment="Center">
|
||||||
<StackPanel Orientation="Horizontal" Spacing="5">
|
<StackPanel Orientation="Horizontal" Spacing="5">
|
||||||
<Button Command="{CompiledBinding ViewLocal}" HorizontalAlignment="Stretch" >Open</Button>
|
<Button Command="{CompiledBinding ViewLocal}" HorizontalAlignment="Stretch" >Open</Button>
|
||||||
|
|||||||
@ -10,7 +10,6 @@ using Artemis.Core.Services;
|
|||||||
using Artemis.UI.DryIoc.Factories;
|
using Artemis.UI.DryIoc.Factories;
|
||||||
using Artemis.UI.Extensions;
|
using Artemis.UI.Extensions;
|
||||||
using Artemis.UI.Screens.Plugins;
|
using Artemis.UI.Screens.Plugins;
|
||||||
using Artemis.UI.Screens.Workshop.Entries;
|
|
||||||
using Artemis.UI.Services.Interfaces;
|
using Artemis.UI.Services.Interfaces;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Routing;
|
using Artemis.UI.Shared.Routing;
|
||||||
@ -36,7 +35,6 @@ public partial class InstalledTabItemViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
[Notify] private bool _updateAvailable;
|
[Notify] private bool _updateAvailable;
|
||||||
[Notify] private bool _autoUpdate;
|
[Notify] private bool _autoUpdate;
|
||||||
[Notify] private EntryVoteViewModel _voteViewModel;
|
|
||||||
|
|
||||||
public InstalledTabItemViewModel(InstalledEntry entry,
|
public InstalledTabItemViewModel(InstalledEntry entry,
|
||||||
IWorkshopClient client,
|
IWorkshopClient client,
|
||||||
@ -45,8 +43,7 @@ public partial class InstalledTabItemViewModel : ActivatableViewModelBase
|
|||||||
IRouter router,
|
IRouter router,
|
||||||
IWindowService windowService,
|
IWindowService windowService,
|
||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
ISettingsVmFactory settingsVmFactory,
|
ISettingsVmFactory settingsVmFactory)
|
||||||
Func<IEntrySummary, EntryVoteViewModel> getEntryVoteViewModel)
|
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_workshopService = workshopService;
|
_workshopService = workshopService;
|
||||||
@ -56,9 +53,9 @@ public partial class InstalledTabItemViewModel : ActivatableViewModelBase
|
|||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_settingsVmFactory = settingsVmFactory;
|
_settingsVmFactory = settingsVmFactory;
|
||||||
_autoUpdate = entry.AutoUpdate;
|
_autoUpdate = entry.AutoUpdate;
|
||||||
|
|
||||||
Entry = entry;
|
Entry = entry;
|
||||||
|
|
||||||
this.WhenActivatedAsync(async _ =>
|
this.WhenActivatedAsync(async _ =>
|
||||||
{
|
{
|
||||||
// Grab the latest entry summary from the workshop
|
// Grab the latest entry summary from the workshop
|
||||||
@ -68,7 +65,6 @@ public partial class InstalledTabItemViewModel : ActivatableViewModelBase
|
|||||||
if (entrySummary.Data?.Entry != null)
|
if (entrySummary.Data?.Entry != null)
|
||||||
{
|
{
|
||||||
Entry.ApplyEntrySummary(entrySummary.Data.Entry);
|
Entry.ApplyEntrySummary(entrySummary.Data.Entry);
|
||||||
VoteViewModel = getEntryVoteViewModel(entrySummary.Data.Entry);
|
|
||||||
_workshopService.SaveInstalledEntry(Entry);
|
_workshopService.SaveInstalledEntry(Entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +73,7 @@ public partial class InstalledTabItemViewModel : ActivatableViewModelBase
|
|||||||
UpdateAvailable = Entry.ReleaseId != Entry.LatestReleaseId;
|
UpdateAvailable = Entry.ReleaseId != Entry.LatestReleaseId;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.WhenAnyValue(vm => vm.AutoUpdate).Skip(1).Subscribe(_ => AutoUpdateToggled());
|
this.WhenAnyValue(vm => vm.AutoUpdate).Skip(1).Subscribe(_ => AutoUpdateToggled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +122,10 @@ public partial class InstalledTabItemViewModel : ActivatableViewModelBase
|
|||||||
private void AutoUpdateToggled()
|
private void AutoUpdateToggled()
|
||||||
{
|
{
|
||||||
_workshopService.SetAutoUpdate(Entry, AutoUpdate);
|
_workshopService.SetAutoUpdate(Entry, AutoUpdate);
|
||||||
|
|
||||||
if (!AutoUpdate)
|
if (!AutoUpdate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await _workshopUpdateService.AutoUpdateEntry(Entry);
|
await _workshopUpdateService.AutoUpdateEntry(Entry);
|
||||||
|
|||||||
@ -53,7 +53,6 @@ public static class ContainerExtensions
|
|||||||
container.Register<IAuthenticationRepository, AuthenticationRepository>(Reuse.Singleton);
|
container.Register<IAuthenticationRepository, AuthenticationRepository>(Reuse.Singleton);
|
||||||
container.Register<IAuthenticationService, AuthenticationService>(Reuse.Singleton);
|
container.Register<IAuthenticationService, AuthenticationService>(Reuse.Singleton);
|
||||||
container.Register<IWorkshopService, WorkshopService>(Reuse.Singleton);
|
container.Register<IWorkshopService, WorkshopService>(Reuse.Singleton);
|
||||||
container.Register<IVoteClient, VoteClient>(Reuse.Singleton);
|
|
||||||
container.Register<ILayoutProvider, WorkshopLayoutProvider>(Reuse.Singleton);
|
container.Register<ILayoutProvider, WorkshopLayoutProvider>(Reuse.Singleton);
|
||||||
container.Register<IUserManagementService, UserManagementService>();
|
container.Register<IUserManagementService, UserManagementService>();
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
mutation CastVote($input: CastVoteInput!) {
|
|
||||||
castVote(input: $input) {
|
|
||||||
...voteCount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutation ClearVote($entryId: Long!) {
|
|
||||||
clearVote(entryId: $entryId) {
|
|
||||||
...voteCount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment voteCount on Entry {
|
|
||||||
upvoteCount
|
|
||||||
downvoteCount
|
|
||||||
}
|
|
||||||
@ -2,4 +2,4 @@ mutation AddEntry ($input: CreateEntryInput!) {
|
|||||||
addEntry(input: $input) {
|
addEntry(input: $input) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,8 +36,6 @@ fragment entrySummary on Entry {
|
|||||||
summary
|
summary
|
||||||
entryType
|
entryType
|
||||||
downloads
|
downloads
|
||||||
upvoteCount
|
|
||||||
downvoteCount
|
|
||||||
createdAt
|
createdAt
|
||||||
latestReleaseId
|
latestReleaseId
|
||||||
categories {
|
categories {
|
||||||
@ -53,8 +51,6 @@ fragment entryDetails on Entry {
|
|||||||
summary
|
summary
|
||||||
entryType
|
entryType
|
||||||
downloads
|
downloads
|
||||||
upvoteCount
|
|
||||||
downvoteCount
|
|
||||||
createdAt
|
createdAt
|
||||||
description
|
description
|
||||||
categories {
|
categories {
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
query GetVotes {
|
|
||||||
votes {
|
|
||||||
entryId
|
|
||||||
upvote
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
using StrawberryShake;
|
|
||||||
|
|
||||||
namespace Artemis.WebClient.Workshop.Services;
|
|
||||||
|
|
||||||
public class VoteClient : IVoteClient
|
|
||||||
{
|
|
||||||
private readonly Dictionary<long, bool> _cache = new();
|
|
||||||
private readonly IWorkshopClient _client;
|
|
||||||
private readonly SemaphoreSlim _lock = new(1, 1);
|
|
||||||
private DateTime _cacheAge = DateTime.MinValue;
|
|
||||||
|
|
||||||
public VoteClient(IWorkshopClient client, IAuthenticationService authenticationService)
|
|
||||||
{
|
|
||||||
_client = client;
|
|
||||||
authenticationService.IsLoggedIn.Subscribe(_ => _cacheAge = DateTime.MinValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<bool?> GetVote(long entryId)
|
|
||||||
{
|
|
||||||
await _lock.WaitAsync();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_cacheAge < DateTime.UtcNow.AddMinutes(-15))
|
|
||||||
{
|
|
||||||
_cache.Clear();
|
|
||||||
IOperationResult<IGetVotesResult> result = await _client.GetVotes.ExecuteAsync();
|
|
||||||
if (result.Data?.Votes != null)
|
|
||||||
foreach (IGetVotes_Votes vote in result.Data.Votes)
|
|
||||||
_cache.Add(vote.EntryId, vote.Upvote);
|
|
||||||
_cacheAge = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cache.TryGetValue(entryId, out bool upvote) ? upvote : null;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IVoteCount?> CastVote(long entryId, bool upvote)
|
|
||||||
{
|
|
||||||
await _lock.WaitAsync();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IOperationResult<ICastVoteResult> result = await _client.CastVote.ExecuteAsync(new CastVoteInput {EntryId = entryId, Upvote = upvote});
|
|
||||||
if (result.IsSuccessResult() && result.Data?.CastVote != null)
|
|
||||||
_cache[entryId] = upvote;
|
|
||||||
|
|
||||||
return result.Data?.CastVote;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IVoteCount?> ClearVote(long entryId)
|
|
||||||
{
|
|
||||||
await _lock.WaitAsync();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IOperationResult<IClearVoteResult> result = await _client.ClearVote.ExecuteAsync(entryId);
|
|
||||||
if (result.IsSuccessResult() && result.Data?.ClearVote != null)
|
|
||||||
_cache.Remove(entryId);
|
|
||||||
|
|
||||||
return result.Data?.ClearVote;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_lock.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IVoteClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the vote status for a specific entry.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entryId">The ID of the entry</param>
|
|
||||||
/// <returns>A Task containing the vote status.</returns>
|
|
||||||
Task<bool?> GetVote(long entryId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Casts a vote for a specific entry.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entryId">The ID of the entry.</param>
|
|
||||||
/// <param name="upvote">A boolean indicating whether the vote is an upvote.</param>
|
|
||||||
/// <returns>A Task containing the cast vote.</returns>
|
|
||||||
Task<IVoteCount?> CastVote(long entryId, bool upvote);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears a vote for a specific entry.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entryId">The ID of the entry</param>
|
|
||||||
/// <returns>A Task containing the vote status.</returns>
|
|
||||||
Task<IVoteCount?> ClearVote(long entryId);
|
|
||||||
}
|
|
||||||
@ -2,10 +2,10 @@ namespace Artemis.WebClient.Workshop;
|
|||||||
|
|
||||||
public static class WorkshopConstants
|
public static class WorkshopConstants
|
||||||
{
|
{
|
||||||
public const string AUTHORITY_URL = "https://localhost:5001";
|
// public const string AUTHORITY_URL = "https://localhost:5001";
|
||||||
public const string WORKSHOP_URL = "https://localhost:7281";
|
// public const string WORKSHOP_URL = "https://localhost:7281";
|
||||||
// public const string AUTHORITY_URL = "https://identity.artemis-rgb.com";
|
public const string AUTHORITY_URL = "https://identity.artemis-rgb.com";
|
||||||
// public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com";
|
public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com";
|
||||||
public const string IDENTITY_CLIENT_NAME = "IdentityApiClient";
|
public const string IDENTITY_CLIENT_NAME = "IdentityApiClient";
|
||||||
public const string WORKSHOP_CLIENT_NAME = "WorkshopApiClient";
|
public const string WORKSHOP_CLIENT_NAME = "WorkshopApiClient";
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@ schema: schema.graphql
|
|||||||
extensions:
|
extensions:
|
||||||
endpoints:
|
endpoints:
|
||||||
Default GraphQL Endpoint:
|
Default GraphQL Endpoint:
|
||||||
url: https://localhost:7281/graphql/
|
url: https://workshop.artemis-rgb.com/graphql
|
||||||
headers:
|
headers:
|
||||||
user-agent: JS GraphQL
|
user-agent: JS GraphQL
|
||||||
introspect: true
|
introspect: true
|
||||||
|
|||||||
@ -56,13 +56,11 @@ type Entry {
|
|||||||
dependantReleases: [Release!]!
|
dependantReleases: [Release!]!
|
||||||
description: String!
|
description: String!
|
||||||
downloads: Long!
|
downloads: Long!
|
||||||
downvoteCount: Int!
|
|
||||||
entryType: EntryType!
|
entryType: EntryType!
|
||||||
icon: Image
|
icon: Image
|
||||||
iconId: UUID
|
iconId: UUID
|
||||||
id: Long!
|
id: Long!
|
||||||
images: [Image!]!
|
images: [Image!]!
|
||||||
isDefault: Boolean!
|
|
||||||
isOfficial: Boolean!
|
isOfficial: Boolean!
|
||||||
latestRelease: Release
|
latestRelease: Release
|
||||||
latestReleaseId: Long
|
latestReleaseId: Long
|
||||||
@ -70,10 +68,8 @@ type Entry {
|
|||||||
name: String!
|
name: String!
|
||||||
pluginInfo: PluginInfo
|
pluginInfo: PluginInfo
|
||||||
releases: [Release!]!
|
releases: [Release!]!
|
||||||
score: Int!
|
|
||||||
summary: String!
|
summary: String!
|
||||||
tags: [Tag!]!
|
tags: [Tag!]!
|
||||||
upvoteCount: Int!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Image {
|
type Image {
|
||||||
@ -103,8 +99,6 @@ type LayoutInfo {
|
|||||||
type Mutation {
|
type Mutation {
|
||||||
addEntry(input: CreateEntryInput!): Entry
|
addEntry(input: CreateEntryInput!): Entry
|
||||||
addLayoutInfo(input: CreateLayoutInfoInput!): LayoutInfo
|
addLayoutInfo(input: CreateLayoutInfoInput!): LayoutInfo
|
||||||
castVote(input: CastVoteInput!): Entry
|
|
||||||
clearVote(entryId: Long!): Entry
|
|
||||||
removeEntry(id: Long!): Entry
|
removeEntry(id: Long!): Entry
|
||||||
removeLayoutInfo(id: Long!): LayoutInfo!
|
removeLayoutInfo(id: Long!): LayoutInfo!
|
||||||
removeRelease(id: Long!): Release!
|
removeRelease(id: Long!): Release!
|
||||||
@ -174,7 +168,6 @@ type Query {
|
|||||||
searchKeyboardLayout(deviceProvider: UUID!, logicalLayout: String, model: String!, physicalLayout: KeyboardLayoutType!, vendor: String!): LayoutInfo
|
searchKeyboardLayout(deviceProvider: UUID!, logicalLayout: String, model: String!, physicalLayout: KeyboardLayoutType!, vendor: String!): LayoutInfo
|
||||||
searchLayout(deviceProvider: UUID!, deviceType: RGBDeviceType!, model: String!, vendor: String!): LayoutInfo
|
searchLayout(deviceProvider: UUID!, deviceType: RGBDeviceType!, model: String!, vendor: String!): LayoutInfo
|
||||||
submittedEntries(order: [EntrySortInput!], where: EntryFilterInput): [Entry!]!
|
submittedEntries(order: [EntrySortInput!], where: EntryFilterInput): [Entry!]!
|
||||||
votes(order: [VoteSortInput!], where: VoteFilterInput): [Vote!]!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Release {
|
type Release {
|
||||||
@ -195,15 +188,6 @@ type Tag {
|
|||||||
name: String!
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Vote {
|
|
||||||
entry: Entry!
|
|
||||||
entryId: Long!
|
|
||||||
id: Long!
|
|
||||||
upvote: Boolean!
|
|
||||||
userId: UUID!
|
|
||||||
votedAt: DateTime!
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ApplyPolicy {
|
enum ApplyPolicy {
|
||||||
AFTER_RESOLVER
|
AFTER_RESOLVER
|
||||||
BEFORE_RESOLVER
|
BEFORE_RESOLVER
|
||||||
@ -266,11 +250,6 @@ input BooleanOperationFilterInput {
|
|||||||
neq: Boolean
|
neq: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
input CastVoteInput {
|
|
||||||
entryId: Long!
|
|
||||||
upvote: Boolean!
|
|
||||||
}
|
|
||||||
|
|
||||||
input CategoryFilterInput {
|
input CategoryFilterInput {
|
||||||
and: [CategoryFilterInput!]
|
and: [CategoryFilterInput!]
|
||||||
icon: StringOperationFilterInput
|
icon: StringOperationFilterInput
|
||||||
@ -289,7 +268,6 @@ input CreateEntryInput {
|
|||||||
categories: [Long!]!
|
categories: [Long!]!
|
||||||
description: String!
|
description: String!
|
||||||
entryType: EntryType!
|
entryType: EntryType!
|
||||||
isDefault: Boolean!
|
|
||||||
name: String!
|
name: String!
|
||||||
summary: String!
|
summary: String!
|
||||||
tags: [String!]!
|
tags: [String!]!
|
||||||
@ -329,13 +307,11 @@ input EntryFilterInput {
|
|||||||
dependantReleases: ListFilterInputTypeOfReleaseFilterInput
|
dependantReleases: ListFilterInputTypeOfReleaseFilterInput
|
||||||
description: StringOperationFilterInput
|
description: StringOperationFilterInput
|
||||||
downloads: LongOperationFilterInput
|
downloads: LongOperationFilterInput
|
||||||
downvoteCount: IntOperationFilterInput
|
|
||||||
entryType: EntryTypeOperationFilterInput
|
entryType: EntryTypeOperationFilterInput
|
||||||
icon: ImageFilterInput
|
icon: ImageFilterInput
|
||||||
iconId: UuidOperationFilterInput
|
iconId: UuidOperationFilterInput
|
||||||
id: LongOperationFilterInput
|
id: LongOperationFilterInput
|
||||||
images: ListFilterInputTypeOfImageFilterInput
|
images: ListFilterInputTypeOfImageFilterInput
|
||||||
isDefault: BooleanOperationFilterInput
|
|
||||||
isOfficial: BooleanOperationFilterInput
|
isOfficial: BooleanOperationFilterInput
|
||||||
latestRelease: ReleaseFilterInput
|
latestRelease: ReleaseFilterInput
|
||||||
latestReleaseId: LongOperationFilterInput
|
latestReleaseId: LongOperationFilterInput
|
||||||
@ -344,10 +320,8 @@ input EntryFilterInput {
|
|||||||
or: [EntryFilterInput!]
|
or: [EntryFilterInput!]
|
||||||
pluginInfo: PluginInfoFilterInput
|
pluginInfo: PluginInfoFilterInput
|
||||||
releases: ListFilterInputTypeOfReleaseFilterInput
|
releases: ListFilterInputTypeOfReleaseFilterInput
|
||||||
score: IntOperationFilterInput
|
|
||||||
summary: StringOperationFilterInput
|
summary: StringOperationFilterInput
|
||||||
tags: ListFilterInputTypeOfTagFilterInput
|
tags: ListFilterInputTypeOfTagFilterInput
|
||||||
upvoteCount: IntOperationFilterInput
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input EntrySortInput {
|
input EntrySortInput {
|
||||||
@ -356,20 +330,16 @@ input EntrySortInput {
|
|||||||
createdAt: SortEnumType
|
createdAt: SortEnumType
|
||||||
description: SortEnumType
|
description: SortEnumType
|
||||||
downloads: SortEnumType
|
downloads: SortEnumType
|
||||||
downvoteCount: SortEnumType
|
|
||||||
entryType: SortEnumType
|
entryType: SortEnumType
|
||||||
icon: ImageSortInput
|
icon: ImageSortInput
|
||||||
iconId: SortEnumType
|
iconId: SortEnumType
|
||||||
id: SortEnumType
|
id: SortEnumType
|
||||||
isDefault: SortEnumType
|
|
||||||
isOfficial: SortEnumType
|
isOfficial: SortEnumType
|
||||||
latestRelease: ReleaseSortInput
|
latestRelease: ReleaseSortInput
|
||||||
latestReleaseId: SortEnumType
|
latestReleaseId: SortEnumType
|
||||||
name: SortEnumType
|
name: SortEnumType
|
||||||
pluginInfo: PluginInfoSortInput
|
pluginInfo: PluginInfoSortInput
|
||||||
score: SortEnumType
|
|
||||||
summary: SortEnumType
|
summary: SortEnumType
|
||||||
upvoteCount: SortEnumType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input EntryTypeOperationFilterInput {
|
input EntryTypeOperationFilterInput {
|
||||||
@ -610,7 +580,6 @@ input UpdateEntryInput {
|
|||||||
categories: [Long!]!
|
categories: [Long!]!
|
||||||
description: String!
|
description: String!
|
||||||
id: Long!
|
id: Long!
|
||||||
isDefault: Boolean!
|
|
||||||
name: String!
|
name: String!
|
||||||
summary: String!
|
summary: String!
|
||||||
tags: [String!]!
|
tags: [String!]!
|
||||||
@ -635,23 +604,3 @@ input UuidOperationFilterInput {
|
|||||||
nlt: UUID
|
nlt: UUID
|
||||||
nlte: UUID
|
nlte: UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
input VoteFilterInput {
|
|
||||||
and: [VoteFilterInput!]
|
|
||||||
entry: EntryFilterInput
|
|
||||||
entryId: LongOperationFilterInput
|
|
||||||
id: LongOperationFilterInput
|
|
||||||
or: [VoteFilterInput!]
|
|
||||||
upvote: BooleanOperationFilterInput
|
|
||||||
userId: UuidOperationFilterInput
|
|
||||||
votedAt: DateTimeOperationFilterInput
|
|
||||||
}
|
|
||||||
|
|
||||||
input VoteSortInput {
|
|
||||||
entry: EntrySortInput
|
|
||||||
entryId: SortEnumType
|
|
||||||
id: SortEnumType
|
|
||||||
upvote: SortEnumType
|
|
||||||
userId: SortEnumType
|
|
||||||
votedAt: SortEnumType
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user