added Board-Timer Feature
This commit is contained in:
parent
dee21d8c08
commit
6090eb849f
|
|
@ -1,8 +1,15 @@
|
|||
@using KoogleApp.Model
|
||||
@using KoogleApp.Store.Game.ThrowTimer
|
||||
|
||||
@inherits FluxorComponent
|
||||
|
||||
<ThrowTimer/>
|
||||
|
||||
<MudGrid>
|
||||
|
||||
<MudItem xs="12">
|
||||
<MudPaper Class="d-flex align-center justify-center mud-width-full py-0">
|
||||
|
||||
Tafel
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<MudText Typo="Typo.h6">Spieler</MudText>
|
||||
</MudDrawerHeader>
|
||||
|
||||
<PlayersPanel/>
|
||||
<PlayersPanel ShowMenu="false"/>
|
||||
|
||||
@code {
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,18 @@
|
|||
@inject IDialogService DialogService
|
||||
|
||||
@* @inject SharedDataService _dataService *@
|
||||
<PanelToolbar>
|
||||
<MudTooltip Text="Spieler anlegen"
|
||||
Color="Color.Primary" Placement="Placement.Bottom" Arrow="true">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Add"
|
||||
Variant="Variant.Filled" Color="Color.Primary"
|
||||
Class="mr-5" OnClick="CreatePlayerClick"/>
|
||||
</MudTooltip>
|
||||
</PanelToolbar>
|
||||
|
||||
@if (ShowMenu)
|
||||
{
|
||||
<PanelToolbar>
|
||||
<MudTooltip Text="Spieler anlegen"
|
||||
Color="Color.Primary" Placement="Placement.Bottom" Arrow="true">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Add"
|
||||
Variant="Variant.Filled" Color="Color.Primary"
|
||||
Class="mr-5" OnClick="CreatePlayerClick"/>
|
||||
</MudTooltip>
|
||||
</PanelToolbar>
|
||||
}
|
||||
|
||||
@if (PlayersState.Value != null)
|
||||
{
|
||||
|
|
@ -50,6 +54,8 @@
|
|||
|
||||
|
||||
@code {
|
||||
[Parameter] public bool ShowMenu { get; set; } = false;
|
||||
|
||||
private PlayerState _selectedValue;
|
||||
|
||||
public PlayerState? SelectedValue
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
@using KoogleApp.Model
|
||||
@using KoogleApp.Store.Game
|
||||
@using KoogleApp.Store.Game.ThrowPanel
|
||||
@using KoogleApp.Store.Game.ThrowTimer
|
||||
@using KoogleApp.Store.Game.UndoRedo
|
||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
|
|
@ -129,6 +130,7 @@
|
|||
{
|
||||
_correcting = false;
|
||||
Dispatcher.Dispatch(new ThrowAction(LeftSink: leftSink, RightSink: rightSink));
|
||||
|
||||
}
|
||||
|
||||
private async Task UnlockClick(MouseEventArgs obj)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@
|
|||
|
||||
};
|
||||
|
||||
|
||||
var dialog = await DialogService.ShowAsync<StartGameDialog>("Spiel starten", parameters, options);
|
||||
var result = await dialog.Result;
|
||||
var startParams = result.Data as StartParams;
|
||||
|
|
@ -69,7 +68,7 @@
|
|||
else
|
||||
{
|
||||
var result = await DialogService.ShowMessageBox("Spiel beenden?", "Spiel wirklich abbrechen?", "JA", "NEIN", cancelText: "Abbrechen");
|
||||
if (result.Value)
|
||||
if (result.HasValue && result.Value)
|
||||
{
|
||||
var action = new StartStopAction(ThrowPanelState.Value, null);
|
||||
Dispatcher.Dispatch(action);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
@using KoogleApp.Store.Game.ThrowTimer
|
||||
|
||||
@inherits FluxorComponent
|
||||
|
||||
@inject IState<TimerState> TimerState
|
||||
@inject IDispatcher Dispatcher
|
||||
|
||||
@if (TimerState.Value.IsRunning)
|
||||
{
|
||||
<MudButton OnClick="AbortTimer">
|
||||
@TimerState.Value.RemainingSeconds</MudButton>
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
private void AbortTimer(MouseEventArgs obj)
|
||||
{
|
||||
Dispatcher.Dispatch(new StopTimerAction());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
@using KoogleApp.Games
|
||||
@using KoogleApp.Model
|
||||
@using KoogleApp.Services
|
||||
@using KoogleApp.Store.DayFeature
|
||||
@using KoogleApp.Store.Game.Setup
|
||||
@using KoogleApp.Store.Game.ThrowPanel
|
||||
|
||||
@inject GameTypeService GameTypeService
|
||||
@inject IState<SetupState> SetupState
|
||||
@inject IState<DayState> DayState
|
||||
|
||||
<MudDialog Style="height: 800px; width:600px">
|
||||
<TitleContent>
|
||||
|
|
@ -74,7 +76,7 @@
|
|||
// if (!string.IsNullOrEmpty(Description))
|
||||
{
|
||||
// Snackbar.Add("Favorite added", Severity.Success);
|
||||
MudDialog.Close(DialogResult.Ok(new StartParams(SetupState.Value.ThrowMode, SetupState.Value.ThrowsPerRound)));
|
||||
MudDialog.Close(DialogResult.Ok(new StartParams(DayState.Value.Id, SetupState.Value.ThrowMode, SetupState.Value.ThrowsPerRound)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
@using KoogleApp.Store.DayFeature
|
||||
@using KoogleApp.Store.Game
|
||||
@using KoogleApp.Store.Game.ThrowPanel
|
||||
@using KoogleApp.Store.Game.ThrowTimer
|
||||
@using KoogleApp.Store.Game.UndoRedo
|
||||
|
||||
@inherits FluxorComponent
|
||||
|
|
@ -25,6 +26,7 @@
|
|||
@inject IMyEventAggregator EventAggregator
|
||||
@inject IState<ThrowPanelState> ThrowPanelState
|
||||
@inject IState<DayState> DayState
|
||||
|
||||
@inject IDispatcher Dispatcher
|
||||
@inject IDialogService DialogService
|
||||
|
||||
|
|
@ -48,7 +50,7 @@
|
|||
</PanelToolbar>
|
||||
break;
|
||||
case GameView.Board:
|
||||
|
||||
|
||||
break;
|
||||
case GameView.Players:
|
||||
|
||||
|
|
@ -79,7 +81,7 @@
|
|||
<BoardPanel/>
|
||||
break;
|
||||
case GameView.Players:
|
||||
<PlayersPanel/>
|
||||
<PlayersPanel ShowMenu="true"/>
|
||||
break;
|
||||
case GameView.Player:
|
||||
<PlayerPanel/>
|
||||
|
|
@ -227,6 +229,11 @@
|
|||
|
||||
public async Task HandleAsync(GameViewChangedMessage message)
|
||||
{
|
||||
if (message is { GameView: GameView.Throw, AutoReturnFromTimer: false })
|
||||
{
|
||||
Dispatcher.Dispatch(new StopTimerAction());
|
||||
}
|
||||
|
||||
_gameView = message.GameView;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ namespace KoogleApp.Model.EventMessages
|
|||
Player
|
||||
}
|
||||
|
||||
public class GameViewChangedMessage(GameView gameView) : ScopedEventBase
|
||||
public class GameViewChangedMessage(GameView gameView, bool autoReturnFromTimer=false) : ScopedEventBase
|
||||
{
|
||||
public GameView GameView { get; private set; } = gameView;
|
||||
|
||||
public bool AutoReturnFromTimer { get; private set; } = autoReturnFromTimer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace KoogleApp.Model
|
||||
{
|
||||
public record StartParams(ThrowMode ThrowMode, int ThrowsPerRound)
|
||||
public record StartParams(int DayId, ThrowMode ThrowMode, int ThrowsPerRound)
|
||||
{
|
||||
public StartParams() : this(ThrowMode: ThrowMode.Reposition, ThrowsPerRound:3)
|
||||
public StartParams() : this(DayId:0, ThrowMode: ThrowMode.Reposition, ThrowsPerRound:3)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
using Fluxor;
|
||||
using KoogleApp.Hub;
|
||||
using KoogleApp.Model;
|
||||
using KoogleApp.Model.EventMessages;
|
||||
using KoogleApp.Model.Framework;
|
||||
using KoogleApp.Services;
|
||||
using KoogleApp.Store.Game.ThrowTimer;
|
||||
using KoogleApp.Store.Game.UndoRedo;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
|
@ -20,8 +23,10 @@ namespace KoogleApp.Store.Game.ThrowPanel
|
|||
private readonly AuthenticationStateProvider _authenticationStateProvider;
|
||||
private readonly IGameStatusDataService _dataService;
|
||||
private readonly Lock _lock = new Lock();
|
||||
private readonly IMyEventAggregator _eventAggregator;
|
||||
|
||||
public ThrowPanelEffects(
|
||||
IMyEventAggregator eventAggregator,
|
||||
ILogger<ThrowPanelEffects> logger,
|
||||
HubConnectionService sharedHubService,
|
||||
IState<ThrowPanelState> state,
|
||||
|
|
@ -35,6 +40,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
|
|||
_sessionStorage = sessionStorage;
|
||||
_dataService = dataService;
|
||||
_authenticationStateProvider = authenticationStateProvider;
|
||||
_eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -101,6 +107,9 @@ namespace KoogleApp.Store.Game.ThrowPanel
|
|||
[EffectMethod]
|
||||
public async Task HandleThrowAction(ThrowAction throwAction, IDispatcher dispatcher)
|
||||
{
|
||||
await ShowBoardForSeconds(dispatcher);
|
||||
|
||||
|
||||
// change ThrowStatus and save - here we need to save the old state, before it is changed by ThrowUpdateAction, so that undo/redo works correctly
|
||||
dispatcher.Dispatch(new EnsureBeforeThrowStatusAction());
|
||||
|
||||
|
|
@ -111,6 +120,12 @@ namespace KoogleApp.Store.Game.ThrowPanel
|
|||
dispatcher.Dispatch(new TriggerNewThrowPanelStateChangedAction(true)); // this will trigger ThrowPanelStateChangedAction with the new state (not current _state.Value)
|
||||
}
|
||||
|
||||
private async Task ShowBoardForSeconds(IDispatcher dispatcher)
|
||||
{
|
||||
dispatcher.Dispatch(new StartTimerAction(5));
|
||||
await _eventAggregator.PublishAsync(new GameViewChangedMessage(GameView.Board) { Scope = EventScope.Circuit });
|
||||
}
|
||||
|
||||
[EffectMethod]
|
||||
public Task HandleTriggerNewThrowPanelStateChangedAction(TriggerNewThrowPanelStateChangedAction action,
|
||||
IDispatcher dispatcher)
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ namespace KoogleApp.Store.Game.ThrowPanel
|
|||
IsStated = !state.IsStated,
|
||||
ThrowMode = startStopAction.StartParams.ThrowMode,
|
||||
ThrowsPerRound = startStopAction.StartParams.ThrowsPerRound,
|
||||
ThrowPanelStateStatus = ThrowPanelStateStatus.GameStart
|
||||
ThrowPanelStateStatus = ThrowPanelStateStatus.GameStart,
|
||||
DayId = startStopAction.StartParams.DayId
|
||||
};
|
||||
|
||||
return state;
|
||||
|
|
|
|||
|
|
@ -32,12 +32,14 @@ namespace KoogleApp.Store.Game.ThrowPanel
|
|||
[FeatureState]
|
||||
public record ThrowPanelState(bool IsStated, bool BellValue,
|
||||
PinStatus Pin1State, PinStatus Pin2State, PinStatus Pin3State, PinStatus Pin4State, PinStatus Pin5State, PinStatus Pin6State, PinStatus Pin7State, PinStatus Pin8State, PinStatus Pin9State,
|
||||
int ThrowsPerRound, int ThrowCounterPerRound, ThrowMode ThrowMode, ThrowPanelStateStatus ThrowPanelStateStatus, int ThrowCounter)
|
||||
int ThrowsPerRound, int ThrowCounterPerRound, ThrowMode ThrowMode, ThrowPanelStateStatus ThrowPanelStateStatus, int ThrowCounter,
|
||||
int DayId)
|
||||
{
|
||||
// Required for creating initial state
|
||||
public ThrowPanelState() : this(BellValue:false, IsStated:false,
|
||||
Pin1State : PinStatus.Standing, Pin2State: PinStatus.Standing, Pin3State: PinStatus.Standing, Pin4State: PinStatus.Standing, Pin5State: PinStatus.Standing, Pin6State: PinStatus.Standing, Pin7State: PinStatus.Standing, Pin8State: PinStatus.Standing, Pin9State: PinStatus.Standing,
|
||||
ThrowsPerRound : 3, ThrowCounterPerRound : 1, ThrowMode : ThrowMode.Reposition, ThrowPanelStateStatus: ThrowPanelStateStatus.Undefined, ThrowCounter:0
|
||||
ThrowsPerRound : 3, ThrowCounterPerRound : 1, ThrowMode : ThrowMode.Reposition, ThrowPanelStateStatus: ThrowPanelStateStatus.Undefined, ThrowCounter:0,
|
||||
DayId:0
|
||||
)
|
||||
{ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
namespace KoogleApp.Store.Game.ThrowTimer
|
||||
{
|
||||
public class StartTimerAction(int seconds)
|
||||
{
|
||||
public int Seconds { get; } = seconds;
|
||||
}
|
||||
|
||||
public class TimerCompletedAction { }
|
||||
|
||||
public class StopTimerAction { }
|
||||
|
||||
public class TickAction { }
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
using Fluxor;
|
||||
using KoogleApp.Model.EventMessages;
|
||||
using KoogleApp.Model.Framework;
|
||||
using KoogleApp.Services;
|
||||
|
||||
namespace KoogleApp.Store.Game.ThrowTimer
|
||||
{
|
||||
public class TimerEffects
|
||||
{
|
||||
private readonly ILogger<TimerEffects> _logger;
|
||||
private readonly IMyEventAggregator _eventAggregator;
|
||||
private CancellationTokenSource? _timerCancellation;
|
||||
|
||||
public TimerEffects(ILogger<TimerEffects> logger, IMyEventAggregator eventAggregator)
|
||||
{
|
||||
_logger = logger;
|
||||
_eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
[EffectMethod]
|
||||
public async Task HandleStartTimer(StartTimerAction action, IDispatcher dispatcher)
|
||||
{
|
||||
_logger.LogInformation("Timer gestartet für {Seconds} Sekunden", action.Seconds);
|
||||
|
||||
// Vorherigen Timer stoppen falls vorhanden
|
||||
_timerCancellation?.Cancel();
|
||||
_timerCancellation = new CancellationTokenSource();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < action.Seconds; i++)
|
||||
{
|
||||
await Task.Delay(1000, _timerCancellation.Token);
|
||||
dispatcher.Dispatch(new TickAction());
|
||||
}
|
||||
|
||||
// Timer abgelaufen
|
||||
dispatcher.Dispatch(new TimerCompletedAction());
|
||||
_logger.LogInformation("Timer abgelaufen");
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
_logger.LogInformation("Timer wurde abgebrochen");
|
||||
}
|
||||
}
|
||||
|
||||
[EffectMethod]
|
||||
public async Task HandleStopTimer(StopTimerAction action, IDispatcher dispatcher)
|
||||
{
|
||||
_logger.LogInformation("Timer wird gestoppt");
|
||||
_timerCancellation?.Cancel();
|
||||
_timerCancellation = null;
|
||||
|
||||
await ReturnToThrowView();
|
||||
}
|
||||
|
||||
private async Task ReturnToThrowView()
|
||||
{
|
||||
await _eventAggregator.PublishAsync(new GameViewChangedMessage(GameView.Throw, true) { Scope = EventScope.Circuit });
|
||||
}
|
||||
|
||||
[EffectMethod]
|
||||
public async Task HandleTimerCompleted(TimerCompletedAction action, IDispatcher dispatcher)
|
||||
{
|
||||
_logger.LogInformation("Timer-Completed Action wurde verarbeitet");
|
||||
|
||||
await ReturnToThrowView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using Fluxor;
|
||||
|
||||
namespace KoogleApp.Store.Game.ThrowTimer
|
||||
{
|
||||
public static class Reducers
|
||||
{
|
||||
[ReducerMethod]
|
||||
public static TimerState OnStartTimer(TimerState state, StartTimerAction action)
|
||||
{
|
||||
return state with
|
||||
{
|
||||
RemainingSeconds = action.Seconds,
|
||||
IsRunning = true
|
||||
};
|
||||
}
|
||||
|
||||
[ReducerMethod]
|
||||
public static TimerState OnTick(TimerState state, TickAction action)
|
||||
{
|
||||
if (!state.IsRunning || state.RemainingSeconds <= 0)
|
||||
return state;
|
||||
|
||||
return state with
|
||||
{
|
||||
RemainingSeconds = state.RemainingSeconds - 1,
|
||||
IsRunning = state.RemainingSeconds - 1 > 0
|
||||
};
|
||||
}
|
||||
|
||||
[ReducerMethod]
|
||||
public static TimerState OnTimerCompleted(TimerState state, TimerCompletedAction action)
|
||||
{
|
||||
return state with
|
||||
{
|
||||
IsRunning = false,
|
||||
RemainingSeconds = 0
|
||||
};
|
||||
}
|
||||
|
||||
[ReducerMethod]
|
||||
public static TimerState OnStopTimer(TimerState state, StopTimerAction action)
|
||||
{
|
||||
return state with
|
||||
{
|
||||
IsRunning = false,
|
||||
RemainingSeconds = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using Fluxor;
|
||||
|
||||
namespace KoogleApp.Store.Game.ThrowTimer
|
||||
{
|
||||
[FeatureState]
|
||||
public record TimerState(int RemainingSeconds, bool IsRunning)
|
||||
{
|
||||
public TimerState():this(0, false)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,5 +14,6 @@
|
|||
"ThrowCounterPerRound": 1,
|
||||
"ThrowMode": 0,
|
||||
"ThrowPanelStateStatus": 4,
|
||||
"ThrowCounter": 0
|
||||
"ThrowCounter": 0,
|
||||
"DayId": 0
|
||||
}
|
||||
Loading…
Reference in New Issue