feat(ui): add About modal opened from Help menu

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mika Kuns
2026-04-28 09:25:34 +02:00
parent bca8c9e4cb
commit 618235d8ed
6 changed files with 113 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ using ClaudeDo.Data;
using ClaudeDo.Data.Models;
using ClaudeDo.Ui.Services;
using ClaudeDo.Ui.ViewModels.Islands;
using ClaudeDo.Ui.ViewModels.Modals;
using ClaudeDo.Ui.ViewModels.Planning;
using Microsoft.EntityFrameworkCore;
@@ -35,6 +36,9 @@ public sealed partial class IslandsShellViewModel : ViewModelBase
// Set by MainWindow to open the conflict resolution dialog.
public Func<ConflictResolutionViewModel, Task>? ShowConflictDialog { get; set; }
// Set by MainWindow to open the About dialog.
public Func<AboutModalViewModel, Task>? ShowAboutModal { get; set; }
[ObservableProperty] private bool _isUpdateBannerVisible;
[ObservableProperty] private string? _updateBannerLatestVersion;
[ObservableProperty] private string? _inlineUpdateStatus;
@@ -222,6 +226,13 @@ public sealed partial class IslandsShellViewModel : ViewModelBase
if (InlineUpdateStatus == text) InlineUpdateStatus = null;
}
[RelayCommand]
private async Task OpenAbout()
{
var vm = new AboutModalViewModel();
if (ShowAboutModal is not null) await ShowAboutModal(vm);
}
[RelayCommand]
private async Task CheckForUpdatesAsync()
{

View File

@@ -0,0 +1,34 @@
using System.Diagnostics;
using System.IO;
using System.Reflection;
using ClaudeDo.Data;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace ClaudeDo.Ui.ViewModels.Modals;
public sealed partial class AboutModalViewModel : ViewModelBase
{
public string AppVersion { get; } =
Assembly.GetExecutingAssembly().GetName().Version?.ToString(3) ?? "0.0.0";
public string DataFolderPath { get; } = Paths.AppDataRoot();
public string LogsFolderPath { get; } = Path.Combine(Paths.AppDataRoot(), "logs");
public string WorkerConfigPath { get; } = Path.Combine(Paths.AppDataRoot(), "worker.config.json");
public Action? CloseAction { get; set; }
[RelayCommand] private void Close() => CloseAction?.Invoke();
[RelayCommand]
private void OpenPath(string? path)
{
if (string.IsNullOrWhiteSpace(path)) return;
try
{
var target = File.Exists(path) ? path : (Directory.Exists(path) ? path : null);
if (target is null) return;
Process.Start(new ProcessStartInfo("explorer.exe", $"\"{target}\"") { UseShellExecute = true });
}
catch { /* ignore */ }
}
}