Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions Desktop/Desktop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
</PropertyGroup>

<ItemGroup Condition="'$(Configuration)' == 'Debug-Windows' Or '$(Configuration)' == 'Release-Windows'">
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.81" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.81" />
<PackageReference Update="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.81" />
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.100" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.100" />
<PackageReference Update="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.100" />
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug-Photino' Or '$(Configuration)' == 'Release-Photino'">
Expand All @@ -60,16 +60,17 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AspNetCore.SassCompiler" Version="1.89.2" />
<PackageReference Update="Microsoft.AspNetCore.Components.Web" Version="9.0.8" />
<PackageReference Include="AspNetCore.SassCompiler" Version="1.90.0" />
<PackageReference Include="CommandLineParser" Version="2.9.1"/>
<PackageReference Include="dnlib" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.7" />
<PackageReference Include="MudBlazor" Version="8.9.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.8" />
<PackageReference Include="MudBlazor" Version="8.11.0" />
<PackageReference Include="Semver" Version="3.0.0" />
<PackageReference Include="Serilog" Version="4.3.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.7" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.8" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
Expand Down
6 changes: 3 additions & 3 deletions Desktop/ModuleFileProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void SetModuleManager(ModuleManager.ModuleManager moduleManager)
{
if (_moduleManager != null)
{
_modulesLoadedSubscription.Dispose();
_modulesLoadedSubscription?.Dispose();
}

_moduleManager = moduleManager;
Expand Down Expand Up @@ -306,13 +306,13 @@ private static void MakeValidEverettFolderIdentifier(StringBuilder builder, stri
#endregion

private bool _disposed;
private IDisposable _modulesLoadedSubscription;
private IDisposable? _modulesLoadedSubscription;

public void Dispose()
{
if (_disposed) return;
_disposed = true;

_modulesLoadedSubscription.Dispose();
_modulesLoadedSubscription?.Dispose();
}
}
7 changes: 7 additions & 0 deletions Desktop/ModuleManager/ModuleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ private void LoadModule(string moduleFolderPath, string moduleDll, string module

var module = (DesktopModuleBase?)ActivatorUtilities.CreateInstance(_serviceProvider, moduleAttribute.ModuleType);
if (module is null) throw new Exception("Failed to instantiate module!");

#pragma warning disable CS0618
if (module.IconPath is not null)
{
module.Icon = IconOneOf.FromPath(module.IconPath);
}
#pragma warning restore CS0618

var loadedModule = new LoadedModule
{
Expand Down
21 changes: 18 additions & 3 deletions Desktop/Ui/Pages/Dash/Components/ModuleManagerItem.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@using System.Collections.Immutable
@using OpenShock.Desktop.Config
@using OpenShock.Desktop.ModuleBase
@using OpenShock.Desktop.ModuleManager
@using OpenShock.Desktop.ModuleManager.Repository
@using OpenShock.Desktop.Utils
Expand All @@ -10,7 +11,15 @@
@inject ISnackbar Snackbar

<MudPaper Class="d-flex module-manager-item-root rounded-lg gap-10" Outlined="true">
<img src="@_moduleIcon" alt="@_moduleName" class="icon rounded-lg"/>
@switch (_moduleIcon?.Index)
{
case 0:
<img src="@_moduleIcon.AsT0" alt="Module Icon" class="icon rounded-lg"/>
break;
case 1:
<MudIcon Icon="@_moduleIcon.AsT1"/>
break;
}

<div class="d-flex flex-column justify-space-evenly overflow-hidden">
<MudText Typo="Typo.h4">@_moduleName</MudText>
Expand Down Expand Up @@ -112,7 +121,7 @@
[Parameter] public required string ModuleId { get; init; }

private string _moduleName = null!;
private string? _moduleIcon;
private IconOneOf? _moduleIcon;

private SemVersion? LatestVersion => RepoModule?.Versions.Keys.Where(x => x.IsRelease).OrderByDescending(x => x, SemVersion.PrecedenceComparer).FirstOrDefault();
private SemVersion? LatestPreReleaseVersion => RepoModule?.Versions.Keys.Where(x => !x.IsRelease).OrderByDescending(x => x, SemVersion.PrecedenceComparer).FirstOrDefault();
Expand All @@ -127,7 +136,13 @@
}

_moduleName = RepoModule?.Name ?? (LoadedModule?.Name ?? "error");
_moduleIcon = RepoModule?.IconUrl?.ToString() ?? LoadedModule?.Module.IconPath;
if (RepoModule?.IconUrl is not null)
{
_moduleIcon = IconOneOf.FromPath(RepoModule.IconUrl.ToString());
}
{
_moduleIcon = LoadedModule?.Module.Icon;
}
_availableVersions = GetAvailableVersions();
}

Expand Down
19 changes: 13 additions & 6 deletions Desktop/Ui/Pages/Dash/Components/ModuleNavComponent.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
@using OpenShock.Desktop.ModuleManager

<ModuleNavGroup IconImage="@LoadedModule.Module.IconPath" Title="@LoadedModule.Name">
@foreach (var subComponent in LoadedModule.Module.NavigationComponents)
{
<ModuleNavLink Icon="@subComponent.Icon" Href="@("/dash/module/" + LoadedModule.Id + "/" + subComponent.Name)">@(subComponent.Name)</ModuleNavLink>
}
</ModuleNavGroup>
@if (LoadedModule.Module.RootComponent is not null)
{
<ModuleNavLink Icon="LoadedModule.Module.Icon" Href="@("/dash/module/" + LoadedModule.Id)">@LoadedModule.Name</ModuleNavLink>
}
else
{
<ModuleNavGroup Icon="@LoadedModule.Module.Icon" Title="@LoadedModule.Name">
@foreach (var subComponent in LoadedModule.Module.NavigationComponents)
{
<ModuleNavLink Icon="@subComponent.Icon" Href="@("/dash/module/" + LoadedModule.Id + "/" + subComponent.Name)">@(subComponent.Name)</ModuleNavLink>
}
</ModuleNavGroup>
}


@code {
Expand Down
11 changes: 8 additions & 3 deletions Desktop/Ui/Pages/Dash/Components/ModuleNavGroup.razor
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@
aria-controls="@_navigationContext.MenuId"
aria-expanded="@_navigationContext.Expanded.ToString().ToLowerInvariant()"
aria-label="Toggle Module Navigation">
@if (!string.IsNullOrEmpty(IconImage))
@switch (Icon?.Index)
{
<img src="@IconImage" alt="Module Icon" style="width: 24px; height: 24px">
case 0:
<img src="@Icon.AsT0" alt="Module Icon" style="width: 24px; height: 24px">
break;
case 1:
<MudIcon Icon="@Icon.AsT1"/>
break;
}
<div Class="mud-nav-link-text">
@Title
</div>
@if (!HideExpandIcon)
{
<MudIcon Disabled="@Disabled" Icon="@ExpandIcon" Class="@ExpandIconClassname" />
<MudIcon Disabled="@Disabled" Icon="@ExpandIcon" Class="@ExpandIconClassname"/>
}
</button>
<MudCollapse aria-hidden="@((_navigationContext.Expanded is false).ToString().ToLowerInvariant())"
Expand Down
3 changes: 2 additions & 1 deletion Desktop/Ui/Pages/Dash/Components/ModuleNavGroup.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using MudBlazor;
using MudBlazor.State;
using MudBlazor.Utilities;
using OpenShock.Desktop.ModuleBase;

namespace OpenShock.Desktop.Ui.Pages.Dash.Components;

Expand Down Expand Up @@ -71,7 +72,7 @@ protected override void OnInitialized()
/// </remarks>
[Parameter]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string? IconImage { get; set; }
public IconOneOf? Icon { get; set; }

/// <summary>
/// The CSS classes applied to this nav group title.
Expand Down
34 changes: 25 additions & 9 deletions Desktop/Ui/Pages/Dash/ModulePage.razor
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
@using OpenShock.Desktop.ModuleManager

@inject ModuleManager ModuleManager
@page "/dash/module/{module}"
@page "/dash/module/{module}/{component}"

@if (LoadedModule == null)
@if (_loadedModule == null)
{
<MudPaper Outlined="true" Class="mud-paper-padding">
<MudText Typo="Typo.h6">Module not found [@Module]</MudText>
</MudPaper>
}
else if (ComponentType == null)
else if (_loadedModule.Module.RootComponent is not null)
{
<MudPaper Outlined="true" Class="mud-paper-padding">
<MudText Typo="Typo.h6">Sub Component not found [@Module] [@Component]</MudText>
</MudPaper>
<DynamicComponent Type="_loadedModule.Module.RootComponent"></DynamicComponent>
}
else if (_componentType is not null)
{
<DynamicComponent Type="_componentType"></DynamicComponent>
}
else
{
<DynamicComponent Type="ComponentType"></DynamicComponent>
<MudPaper Outlined="true" Class="mud-paper-padding">
<MudText Typo="Typo.h6">Sub Component not found [@Module] [@Component]</MudText>
</MudPaper>
}

@code {
[Parameter] public string? Module { get; set; }

[Parameter] public string? Component { get; set; }

private LoadedModule? LoadedModule => string.IsNullOrWhiteSpace(Module) ? null : ModuleManager.Modules.GetValueOrDefault(Module);
private LoadedModule? _loadedModule;

private Type? _componentType;

private Type? ComponentType => LoadedModule?.Module.NavigationComponents.FirstOrDefault(x => x.Name.Equals(Component, StringComparison.InvariantCultureIgnoreCase))
?.ComponentType;
public override async Task SetParametersAsync(ParameterView parameters)
{
await base.SetParametersAsync(parameters);
SetupVariables();
}

private void SetupVariables()
{
_loadedModule = string.IsNullOrWhiteSpace(Module) ? null : ModuleManager.Modules.GetValueOrDefault(Module);
_componentType = _loadedModule?.Module.NavigationComponents.FirstOrDefault(x => x.Name.Equals(Component, StringComparison.InvariantCultureIgnoreCase))
?.ComponentType;
}
}
2 changes: 1 addition & 1 deletion ExampleModule/ExampleModule.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="MudBlazor" Version="8.10.0" />
<PackageReference Include="MudBlazor" Version="8.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

Expand Down
50 changes: 49 additions & 1 deletion ModuleBase/DesktopModuleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,75 @@

namespace OpenShock.Desktop.ModuleBase;

/// <summary>
/// The main base class for all desktop modules.
/// </summary>
public abstract class DesktopModuleBase
{
/// <summary>
/// Icon path for the module, used in navigation and other UI components.
/// </summary>
[Obsolete("Use Icon property instead. This property will be removed in a future version.")]
public virtual string? IconPath { get; } = null;

/// <summary>
/// Main icon for the module, used in navigation and other UI components.
/// </summary>
public virtual IconOneOf? Icon { get; set; } = null;

/// <summary>
/// Main interface for modules to interact with OpenShock Desktop.
/// </summary>
public IModuleInstanceManager ModuleInstanceManager { get; private set; } = null!;


/// <summary>
/// A collection of navigation components that this module provides.
/// These components will be displayed in the main navigation menu of the application.
/// </summary>
public abstract IReadOnlyCollection<NavigationItem> NavigationComponents { get; }

/// <summary>
/// Alternative to <see cref="NavigationComponents"/> for modules that have a single main component.
/// </summary>
public virtual Type? RootComponent { get; } = null;

/// <summary>
/// This method is called by OpenShock Desktop to set the context for the module. Do not call this method by yourself.
/// </summary>
/// <param name="moduleInstanceManager"></param>
public void SetContext(IModuleInstanceManager moduleInstanceManager)
{
ModuleInstanceManager = moduleInstanceManager;
}

/// <summary>
/// During startup, this method is called to allow the module to perform any necessary setup.
/// </summary>
/// <returns>A <see cref="Task"/> that represents the completion of any asynchronous setup operations required by the module.</returns>
public virtual Task Setup()
{
return Task.CompletedTask;
}

/// <summary>
/// Called after <see cref="Setup"/> to allow the module to start any necessary services or perform additional initialization.
/// </summary>
/// <returns>A <see cref="Task"/> that represents the completion of any startup logic or initialization performed by the module.</returns>
public virtual Task Start()
{
return Task.CompletedTask;
}

/// <summary>
/// Module service provider.
/// You can use the <see cref="ModuleInjectAttribute"/> to resolve services that are registered for this module within blazor components.
///
/// <example>
/// <code>
/// [ModuleInject] private IModuleConfig<SomeModuleConfig> ModuleConfig { get; set; } = null!;
/// </code>
/// </example>
///
/// </summary>
public IServiceProvider ModuleServiceProvider { get; protected set; } = new ServiceCollection().BuildServiceProvider();
}
2 changes: 1 addition & 1 deletion ModuleBase/ModuleBase.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<ItemGroup>
<PackageReference Include="OpenShock.MinimalEvents" Version="0.0.1" />
<PackageReference Update="Microsoft.AspNetCore.Components.Web" Version="9.0.7" />
<PackageReference Update="Microsoft.AspNetCore.Components.Web" Version="9.0.8" />
</ItemGroup>

</Project>
Loading