mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-02-04 02:43:32 +00:00
Surface editor - Show model instead of device name
Settings - Add link to plugin's workshop page Workshop library - Recently updated tab (WIP)
This commit is contained in:
parent
0823de45a4
commit
74d5480d7b
@ -50,7 +50,8 @@ namespace Artemis.UI.Routing
|
||||
new RouteRegistration<SubmissionsTabViewModel>("submissions"),
|
||||
new RouteRegistration<SubmissionManagementViewModel>("submissions/{entryId:long}", [
|
||||
new RouteRegistration<SubmissionReleaseViewModel>("releases/{releaseId:long}")
|
||||
])
|
||||
]),
|
||||
new RouteRegistration<RecentlyUpdatedViewModel>("recently-updated")
|
||||
])
|
||||
]),
|
||||
new RouteRegistration<SurfaceEditorViewModel>("surface-editor"),
|
||||
|
||||
@ -92,6 +92,12 @@
|
||||
ToolTip.Tip="Open settings">
|
||||
<avalonia:MaterialIcon Kind="Cog" />
|
||||
</HyperlinkButton>
|
||||
<HyperlinkButton Classes="icon-button icon-button-large"
|
||||
IsVisible="{CompiledBinding WorkshopEntry, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
Command="{CompiledBinding ViewEntry}"
|
||||
ToolTip.Tip="View on workshop">
|
||||
<avalonia:MaterialIcon Kind="TestTube" />
|
||||
</HyperlinkButton>
|
||||
<HyperlinkButton Classes="icon-button icon-button-large"
|
||||
IsVisible="{CompiledBinding PluginInfo.HelpPage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
|
||||
NavigateUri="{CompiledBinding PluginInfo.HelpPage}"
|
||||
|
||||
@ -11,6 +11,8 @@ using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.WebClient.Workshop.Models;
|
||||
using Artemis.WebClient.Workshop.Services;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Threading;
|
||||
using Material.Icons;
|
||||
@ -22,21 +24,25 @@ namespace Artemis.UI.Screens.Plugins;
|
||||
public partial class PluginViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly IPluginInteractionService _pluginInteractionService;
|
||||
private readonly IWorkshopService _workshopService;
|
||||
private readonly IWindowService _windowService;
|
||||
private Window? _settingsWindow;
|
||||
[Notify] private bool _canInstallPrerequisites;
|
||||
[Notify] private bool _canRemovePrerequisites;
|
||||
[Notify] private bool _enabling;
|
||||
[Notify] private InstalledEntry? _workshopEntry;
|
||||
|
||||
public PluginInfo PluginInfo { get; }
|
||||
public Plugin? Plugin { get; }
|
||||
|
||||
public PluginViewModel(PluginInfo pluginInfo, ReactiveCommand<Unit, Unit>? reload, IWindowService windowService, IPluginInteractionService pluginInteractionService)
|
||||
public PluginViewModel(PluginInfo pluginInfo, ReactiveCommand<Unit, Unit>? reload, IWindowService windowService, IPluginInteractionService pluginInteractionService,
|
||||
IWorkshopService workshopService)
|
||||
{
|
||||
PluginInfo = pluginInfo;
|
||||
Plugin = pluginInfo?.Plugin;
|
||||
_windowService = windowService;
|
||||
_pluginInteractionService = pluginInteractionService;
|
||||
_workshopService = workshopService;
|
||||
|
||||
Platforms = [];
|
||||
if (PluginInfo.Platforms != null)
|
||||
@ -51,12 +57,8 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
|
||||
Reload = reload;
|
||||
OpenSettings = ReactiveCommand.Create(ExecuteOpenSettings, this.WhenAnyValue(vm => vm.IsEnabled, e => e && Plugin?.ConfigurationDialog != null));
|
||||
RemoveSettings = ReactiveCommand.CreateFromTask(ExecuteRemoveSettings);
|
||||
Remove = ReactiveCommand.CreateFromTask(ExecuteRemove);
|
||||
InstallPrerequisites = ReactiveCommand.CreateFromTask(ExecuteInstallPrerequisites, this.WhenAnyValue(x => x.CanInstallPrerequisites));
|
||||
RemovePrerequisites = ReactiveCommand.CreateFromTask<bool>(ExecuteRemovePrerequisites, this.WhenAnyValue(x => x.CanRemovePrerequisites));
|
||||
ShowLogsFolder = ReactiveCommand.Create(ExecuteShowLogsFolder);
|
||||
OpenPluginDirectory = ReactiveCommand.Create(ExecuteOpenPluginDirectory);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
@ -65,6 +67,7 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
|
||||
Plugin.Enabled += OnPluginToggled;
|
||||
Plugin.Disabled += OnPluginToggled;
|
||||
WorkshopEntry = _workshopService.GetInstalledEntryByPlugin(Plugin);
|
||||
|
||||
Disposable.Create(() =>
|
||||
{
|
||||
@ -77,12 +80,8 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
|
||||
public ReactiveCommand<Unit, Unit>? Reload { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenSettings { get; }
|
||||
public ReactiveCommand<Unit, Unit> RemoveSettings { get; }
|
||||
public ReactiveCommand<Unit, Unit> Remove { get; }
|
||||
public ReactiveCommand<Unit, Unit> InstallPrerequisites { get; }
|
||||
public ReactiveCommand<bool, Unit> RemovePrerequisites { get; }
|
||||
public ReactiveCommand<Unit, Unit> ShowLogsFolder { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenPluginDirectory { get; }
|
||||
|
||||
public ObservableCollection<PluginPlatformViewModel> Platforms { get; }
|
||||
public bool IsEnabled => Plugin != null && Plugin.IsEnabled;
|
||||
@ -121,6 +120,68 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
});
|
||||
}
|
||||
|
||||
public void OpenPluginDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Plugin != null)
|
||||
Utilities.OpenFolder(Plugin.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_windowService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RemoveSettings()
|
||||
{
|
||||
if (Plugin == null)
|
||||
return;
|
||||
|
||||
await _pluginInteractionService.RemovePluginSettings(Plugin);
|
||||
}
|
||||
|
||||
public async Task Remove()
|
||||
{
|
||||
if (Plugin == null)
|
||||
return;
|
||||
|
||||
await _pluginInteractionService.RemovePlugin(Plugin);
|
||||
}
|
||||
|
||||
public async Task AutoEnable()
|
||||
{
|
||||
if (IsEnabled)
|
||||
return;
|
||||
|
||||
await UpdateEnabled(true);
|
||||
|
||||
// If enabling failed, don't offer to show the settings
|
||||
if (!IsEnabled || Plugin?.ConfigurationDialog == null)
|
||||
return;
|
||||
|
||||
if (await _windowService.ShowConfirmContentDialog("Open plugin settings", "This plugin has settings, would you like to view them?", "Yes", "No"))
|
||||
ExecuteOpenSettings();
|
||||
}
|
||||
|
||||
public async Task ViewEntry()
|
||||
{
|
||||
if (WorkshopEntry != null)
|
||||
await _workshopService.NavigateToEntry(WorkshopEntry.Id, WorkshopEntry.EntryType);
|
||||
}
|
||||
|
||||
public async Task ExecuteRemovePrerequisites(bool forPluginRemoval = false)
|
||||
{
|
||||
if (Plugin == null)
|
||||
return;
|
||||
|
||||
List<IPrerequisitesSubject> subjects = [PluginInfo];
|
||||
subjects.AddRange(!forPluginRemoval ? Plugin.Features.Where(f => f.AlwaysEnabled) : Plugin.Features);
|
||||
|
||||
if (subjects.Any(s => s.PlatformPrerequisites.Any(p => p.UninstallActions.Any())))
|
||||
await PluginPrerequisitesUninstallDialogViewModel.Show(_windowService, subjects, forPluginRemoval ? "Skip, remove plugin" : "Cancel");
|
||||
}
|
||||
|
||||
private void ExecuteOpenSettings()
|
||||
{
|
||||
if (Plugin?.ConfigurationDialog == null)
|
||||
@ -148,19 +209,6 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteOpenPluginDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Plugin != null)
|
||||
Utilities.OpenFolder(Plugin.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_windowService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ExecuteInstallPrerequisites()
|
||||
{
|
||||
if (Plugin == null)
|
||||
@ -173,46 +221,6 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_windowService, subjects);
|
||||
}
|
||||
|
||||
public async Task ExecuteRemovePrerequisites(bool forPluginRemoval = false)
|
||||
{
|
||||
if (Plugin == null)
|
||||
return;
|
||||
|
||||
List<IPrerequisitesSubject> subjects = [PluginInfo];
|
||||
subjects.AddRange(!forPluginRemoval ? Plugin.Features.Where(f => f.AlwaysEnabled) : Plugin.Features);
|
||||
|
||||
if (subjects.Any(s => s.PlatformPrerequisites.Any(p => p.UninstallActions.Any())))
|
||||
await PluginPrerequisitesUninstallDialogViewModel.Show(_windowService, subjects, forPluginRemoval ? "Skip, remove plugin" : "Cancel");
|
||||
}
|
||||
|
||||
private async Task ExecuteRemoveSettings()
|
||||
{
|
||||
if (Plugin == null)
|
||||
return;
|
||||
|
||||
await _pluginInteractionService.RemovePluginSettings(Plugin);
|
||||
}
|
||||
|
||||
private async Task ExecuteRemove()
|
||||
{
|
||||
if (Plugin == null)
|
||||
return;
|
||||
|
||||
await _pluginInteractionService.RemovePlugin(Plugin);
|
||||
}
|
||||
|
||||
private void ExecuteShowLogsFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
Utilities.OpenFolder(Constants.LogsFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_windowService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPluginToggled(object? sender, EventArgs e)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
@ -222,19 +230,4 @@ public partial class PluginViewModel : ActivatableViewModelBase
|
||||
_settingsWindow?.Close();
|
||||
});
|
||||
}
|
||||
|
||||
public async Task AutoEnable()
|
||||
{
|
||||
if (IsEnabled)
|
||||
return;
|
||||
|
||||
await UpdateEnabled(true);
|
||||
|
||||
// If enabling failed, don't offer to show the settings
|
||||
if (!IsEnabled || Plugin?.ConfigurationDialog == null)
|
||||
return;
|
||||
|
||||
if (await _windowService.ShowConfirmContentDialog("Open plugin settings", "This plugin has settings, would you like to view them?", "Yes", "No"))
|
||||
ExecuteOpenSettings();
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@
|
||||
<Border Grid.Column="0" Grid.RowSpan="2" Width="64" Height="50" Margin="0 0 10 0">
|
||||
<shared:DeviceVisualizer Device="{CompiledBinding Device}" ShowColors="True" VerticalAlignment="Center" HorizontalAlignment="Center" RenderOptions.BitmapInterpolationMode="MediumQuality"/>
|
||||
</Border>
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.DeviceName}" VerticalAlignment="Bottom" />
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.Model}" VerticalAlignment="Bottom" />
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Classes="subtitle" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.Manufacturer}" VerticalAlignment="Top" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -0,0 +1,10 @@
|
||||
<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:tabs="clr-namespace:Artemis.UI.Screens.Workshop.Library.Tabs"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Library.Tabs.RecentlyUpdatedItemView"
|
||||
x:DataType="tabs:RecentlyUpdatedItemViewModel">
|
||||
Welcome to Avalonia!
|
||||
</UserControl>
|
||||
@ -0,0 +1,11 @@
|
||||
using ReactiveUI.Avalonia;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Library.Tabs;
|
||||
|
||||
public partial class RecentlyUpdatedItemView : ReactiveUserControl<RecentlyUpdatedItemViewModel>
|
||||
{
|
||||
public RecentlyUpdatedItemView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Library.Tabs;
|
||||
|
||||
public partial class RecentlyUpdatedItemViewModel : ActivatableViewModelBase
|
||||
{
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<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:tabs="clr-namespace:Artemis.UI.Screens.Workshop.Library.Tabs"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Library.Tabs.RecentlyUpdatedView"
|
||||
x:DataType="tabs:RecentlyUpdatedViewModel">
|
||||
Welcome to Avalonia!
|
||||
</UserControl>
|
||||
@ -0,0 +1,11 @@
|
||||
using ReactiveUI.Avalonia;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Library.Tabs;
|
||||
|
||||
public partial class RecentlyUpdatedView : ReactiveUserControl<InstalledTabViewModel>
|
||||
{
|
||||
public RecentlyUpdatedView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using Artemis.UI.Shared.Routing;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Library.Tabs;
|
||||
|
||||
public partial class RecentlyUpdatedViewModel : RoutableScreen
|
||||
{
|
||||
|
||||
}
|
||||
@ -26,7 +26,8 @@ public partial class WorkshopLibraryViewModel : RoutableHostScreen<RoutableScree
|
||||
Tabs =
|
||||
[
|
||||
new RouteViewModel("Installed", "workshop/library/installed"),
|
||||
new RouteViewModel("Submissions", "workshop/library/submissions")
|
||||
new RouteViewModel("Submissions", "workshop/library/submissions"),
|
||||
new RouteViewModel("Recently Updated", "workshop/library/recently-updated")
|
||||
];
|
||||
|
||||
this.WhenActivated(d =>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user