diff options
20 files changed, 270 insertions, 57 deletions
@@ -16,3 +16,9 @@ obj/** ######################## **/.Temp/ **/.temp/ + +################### +### DotSettings ### +################### +*.DotSettings.* +*.user diff --git a/CommandLineWrapper/Constants.cs b/CommandLineWrapper/Constants.cs index 91d0bd8..cf03242 100644 --- a/CommandLineWrapper/Constants.cs +++ b/CommandLineWrapper/Constants.cs @@ -3,7 +3,7 @@ namespace CommandLineWrapper; public static class Constants { // Command line program path - public static FileInfo CommandLinePath => new FileInfo( + public static FileInfo CommandLinePath => new( Path.Combine(AppDomain.CurrentDomain.BaseDirectory, OperatingSystem.IsWindows() ? "JustEnoughVCS.exe" : "JustEnoughVCS") ); diff --git a/CommandLineWrapper/JVCSCommandInvoker.cs b/CommandLineWrapper/JVCSCommandInvoker.cs index 56d67ca..3d4e594 100644 --- a/CommandLineWrapper/JVCSCommandInvoker.cs +++ b/CommandLineWrapper/JVCSCommandInvoker.cs @@ -1,5 +1,6 @@ using System.Diagnostics; -using CommandLineWrapper; + +namespace CommandLineWrapper; public static class JVCSCommandInvoker { @@ -25,17 +26,16 @@ public static class JVCSCommandInvoker if (!string.IsNullOrEmpty(workingDirectory)) startInfo.WorkingDirectory = workingDirectory; - using (var process = new Process { StartInfo = startInfo }) - { - process.Start(); - string output = await process.StandardOutput.ReadToEndAsync(); - await process.WaitForExitAsync(); + using var process = new Process(); + process.StartInfo = startInfo; + process.Start(); + string output = await process.StandardOutput.ReadToEndAsync(); + await process.WaitForExitAsync(); - return new InvokeResult - { - ExitCode = process.ExitCode, - StandardOutput = output.Trim() - }; - } + return new InvokeResult + { + ExitCode = process.ExitCode, + StandardOutput = output.Trim() + }; } -} +}
\ No newline at end of file diff --git a/CommandLineWrapper/JVCSWorkspace.cs b/CommandLineWrapper/JVCSWorkspace.cs index d88209c..8afd212 100644 --- a/CommandLineWrapper/JVCSWorkspace.cs +++ b/CommandLineWrapper/JVCSWorkspace.cs @@ -1,10 +1,12 @@ -using CommandLineWrapper; +namespace CommandLineWrapper; public class JVCSWorkspace { public string WorkspaceDirectory => _workspaceDirectory ?? Directory.GetCurrentDirectory(); + public bool SuccessInitialized => _successInitialized; private string? _workspaceDirectory; + private bool _successInitialized; public async Task InitializeAsync(string directory) { @@ -17,15 +19,18 @@ public class JVCSWorkspace var currentWorkspace = result.StandardOutput; // Check if the obtained workspace directory is valid (not empty and exists) - if (string.IsNullOrWhiteSpace(currentWorkspace) && + if (!string.IsNullOrWhiteSpace(currentWorkspace) && Directory.Exists(currentWorkspace)) { _workspaceDirectory = currentWorkspace; + _successInitialized = true; } else { // If the workspace is invalid, initialize a new workspace - await JVCSCommandInvoker.Invoke(Constants.CommandParameterGenerator.Initialize()); + result = await JVCSCommandInvoker.Invoke(Constants.CommandParameterGenerator.Initialize(), directory); + if (result.ExitCode == 0) + _successInitialized = true; } } } diff --git a/CommandLineWrapper/JsonResults/Implements/AccountListResult.cs b/CommandLineWrapper/JsonResults/Implements/AccountListResult.cs index 600b839..c6242ff 100644 --- a/CommandLineWrapper/JsonResults/Implements/AccountListResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/AccountListResult.cs @@ -1,5 +1,4 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; public class AccountListResultGetter : JsonResultGetter<AccountListResult> { @@ -15,4 +14,4 @@ public struct AccountListResult public struct AccountItem { public bool HasPrivateKey { get; set; } -} +}
\ No newline at end of file diff --git a/CommandLineWrapper/JsonResults/Implements/HereResult.cs b/CommandLineWrapper/JsonResults/Implements/HereResult.cs index b3086a1..497d6c2 100644 --- a/CommandLineWrapper/JsonResults/Implements/HereResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/HereResult.cs @@ -1,5 +1,4 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; public class HereResultGetter : JsonResultGetter<HereResult> { @@ -8,6 +7,9 @@ public class HereResultGetter : JsonResultGetter<HereResult> public HereResultGetter(DirectoryInfo currentDirectory) => _currentDirectory = currentDirectory; + public void ChangeDirectory(DirectoryInfo directory) + => _currentDirectory = directory; + protected override Task<JVCSCommandInvoker.InvokeResult> ExecCommand(JVCSWorkspace workspace) => JVCSCommandInvoker.Invoke(Constants.CommandParameterGenerator.Here(), _currentDirectory.ToString()); } @@ -27,4 +29,4 @@ public struct HereResultItem public bool Exist { get; set; } public bool Modified { get; set; } public string Holder { get; set; } -} +}
\ No newline at end of file diff --git a/CommandLineWrapper/JsonResults/Implements/InfoResult.cs b/CommandLineWrapper/JsonResults/Implements/InfoResult.cs index ecef724..1a3d11e 100644 --- a/CommandLineWrapper/JsonResults/Implements/InfoResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/InfoResult.cs @@ -1,5 +1,4 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; public class InfoResultGetter : JsonResultGetter<InfoResult> { @@ -8,6 +7,9 @@ public class InfoResultGetter : JsonResultGetter<InfoResult> public InfoResultGetter(string mappingName) => _mappingName = mappingName; + public void ChangeMappingName(string mappingName) + => _mappingName = mappingName; + protected override Task<JVCSCommandInvoker.InvokeResult> ExecCommand(JVCSWorkspace workspace) => workspace.Info(_mappingName); } diff --git a/CommandLineWrapper/JsonResults/Implements/ShareListResult.cs b/CommandLineWrapper/JsonResults/Implements/ShareListResult.cs index 4736b81..f309f8c 100644 --- a/CommandLineWrapper/JsonResults/Implements/ShareListResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/ShareListResult.cs @@ -1,5 +1,4 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; public class ShareListResultGetter : JsonResultGetter<ShareListResult> { @@ -18,4 +17,4 @@ public struct ShareItem public string Sharer { get; set; } public string Description { get; set; } public int FileCount { get; set; } -} +}
\ No newline at end of file diff --git a/CommandLineWrapper/JsonResults/Implements/ShareSeeResult.cs b/CommandLineWrapper/JsonResults/Implements/ShareSeeResult.cs index c965b25..0fc63ee 100644 --- a/CommandLineWrapper/JsonResults/Implements/ShareSeeResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/ShareSeeResult.cs @@ -1,7 +1,7 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; using System.Text.Json.Serialization; +namespace CommandLineWrapper.JsonResults.Implements; + public class ShareSeeResultGetter : JsonResultGetter<SeeShareResult> { private string _shareId; @@ -9,6 +9,9 @@ public class ShareSeeResultGetter : JsonResultGetter<SeeShareResult> public ShareSeeResultGetter(string shareId) => _shareId = shareId; + public void ChangeShareId(string shareId) + => _shareId = shareId; + protected override Task<JVCSCommandInvoker.InvokeResult> ExecCommand(JVCSWorkspace workspace) => workspace.ShareSee(_shareId); } diff --git a/CommandLineWrapper/JsonResults/Implements/SheetAlignTasksResult.cs b/CommandLineWrapper/JsonResults/Implements/SheetAlignTasksResult.cs index 5539d19..60d07f3 100644 --- a/CommandLineWrapper/JsonResults/Implements/SheetAlignTasksResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/SheetAlignTasksResult.cs @@ -1,13 +1,12 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; -public class SheetAlignTasksResultGetter : JsonResultGetter<AlignJsonResult> +public class SheetAlignTasksResultGetter : JsonResultGetter<AlignResult> { protected override Task<JVCSCommandInvoker.InvokeResult> ExecCommand(JVCSWorkspace workspace) => workspace.SheetAlignList(); } -public struct AlignJsonResult +public struct AlignResult { public Dictionary<string, AlignTaskMapping> AlignTasks { get; set; } } @@ -16,4 +15,4 @@ public struct AlignTaskMapping { public string LocalMapping { get; set; } public string RemoteMapping { get; set; } -} +}
\ No newline at end of file diff --git a/CommandLineWrapper/JsonResults/Implements/SheetListResult.cs b/CommandLineWrapper/JsonResults/Implements/SheetListResult.cs index 1fa9f0b..eb1068d 100644 --- a/CommandLineWrapper/JsonResults/Implements/SheetListResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/SheetListResult.cs @@ -1,5 +1,4 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; public class SheetListResultGetter : JsonResultGetter<SheetListResult> { @@ -23,4 +22,4 @@ public struct SheetItem { public string Name { get; set; } public string Holder { get; set; } -} +}
\ No newline at end of file diff --git a/CommandLineWrapper/JsonResults/Implements/StatusResult.cs b/CommandLineWrapper/JsonResults/Implements/StatusResult.cs index aba2c25..6b52731 100644 --- a/CommandLineWrapper/JsonResults/Implements/StatusResult.cs +++ b/CommandLineWrapper/JsonResults/Implements/StatusResult.cs @@ -1,5 +1,4 @@ -using CommandLineWrapper; -using CommandLineWrapper.JsonResults; +namespace CommandLineWrapper.JsonResults.Implements; public class StatusResultGetter : JsonResultGetter<StatusResult> { diff --git a/CommandLineWrapper/JsonResults/JsonResultGetter.cs b/CommandLineWrapper/JsonResults/JsonResultGetter.cs index e1bf607..2afd10c 100644 --- a/CommandLineWrapper/JsonResults/JsonResultGetter.cs +++ b/CommandLineWrapper/JsonResults/JsonResultGetter.cs @@ -1,10 +1,8 @@ -using static JVCSCommandInvoker; - namespace CommandLineWrapper.JsonResults { public abstract class JsonResultGetter<TJsonFormat> { - protected abstract Task<InvokeResult> ExecCommand(JVCSWorkspace workspace); + protected abstract Task<JVCSCommandInvoker.InvokeResult> ExecCommand(JVCSWorkspace workspace); public async Task<TJsonFormat?> Get(JVCSWorkspace workspace) { diff --git a/CommandLineWrapper/WorkspaceCommandGenerator/Program.cs b/CommandLineWrapper/WorkspaceCommandGenerator/Program.cs index e0bf373..1840066 100644 --- a/CommandLineWrapper/WorkspaceCommandGenerator/Program.cs +++ b/CommandLineWrapper/WorkspaceCommandGenerator/Program.cs @@ -1,7 +1,7 @@ using System.Text; using System.Text.RegularExpressions; -namespace CommandLineWrapper.CodeGenerator +namespace CommandLineWrapper.WorkspaceCommandGenerator { class Program { @@ -114,7 +114,7 @@ namespace CommandLineWrapper.CodeGenerator var sb = new StringBuilder(); // Add using statements and namespace - sb.AppendLine("using static JVCSCommandInvoker;"); + sb.AppendLine("using static CommandLineWrapper.JVCSCommandInvoker;"); sb.AppendLine(); sb.AppendLine("namespace CommandLineWrapper"); sb.AppendLine("{"); diff --git a/CommandLineWrapperExample/Program.cs b/CommandLineWrapperExample/Program.cs index 0d9ecdf..6c0e587 100644 --- a/CommandLineWrapperExample/Program.cs +++ b/CommandLineWrapperExample/Program.cs @@ -1,6 +1,8 @@ using CommandLineWrapper; -internal class Program +namespace CommandLineWrapperExample; + +internal abstract class Program { private static string currentDirectory = "/.Temp/Current/"; private static string CorrectCurrentDirectory() @@ -20,4 +22,4 @@ internal class Program var workspace = new JVCSWorkspace(); await workspace.InitializeAsync(current); } -} +}
\ No newline at end of file diff --git a/JVDesktop/JVDesktop.csproj b/JVDesktop/JVDesktop.csproj index 2940b03..67d341c 100644 --- a/JVDesktop/JVDesktop.csproj +++ b/JVDesktop/JVDesktop.csproj @@ -8,7 +8,7 @@ <AvaloniaUseCompiledBindingsByDefault >true</AvaloniaUseCompiledBindingsByDefault> <BaseOutputPath>..\.Temp\Debug\</BaseOutputPath> - <OutDir>$(OutputPath)</OutDir> + <OutputPath>..\.Temp\Debug\</OutputPath> <AppendTargetFrameworkToOutputPath >false</AppendTargetFrameworkToOutputPath> <AppendRuntimeIdentifierToOutputPath @@ -33,6 +33,7 @@ >All</PrivateAssets> </PackageReference> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" /> + <PackageReference Include="ReactiveUI" Version="22.3.1" /> </ItemGroup> <ItemGroup> diff --git a/JVDesktop/Program.cs b/JVDesktop/Program.cs index 850598c..75068c2 100644 --- a/JVDesktop/Program.cs +++ b/JVDesktop/Program.cs @@ -3,13 +3,13 @@ using System; namespace JVDesktop; -sealed class Program +static class Program { [STAThread] public static void Main(string[] args) => BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); - public static AppBuilder BuildAvaloniaApp() + private static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>() .UsePlatformDetect() .WithInterFont() diff --git a/JVDesktop/ViewModels/DashboardViewModel.cs b/JVDesktop/ViewModels/DashboardViewModel.cs index 5ae7d95..9371ddd 100644 --- a/JVDesktop/ViewModels/DashboardViewModel.cs +++ b/JVDesktop/ViewModels/DashboardViewModel.cs @@ -1,15 +1,173 @@ -using System; +using System.IO; +using System.Threading.Tasks; +using CommandLineWrapper; +using CommandLineWrapper.JsonResults.Implements; +using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace JVDesktop.ViewModels; public partial class DashboardViewModel : ViewModel { - public string Greeting => "Welcome to Avalonia!"; + // Getters + private StatusResultGetter? _statusResultGetter; + private InfoResultGetter? _infoResultGetter; + private AccountListResultGetter? _accountListResultGetter; + private HereResultGetter? _hereResultGetter; + private ShareListResultGetter? _shareListResultGetter; + private ShareSeeResultGetter? _shareSeeResultGetter; + private SheetAlignTasksResultGetter? _sheetAlignTasksResultGetter; + private SheetListResultGetter? _sheetListResultGetter; - [RelayCommand] - private void ButtonClick() + /// <summary> + /// Workspace object + /// </summary> + [ObservableProperty] + private JVCSWorkspace? _workspace; + + /// <summary> + /// If the workspace object exists, it proves the workspace is initialized + /// </summary> + public bool WorkspaceInitialized => Workspace != null; + + /// <summary> + /// Current workspace directory + /// </summary> + [ObservableProperty] + private string _currentWorkspaceDirectory = ""; + + /// <summary> + /// Currently used account + /// </summary> + [ObservableProperty] + private string _currentAccount = "unknown"; + + /// <summary> + /// Whether HOST mode is currently enabled + /// </summary> + [ObservableProperty] + private bool? _hostMode; + + /// <summary> + /// Currently used structure sheet (empty means no sheet is used) + /// </summary> + [ObservableProperty] + private string? _currentSheet; + + /// <summary> + /// Upstream of the current workspace + /// </summary> + [ObservableProperty] + private string _currentUpstream = "127.0.0.1"; + + /// <summary> + /// Result from the last alignment check + /// </summary> + [ObservableProperty] + private AlignResult? _alignResult; + + /// <summary> + /// Result from the last current directory information collection + /// </summary> + [ObservableProperty] + private HereResult? _hereResult; + + /// <summary> + /// Result from the last change status collection + /// </summary> + [ObservableProperty] + private StatusResult? _statusResult; + + /// <summary> + /// Result from the last sheet detection + /// </summary> + [ObservableProperty] + private SheetListResult? _sheetListResult; + + /// <summary> + /// Result from the last account detection + /// </summary> + [ObservableProperty] + private AccountListResult? _accountListResult; + + /// <summary> + /// Triggered when the workspace changes + /// </summary> + partial void OnWorkspaceChanged(JVCSWorkspace? value) { - Console.WriteLine("Button clicked"); + // Update workspace initialization status + OnPropertyChanged(nameof(WorkspaceInitialized)); + + // Clear status + if (value == null) + { + StatusClean(); + return; + } + + // Initial load + _ = ReloadFromWorkspace(value); + } + + /// <summary> + /// Clear status + /// </summary> + private void StatusClean() + { + CurrentWorkspaceDirectory = ""; + CurrentAccount = "unknown"; + HostMode = null; + CurrentSheet = null; + CurrentUpstream = "127.0.0.1"; + AlignResult = null; + HereResult = null; + StatusResult = null; + SheetListResult = null; + } + + /// <summary> + /// Load status from the workspace object + /// </summary> + /// <param name="workspace"> Workspace </param> + private async Task ReloadFromWorkspace(JVCSWorkspace workspace) + { + InitializeGetters(workspace); + + var alignTask = _sheetAlignTasksResultGetter?.Get(workspace)!; + var hereTask = _hereResultGetter?.Get(workspace)!; + var statusTask = _statusResultGetter?.Get(workspace)!; + var sheetListTask = _sheetListResultGetter?.Get(workspace)!; + var accountListTask = _accountListResultGetter?.Get(workspace)!; + + await Task.WhenAll(alignTask, hereTask, statusTask, sheetListTask, accountListTask); + + AlignResult = await alignTask; + HereResult = await hereTask; + StatusResult = await statusTask; + SheetListResult = await sheetListTask; + AccountListResult = await accountListTask; + } + + /// <summary> + /// Initializes all getters if they are null. + /// </summary> + /// <param name="workspace"> Workspace </param> + private void InitializeGetters(JVCSWorkspace workspace) + { + if (Workspace == null) + return; + + var workspaceDirectory = ""; + if (Workspace.SuccessInitialized) + workspaceDirectory = Workspace.WorkspaceDirectory; + + _statusResultGetter ??= new StatusResultGetter(); + _infoResultGetter ??= new InfoResultGetter(""); + _accountListResultGetter ??= new AccountListResultGetter(); + _hereResultGetter ??= new HereResultGetter(new DirectoryInfo(workspaceDirectory)); + _shareListResultGetter ??= new ShareListResultGetter(); + _shareSeeResultGetter ??= new ShareSeeResultGetter(""); + _sheetAlignTasksResultGetter ??= new SheetAlignTasksResultGetter(); + _sheetListResultGetter ??= new SheetListResultGetter(); } } diff --git a/JVDesktop/Views/DashboardView.axaml b/JVDesktop/Views/DashboardView.axaml index 553754f..1f0a0c4 100644 --- a/JVDesktop/Views/DashboardView.axaml +++ b/JVDesktop/Views/DashboardView.axaml @@ -38,13 +38,13 @@ <Border Grid.Row="1" Background="Black"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock - Text="{Binding Greeting}" + Text="{Binding WorkspaceInitialized}" HorizontalAlignment="Center" VerticalAlignment="Center" /> <Button Content="Click" - Command="{Binding ButtonClickCommand}" + Click="SetupWorkspace" Margin="0,10,0,0" /> </StackPanel> diff --git a/JVDesktop/Views/DashboardView.axaml.cs b/JVDesktop/Views/DashboardView.axaml.cs index ae58263..42e65f9 100644 --- a/JVDesktop/Views/DashboardView.axaml.cs +++ b/JVDesktop/Views/DashboardView.axaml.cs @@ -1,5 +1,12 @@ +using System; +using System.IO; +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Platform.Storage; +using CommandLineWrapper; +using JVDesktop.ViewModels; namespace JVDesktop.Views; @@ -12,4 +19,38 @@ public partial class DashboardView : Window if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) BeginMoveDrag(e); } + + /// <summary> + /// Select and setup workspace + /// </summary> + private async void SetupWorkspace(object? sender, RoutedEventArgs routedEventArgs) + { + var topLevel = GetTopLevel(this); + if (topLevel == null) return; + + var storageProvider = topLevel.StorageProvider; + + var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions + { + Title = "Select JustEnoughVCS Workspace", + AllowMultiple = false + }); + + if (result.Count > 0) + { + var selectedFolder = result[0]; + var folderPath = selectedFolder.Path.LocalPath; + + if (Directory.Exists(folderPath)) + { + var workspace = new JVCSWorkspace(); + await workspace.InitializeAsync(folderPath); + if (workspace.SuccessInitialized) + { + if (DataContext is DashboardViewModel viewModel) + viewModel.Workspace = workspace; + } + } + } + } } |
