singal undoredo state to other clients

This commit is contained in:
beo3000 2025-11-11 20:26:46 +01:00
parent 0df393812a
commit b9758b0497
9 changed files with 148 additions and 95 deletions

View File

@ -17,6 +17,8 @@ namespace KoogleApp.Hub
{
private readonly IGameStatusDataService _dataService;
private readonly AuthenticationStateProvider _authenticationStateProvider;
private readonly ILogger<SharedModelHub> _logger;
//private HubConnection _hubConnection;
//public async Task UpdateText(string newText)
@ -25,89 +27,91 @@ namespace KoogleApp.Hub
//}
public SharedModelHub(IGameStatusDataService dataService, NavigationManager navigationManager,
AuthenticationStateProvider authenticationStateProvider)
AuthenticationStateProvider authenticationStateProvider,
ILogger<SharedModelHub> logger)
{
_dataService = dataService;
_authenticationStateProvider = authenticationStateProvider;
_logger = logger;
}
public async Task UpdateThrowPanelState(ThrowPanelState panelState, string username)
{
await Clients.All.SendAsync("UpdateThrowPanelState", panelState);
}
//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();
//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
};
// var changeEvent = new DataChangeEvent
// {
// Content = content,
// Username = currentData.LastModifiedBy,
// Timestamp = currentData.LastModified,
// Version = currentData.Version
// };
await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
await BroadcastUndoRedoState();
}
// await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
// await BroadcastUndoRedoState();
//}
public async Task RequestUndo(string username)
{
var success = _dataService.Undo();
//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
};
// 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();
}
}
// await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
// await BroadcastUndoRedoState();
// }
//}
public async Task RequestRedo(string username)
{
var success = _dataService.Redo();
//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
};
// 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();
}
}
// await Clients.All.SendAsync("ReceiveDataUpdate", changeEvent);
// await BroadcastUndoRedoState();
// }
//}
public async Task GetUndoRedoState()
{
await BroadcastUndoRedoState();
}
//public async Task GetUndoRedoState()
//{
// await BroadcastUndoRedoState();
//}
private async Task BroadcastUndoRedoState()
{
var state = new UndoRedoState
{
CanUndo = _dataService.CanUndo(),
CanRedo = _dataService.CanRedo()
};
//private async Task BroadcastUndoRedoState()
//{
// var state = new UndoRedoState
// {
// CanUndo = _dataService.CanUndo(),
// CanRedo = _dataService.CanRedo()
// };
await Clients.All.SendAsync("UpdateUndoRedoState", state);
}
// await Clients.All.SendAsync("UpdateUndoRedoState", state);
//}
public override async Task OnConnectedAsync()
{
@ -120,12 +124,6 @@ namespace KoogleApp.Hub
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);
@ -137,7 +135,20 @@ namespace KoogleApp.Hub
}
catch (Exception ex)
{
//_logger.LogError(ex, "Failed to add activity");
_logger.LogError(ex, "Failed to BroadcastThrowPanelState");
// Optional: Error-Handling Action dispatchen
}
}
public async Task BroadcastUndoRedoState(UndoRedoState state, IDispatcher dispatcher)
{
try
{
await Clients.Others.SendAsync("ReceiveUndoRedoState", state);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to BroadcastThrowPanelState");
// Optional: Error-Handling Action dispatchen
}
}

View File

