2026-03-09 12:27:33 +08:00
|
|
|
using LanMountainDesktop.PluginSdk;
|
|
|
|
|
|
|
|
|
|
namespace LanMountainDesktop.SamplePlugin;
|
|
|
|
|
|
|
|
|
|
[PluginEntrance]
|
|
|
|
|
public sealed class SamplePlugin : PluginBase, IDisposable
|
|
|
|
|
{
|
2026-03-09 14:14:50 +08:00
|
|
|
private SamplePluginRuntimeStateService? _stateService;
|
|
|
|
|
private SamplePluginClockService? _clockService;
|
2026-03-09 12:27:33 +08:00
|
|
|
|
|
|
|
|
public override void Initialize(IPluginContext context)
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(context.DataDirectory);
|
2026-03-10 00:40:26 +08:00
|
|
|
var localizer = PluginLocalizer.Create(context);
|
2026-03-09 12:27:33 +08:00
|
|
|
|
2026-03-10 00:40:26 +08:00
|
|
|
var hostName = GetHostProperty(context, PluginHostPropertyKeys.HostApplicationName, "UnknownHost");
|
|
|
|
|
var hostVersion = GetHostProperty(context, PluginHostPropertyKeys.HostVersion, "UnknownVersion");
|
|
|
|
|
var sdkApiVersion = GetHostProperty(context, PluginHostPropertyKeys.PluginSdkApiVersion, "UnknownApiVersion");
|
2026-03-09 14:14:50 +08:00
|
|
|
var messageBus = context.GetService<IPluginMessageBus>()
|
|
|
|
|
?? throw new InvalidOperationException("Plugin message bus is not available.");
|
2026-03-09 12:27:33 +08:00
|
|
|
|
2026-03-09 14:14:50 +08:00
|
|
|
_stateService = new SamplePluginRuntimeStateService(
|
|
|
|
|
context.Manifest,
|
|
|
|
|
context.PluginDirectory,
|
|
|
|
|
context.DataDirectory,
|
|
|
|
|
hostName,
|
|
|
|
|
hostVersion,
|
|
|
|
|
sdkApiVersion,
|
2026-03-10 00:40:26 +08:00
|
|
|
messageBus,
|
|
|
|
|
localizer);
|
2026-03-09 14:14:50 +08:00
|
|
|
context.RegisterService(_stateService);
|
2026-03-09 12:27:33 +08:00
|
|
|
|
2026-03-10 00:40:26 +08:00
|
|
|
_clockService = new SamplePluginClockService(context.DataDirectory, _stateService, messageBus, localizer);
|
2026-03-09 14:14:50 +08:00
|
|
|
context.RegisterService(_clockService);
|
|
|
|
|
_stateService.AttachClockService(_clockService);
|
|
|
|
|
|
|
|
|
|
var logPath = Path.Combine(context.DataDirectory, "sample-plugin.log");
|
|
|
|
|
var initMessage =
|
|
|
|
|
$"[{DateTimeOffset.UtcNow:O}] {context.Manifest.Name} initialized in {hostName} (plugin version {context.Manifest.Version ?? "dev"}).";
|
2026-03-09 12:27:33 +08:00
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2026-03-09 14:14:50 +08:00
|
|
|
File.AppendAllText(logPath, initMessage + Environment.NewLine);
|
2026-03-10 00:40:26 +08:00
|
|
|
_stateService.MarkBackendReady(localizer.Format(
|
|
|
|
|
"status.backend.detail.log_written",
|
2026-03-13 00:33:00 +08:00
|
|
|
"Initialization log written: {0}",
|
2026-03-10 00:40:26 +08:00
|
|
|
logPath));
|
2026-03-09 12:27:33 +08:00
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2026-03-10 00:40:26 +08:00
|
|
|
_stateService.MarkBackendFaulted(localizer.Format(
|
|
|
|
|
"status.backend.detail.log_write_failed",
|
2026-03-13 00:33:00 +08:00
|
|
|
"Initialization log failed: {0}",
|
2026-03-10 00:40:26 +08:00
|
|
|
ex.Message));
|
2026-03-09 12:27:33 +08:00
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-09 14:14:50 +08:00
|
|
|
_clockService.Start();
|
2026-03-09 12:27:33 +08:00
|
|
|
|
|
|
|
|
context.RegisterDesktopComponent(new PluginDesktopComponentRegistration(
|
|
|
|
|
"LanMountainDesktop.SamplePlugin.StatusClock",
|
2026-03-13 00:33:00 +08:00
|
|
|
localizer.GetString("widget.display_name", "Sample Plugin Status Clock"),
|
2026-03-09 12:27:33 +08:00
|
|
|
widgetContext => new SamplePluginStatusClockWidget(widgetContext),
|
|
|
|
|
iconKey: "PuzzlePiece",
|
2026-03-13 00:33:00 +08:00
|
|
|
category: localizer.GetString("widget.category", "Plugins"),
|
2026-03-09 12:27:33 +08:00
|
|
|
minWidthCells: 4,
|
|
|
|
|
minHeightCells: 4,
|
|
|
|
|
allowDesktopPlacement: true,
|
|
|
|
|
allowStatusBarPlacement: false,
|
|
|
|
|
resizeMode: PluginDesktopComponentResizeMode.Proportional,
|
|
|
|
|
cornerRadiusResolver: cellSize => Math.Clamp(cellSize * 0.34, 18, 34)));
|
2026-03-11 09:40:36 +08:00
|
|
|
|
|
|
|
|
context.RegisterDesktopComponent(new PluginDesktopComponentRegistration(
|
|
|
|
|
"LanMountainDesktop.SamplePlugin.CloseDesktop",
|
2026-03-13 00:33:00 +08:00
|
|
|
localizer.GetString("widget.close_desktop.display_name", "Close Desktop"),
|
2026-03-11 09:40:36 +08:00
|
|
|
widgetContext => new SamplePluginCloseDesktopWidget(widgetContext),
|
|
|
|
|
iconKey: "DismissCircle",
|
2026-03-13 00:33:00 +08:00
|
|
|
category: localizer.GetString("widget.category", "Plugins"),
|
2026-03-11 09:40:36 +08:00
|
|
|
minWidthCells: 2,
|
|
|
|
|
minHeightCells: 1,
|
|
|
|
|
allowDesktopPlacement: true,
|
|
|
|
|
allowStatusBarPlacement: false,
|
|
|
|
|
resizeMode: PluginDesktopComponentResizeMode.Free,
|
|
|
|
|
cornerRadiusResolver: cellSize => Math.Clamp(cellSize * 0.28, 14, 22)));
|
2026-03-09 12:27:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2026-03-09 14:14:50 +08:00
|
|
|
_clockService?.Dispose();
|
|
|
|
|
_clockService = null;
|
|
|
|
|
_stateService = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string GetHostProperty(IPluginContext context, string key, string fallback)
|
|
|
|
|
{
|
|
|
|
|
return context.TryGetProperty<string>(key, out var value) && !string.IsNullOrWhiteSpace(value)
|
|
|
|
|
? value
|
|
|
|
|
: fallback;
|
2026-03-09 12:27:33 +08:00
|
|
|
}
|
|
|
|
|
}
|