Initial commit

This commit is contained in:
2026-07-03 16:31:37 +07:00
commit 899c7c637d
1939 changed files with 641750 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using RobotNet10.Components.Clients;
using RobotNet10.ScriptEngine.Shared;
namespace RobotNet10.ScriptEditor.Clients;
/// <summary>
/// SignalR HubClient for FileManagerHub - handles file management operations.
/// Note: Events are only triggered when other clients perform actions through Hub methods,
/// not from FileManager class directly (FileManager doesn't have HubContext).
/// </summary>
public class FileManagerHubClient : HubClient
{
/// <summary>
/// Triggered when edit permission is revoked (sent to the previous connection).
/// </summary>
public event Action<string?>? EditPermissionRevoked;
/// <summary>
/// Triggered when another client saves a file.
/// </summary>
public event Action<string, string?>? FileSaved;
/// <summary>
/// Triggered when another client creates a file.
/// </summary>
public event Action<string, string?>? FileCreated;
/// <summary>
/// Triggered when another client creates a folder.
/// </summary>
public event Action<string, string?>? FolderCreated;
/// <summary>
/// Triggered when another client deletes a file.
/// </summary>
public event Action<string, string?>? FileDeleted;
/// <summary>
/// Triggered when another client deletes a folder.
/// </summary>
public event Action<string, string?>? FolderDeleted;
/// <summary>
/// Triggered when any client creates a backup.
/// </summary>
public event Action<string, string?>? BackupCreated;
/// <summary>
/// Triggered when any client restores a backup.
/// </summary>
public event Action<string, string?>? BackupRestored;
/// <summary>
/// Triggered when any client deletes a backup.
/// </summary>
public event Action<string, string?>? BackupDeleted;
public FileManagerHubClient(NavigationManager navigationManager)
: base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptFileManagerHubPath))
{
Connection.On<string?>("EditPermissionRevoked", userId => EditPermissionRevoked?.Invoke(userId));
Connection.On<string, string?>("FileSaved", (path, userId) => FileSaved?.Invoke(path, userId));
Connection.On<string, string?>("FileCreated", (path, userId) => FileCreated?.Invoke(path, userId));
Connection.On<string, string?>("FolderCreated", (path, userId) => FolderCreated?.Invoke(path, userId));
Connection.On<string, string?>("FileDeleted", (path, userId) => FileDeleted?.Invoke(path, userId));
Connection.On<string, string?>("FolderDeleted", (path, userId) => FolderDeleted?.Invoke(path, userId));
Connection.On<string, string?>("BackupCreated", (fileName, userId) => BackupCreated?.Invoke(fileName, userId));
Connection.On<string, string?>("BackupRestored", (fileName, userId) => BackupRestored?.Invoke(fileName, userId));
Connection.On<string, string?>("BackupDeleted", (fileName, userId) => BackupDeleted?.Invoke(fileName, userId));
// Request edit permission when reconnected
// This will always succeed and force out any previous connection
Connection.Reconnected += async _ =>
{
if (IsConnected)
{
try
{
await RequestEditPermissionAsync();
}
catch (Exception)
{
// Ignore errors - permission request should always succeed
}
}
};
}
public override async Task StartAsync()
{
await base.StartAsync();
// Automatically request edit permission when connected
// This will always succeed and force out any previous connection
if (IsConnected)
{
try
{
await RequestEditPermissionAsync();
}
catch (Exception)
{
// Ignore errors - permission request should always succeed
}
}
}
/// <summary>
/// Gets the root folder structure with all files and folders.
/// </summary>
public Task<ScriptFolderDto> GetRootFolderAsync() => Connection.InvokeAsync<ScriptFolderDto>("GetRootFolder");
/// <summary>
/// Gets the current state of the FileManager.
/// </summary>
public Task<ScriptEngineState> GetStateAsync() => Connection.InvokeAsync<ScriptEngineState>("GetState");
/// <summary>
/// Requests edit permission. If another connection has permission, it will be revoked and notified.
/// </summary>
public Task<bool> RequestEditPermissionAsync() => Connection.InvokeAsync<bool>("RequestEditPermission");
/// <summary>
/// Revokes edit permission for the current connection.
/// </summary>
public Task RevokeEditPermissionAsync() => Connection.InvokeAsync("RevokeEditPermission");
/// <summary>
/// Checks if the current connection has edit permission.
/// </summary>
public Task<bool> HasEditPermissionAsync() => Connection.InvokeAsync<bool>("HasEditPermission");
/// <summary>
/// Saves file content.
/// </summary>
public Task SaveFileAsync(string relativePath, string content) => Connection.InvokeAsync("SaveFile", relativePath, content);
/// <summary>
/// Creates a new file.
/// </summary>
public Task CreateFileAsync(string relativePath, string content) => Connection.InvokeAsync("CreateFile", relativePath, content);
/// <summary>
/// Creates a new folder.
/// </summary>
public Task CreateFolderAsync(string relativePath) => Connection.InvokeAsync("CreateFolder", relativePath);
/// <summary>
/// Deletes a file.
/// </summary>
public Task DeleteFileAsync(string relativePath) => Connection.InvokeAsync("DeleteFile", relativePath);
/// <summary>
/// Deletes a folder.
/// </summary>
public Task DeleteFolderAsync(string relativePath) => Connection.InvokeAsync("DeleteFolder", relativePath);
/// <summary>
/// Creates a backup of all scripts.
/// </summary>
public Task<string> CreateBackupAsync(string? backupName = null) => Connection.InvokeAsync<string>("CreateBackup", backupName);
/// <summary>
/// Lists available backup files.
/// </summary>
public Task<ScriptBackupInfo[]> ListBackupsAsync() => Connection.InvokeAsync<ScriptBackupInfo[]>("ListBackups");
/// <summary>
/// Restores scripts from a backup.
/// </summary>
public Task RestoreBackupAsync(string backupFileName, bool replaceExisting = true) =>
Connection.InvokeAsync("RestoreBackup", backupFileName, replaceExisting);
/// <summary>
/// Deletes a backup file.
/// </summary>
public Task DeleteBackupAsync(string backupFileName) => Connection.InvokeAsync("DeleteBackup", backupFileName);
}