@ -1,5 +1,6 @@
using Fluxor;
using KoogleApp.Store.Game.ThrowPanel;
using KoogleApp.Store.Game.UndoRedo;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.SignalR.Client;
@ -12,12 +13,15 @@ namespace KoogleApp.Services
private readonly AuthenticationStateProvider _authenticationStateProvider;
private HubConnection? _hubConnection;
private string? _userName;
private readonly ILogger<HubConnectionService> _logger;
public HubConnectionService(NavigationManager navigationManager,
AuthenticationStateProvider authenticationStateProvider)
AuthenticationStateProvider authenticationStateProvider,
ILogger<HubConnectionService> logger)
{
_navigationManager = navigationManager;
_authenticationStateProvider = authenticationStateProvider;
_logger = logger;
}
public HubConnection Connection => _hubConnection
@ -43,26 +47,24 @@ namespace KoogleApp.Services
.Build();
_hubConnection.On<ThrowPanelState>("ReceiveThrowPanelState", state =>
{
dispatcher.Dispatch(new ReceiveStateFromServerAction(state));
dispatcher.Dispatch(new ReceiveThrowPanelStateFromServerAction(state));
});
// _hubConnection.On<string>("ReceiveTextUpdate", (newText) =>
// {
// _sharedText = newText;
// InvokeAsync(StateHasChanged);
// });
_hubConnection.On<UndoRedoState>("ReceiveUndoRedoState", (state) =>
{
dispatcher.Dispatch(new ReceiveUndoRedoStateFromServerAction(state));
});
await _hubConnection.StartAsync();
}
public async Task HandelBroadcastThrowPanelStateAction(BroadcastThrowPanelStateAction action, IDispatcher dispatcher)
public async Task BroadcastThrowPanelState(ThrowPanelState state, IDispatcher dispatcher)
{
if (_hubConnection?.State != HubConnectionState.Connected)
{
//_logger.LogWarning("Cannot add activity: not connected");
_logger.LogWarning("Cannot BroadcastThrowPanelState: not connected");
return;
}
@ -70,7 +72,7 @@ namespace KoogleApp.Services
{
if (_hubConnection is not null)
{
await _hubConnection.SendAsync("BroadcastThrowPanelState", action.State);
await _hubConnection.SendAsync("BroadcastThrowPanelState", state);
}
//await Clients.Others.SendAsync("ReceiveThrowPanelState", new ThrowPanelState());
@ -82,7 +84,29 @@ namespace KoogleApp.Services
}
catch (Exception ex)
{
//_logger.LogError(ex, "Failed to add activity");
_logger.LogError(ex, "Failed to BroadcastThrowPanelState");
// Optional: Error-Handling Action dispatchen
}
}
public async Task BroadcastUndoRedoState(UndoRedoState state, IDispatcher dispatcher)
{
if (_hubConnection?.State != HubConnectionState.Connected)
{
_logger.LogWarning("Cannot BroadcastUndoRedoState: not connected");
return;
}
try
{
if (_hubConnection is not null)
{
await _hubConnection.SendAsync("BroadcastUndoRedoState", state);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to BroadcastUndoRedoState");
// Optional: Error-Handling Action dispatchen
}
}

View File

@ -14,7 +14,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
public record UpdatePinStateByNumberAction(int Number);
public record ReceiveStateFromServerAction(ThrowPanelState State);
public record ReceiveThrowPanelStateFromServerAction(ThrowPanelState State);
public record LoadStateFromSessionAction();

View File

@ -227,7 +227,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
[EffectMethod]
public async Task HandelBroadcastThrowPanelStateAction(BroadcastThrowPanelStateAction action, IDispatcher dispatcher)
{
await _sharedHubService.HandelBroadcastThrowPanelStateAction(action, dispatcher);
await _sharedHubService.BroadcastThrowPanelState(action.State, dispatcher);
}

View File

@ -5,7 +5,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
public static class ThrowPanelStateReducer
{
[ReducerMethod]
public static ThrowPanelState OnReceiveStateFromServer(ThrowPanelState state, ReceiveStateFromServerAction action)
public static ThrowPanelState OnReceiveStateFromServer(ThrowPanelState state, ReceiveThrowPanelStateFromServerAction action)
{
return action.State;
}

View File

@ -13,7 +13,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
public enum ThrowPanelStateStatus
{
undefined,
Undefined,
GameStart,
BeforeThrow,
AfterThrow,
@ -30,14 +30,9 @@ namespace KoogleApp.Store.Game.ThrowPanel
public ThrowPanelState() : this(BellValue:false, IsStated:false,
Pin1Value:false, Pin2Value:false, Pin3Value: false, Pin4Value: false, Pin5Value: false, Pin6Value: false, Pin7Value: false, Pin8Value: false, Pin9Value: false,
Pin1Disabled:false, Pin2Disabled:false, Pin3Disabled: false, Pin4Disabled: false, Pin5Disabled: false, Pin6Disabled: false, Pin7Disabled: false, Pin8Disabled: false, Pin9Disabled: false,
ThrowsPerRound : 3, ThrowCounterPerRound : 1, ThrowMode : ThrowMode.Reposition, ThrowPanelStateStatus: ThrowPanelStateStatus.undefined, ThrowCounter:0
ThrowsPerRound : 3, ThrowCounterPerRound : 1, ThrowMode : ThrowMode.Reposition, ThrowPanelStateStatus: ThrowPanelStateStatus.Undefined, ThrowCounter:0
)
{ }
}
// Actions
}

View File

@ -7,4 +7,8 @@
public record CanUndoRedoAction(bool CanUndo, bool CanRedo, int Version, DateTime ModifiedAt, string ModifiedBy);
public record UpdateUndoRedoStateAction();
public record BroadcastUndoRedoStateAction(UndoRedoState State);
public record ReceiveUndoRedoStateFromServerAction(UndoRedoState State);
}

View File

@ -65,6 +65,19 @@ namespace KoogleApp.Store.Game.UndoRedo
dispatcher.Dispatch(new CanUndoRedoAction(canUndo,canRedo, currentData.Version, currentData.LastModified, currentData.LastModifiedBy));
return Task.CompletedTask;
}
[EffectMethod]
public Task HandleCanUndoRedoAction(CanUndoRedoAction action, IDispatcher dispatcher)
{
dispatcher.Dispatch(new BroadcastUndoRedoStateAction(_state.Value));
return Task.CompletedTask;
}
[EffectMethod]
public async Task HandelBroadcastUndoRedoStateAction(BroadcastUndoRedoStateAction action, IDispatcher dispatcher)
{
await _sharedHubService.BroadcastUndoRedoState(action.State, dispatcher);
}
}
}

View File

@ -16,5 +16,11 @@ namespace KoogleApp.Store.Game.UndoRedo
IsInitialized = true
};
}
[ReducerMethod]
public static UndoRedoState OnReceiveStateFromServer(UndoRedoState state, ReceiveUndoRedoStateFromServerAction action)
{
return action.State;
}
}
}