using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.SignalR.Client; using RobotNet10.Components.Clients; using RobotNet10.ScriptEngine.Shared; namespace RobotNet10.ScriptEditor.Clients; /// /// 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). /// public class FileManagerHubClient : HubClient { /// /// Triggered when edit permission is revoked (sent to the previous connection). /// public event Action? EditPermissionRevoked; /// /// Triggered when another client saves a file. /// public event Action? FileSaved; /// /// Triggered when another client creates a file. /// public event Action? FileCreated; /// /// Triggered when another client creates a folder. /// public event Action? FolderCreated; /// /// Triggered when another client deletes a file. /// public event Action? FileDeleted; /// /// Triggered when another client deletes a folder. /// public event Action? FolderDeleted; /// /// Triggered when any client creates a backup. /// public event Action? BackupCreated; /// /// Triggered when any client restores a backup. /// public event Action? BackupRestored; /// /// Triggered when any client deletes a backup. /// public event Action? BackupDeleted; public FileManagerHubClient(NavigationManager navigationManager) : base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptFileManagerHubPath)) { Connection.On("EditPermissionRevoked", userId => EditPermissionRevoked?.Invoke(userId)); Connection.On("FileSaved", (path, userId) => FileSaved?.Invoke(path, userId)); Connection.On("FileCreated", (path, userId) => FileCreated?.Invoke(path, userId)); Connection.On("FolderCreated", (path, userId) => FolderCreated?.Invoke(path, userId)); Connection.On("FileDeleted", (path, userId) => FileDeleted?.Invoke(path, userId)); Connection.On("FolderDeleted", (path, userId) => FolderDeleted?.Invoke(path, userId)); Connection.On("BackupCreated", (fileName, userId) => BackupCreated?.Invoke(fileName, userId)); Connection.On("BackupRestored", (fileName, userId) => BackupRestored?.Invoke(fileName, userId)); Connection.On("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 } } } /// /// Gets the root folder structure with all files and folders. /// public Task GetRootFolderAsync() => Connection.InvokeAsync("GetRootFolder"); /// /// Gets the current state of the FileManager. /// public Task GetStateAsync() => Connection.InvokeAsync("GetState"); /// /// Requests edit permission. If another connection has permission, it will be revoked and notified. /// public Task RequestEditPermissionAsync() => Connection.InvokeAsync("RequestEditPermission"); /// /// Revokes edit permission for the current connection. /// public Task RevokeEditPermissionAsync() => Connection.InvokeAsync("RevokeEditPermission"); /// /// Checks if the current connection has edit permission. /// public Task HasEditPermissionAsync() => Connection.InvokeAsync("HasEditPermission"); /// /// Saves file content. /// public Task SaveFileAsync(string relativePath, string content) => Connection.InvokeAsync("SaveFile", relativePath, content); /// /// Creates a new file. /// public Task CreateFileAsync(string relativePath, string content) => Connection.InvokeAsync("CreateFile", relativePath, content); /// /// Creates a new folder. /// public Task CreateFolderAsync(string relativePath) => Connection.InvokeAsync("CreateFolder", relativePath); /// /// Deletes a file. /// public Task DeleteFileAsync(string relativePath) => Connection.InvokeAsync("DeleteFile", relativePath); /// /// Deletes a folder. /// public Task DeleteFolderAsync(string relativePath) => Connection.InvokeAsync("DeleteFolder", relativePath); /// /// Creates a backup of all scripts. /// public Task CreateBackupAsync(string? backupName = null) => Connection.InvokeAsync("CreateBackup", backupName); /// /// Lists available backup files. /// public Task ListBackupsAsync() => Connection.InvokeAsync("ListBackups"); /// /// Restores scripts from a backup. /// public Task RestoreBackupAsync(string backupFileName, bool replaceExisting = true) => Connection.InvokeAsync("RestoreBackup", backupFileName, replaceExisting); /// /// Deletes a backup file. /// public Task DeleteBackupAsync(string backupFileName) => Connection.InvokeAsync("DeleteBackup", backupFileName); }