KoogleApp/KoogleApp/Hub/SharedModelHub.cs

214 lines
6.9 KiB
C#

using Fluxor;
using KoogleApp.Model;
using KoogleApp.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.Diagnostics;
using KoogleApp.Store.Game.ThrowPanel;
namespace KoogleApp.Hub
{
public class HubConnectionService : IAsyncDisposable
{
private readonly NavigationManager _navigationManager;
private HubConnection? _hubConnection;
public HubConnectionService(NavigationManager navigationManager)
{
_navigationManager = navigationManager;
}
public HubConnection Connection => _hubConnection
?? throw new InvalidOperationException("Connection not initialized");
public async ValueTask DisposeAsync()
{
if (_hubConnection != null)
await _hubConnection.DisposeAsync();
}
public async Task ConnectToHub(IDispatcher dispatcher)
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(_navigationManager.ToAbsoluteUri("/sharedmodelhub"))
.WithAutomaticReconnect()
.Build();
_hubConnection.On<ThrowPanelState>("ReceiveThrowPanelState", state =>
{
dispatcher.Dispatch(new ReceiveStateFromServer(state));
});
// _hubConnection.On<string>("ReceiveTextUpdate", (newText) =>
// {
// _sharedText = newText;
// InvokeAsync(StateHasChanged);
// });
await _hubConnection.StartAsync();
}
public async Task HandleStartAction(StartAction action, IDispatcher dispatcher)
{
if (_hubConnection?.State != HubConnectionState.Connected)
{
//_logger.LogWarning("Cannot add activity: not connected");
return;
}
try
{
if (_hubConnection is not null)
{
await _hubConnection.SendAsync("BroadcastThrowPanelState", action.State);
}
//await Clients.Others.SendAsync("ReceiveThrowPanelState", new ThrowPanelState());
//await _hubConnection.InvokeAsync("StartAction", action);
// Der Server wird ActivityAdded an alle Clients senden,
// einschließlich diesem. Dann wird ActivityAddedAction dispatched.
}
catch (Exception ex)
{
//_logger.LogError(ex, "Failed to add activity");
// Optional: Error-Handling Action dispatchen
}
}
}
public class SharedModelHub : Microsoft.AspNetCore.SignalR.Hub
{
private readonly IGameStatusDataService _dataService;
//private HubConnection _hubConnection;
//public async Task UpdateText(string newText)
//{
// await Clients.Others.SendAsync("ReceiveTextUpdate", newText);
//}
public SharedModelHub(IGameStatusDataService dataService, NavigationManager navigationManager)
{
_dataService = dataService;
}
public async Task UpdateThrowPanelState(ThrowPanelState panelState, string username)
{
await Clients.All.SendAsync("UpdateThrowPanelState", panelState);
}
public async Task SendDataUpdate(GameStatus content, string username)
{
_dataService.UpdateData(content, username);
var currentData = _dataService.GetCurrentData();
var changeEvent = new DataChangeEvent
{
Content = content,
Username = currentData.LastModifiedBy,
Timestamp = currentData.LastModified,
Version = currentData.Version
};
await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
await BroadcastUndoRedoState();
}
public async Task RequestUndo(string username)
{
var success = _dataService.Undo();
if (success)
{
var currentData = _dataService.GetCurrentData();
var changeEvent = new DataChangeEvent
{
Content = currentData.Status,
Username = $"{username} (Undo)",
Timestamp = currentData.LastModified,
Version = currentData.Version
};
await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
await BroadcastUndoRedoState();
}
}
public async Task RequestRedo(string username)
{
var success = _dataService.Redo();
if (success)
{
var currentData = _dataService.GetCurrentData();
var changeEvent = new DataChangeEvent
{
Content = currentData.Status,
Username = $"{username} (Redo)",
Timestamp = currentData.LastModified,
Version = currentData.Version
};
await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
await BroadcastUndoRedoState();
}
}
public async Task GetUndoRedoState()
{
await BroadcastUndoRedoState();
}
private async Task BroadcastUndoRedoState()
{
var state = new UndoRedoState
{
CanUndo = _dataService.CanUndo(),
CanRedo = _dataService.CanRedo()
};
await Clients.All.SendAsync("UpdateUndoRedoState", state);
}
public override async Task OnConnectedAsync()
{
//var currentData = _dataService.GetCurrentData();
//await Clients.Caller.SendAsync("InitialData", currentData);
//await BroadcastUndoRedoState();
await base.OnConnectedAsync();
}
public async Task BroadcastThrowPanelState(ThrowPanelState state, IDispatcher dispatcher)
{
//if (_hubConnection?.State != HubConnectionState.Connected)
//{
// //_logger.LogWarning("Cannot add activity: not connected");
// return;
//}
try
{
await Clients.Others.SendAsync("ReceiveThrowPanelState", state);
//await _hubConnection.InvokeAsync("StartAction", action);
// Der Server wird ActivityAdded an alle Clients senden,
// einschließlich diesem. Dann wird ActivityAddedAction dispatched.
}
catch (Exception ex)
{
//_logger.LogError(ex, "Failed to add activity");
// Optional: Error-Handling Action dispatchen
}
}
}
}