feat: simplify angular host/player mvp controls
All checks were successful
CI / test-and-quality (push) Successful in 2m27s
CI / test-and-quality (pull_request) Successful in 2m31s

This commit is contained in:
2026-03-13 08:24:14 +00:00
parent 9594a8fcb0
commit 58874c0d78
5 changed files with 144 additions and 30 deletions

View File

@@ -11,6 +11,17 @@ interface SessionDetail {
session: { code: string; status: string; current_round: number };
round_question: { id: number; prompt: string; answers: Array<{ text: string }> } | null;
players: Array<{ id: number; nickname: string; score: number }>;
phase_view_model?: {
host?: {
can_start_round?: boolean;
can_show_question?: boolean;
can_mix_answers?: boolean;
can_calculate_scores?: boolean;
can_reveal_scoreboard?: boolean;
can_start_next_round?: boolean;
can_finish_game?: boolean;
};
};
}
type LeaderboardEntry = ScoreboardResponse['leaderboard'][number];
@@ -25,18 +36,15 @@ type LeaderboardResponse = FinishGameResponse;
<div class="panel" [attr.data-client-has-no-audio-output]="clientHasNoAudioOutput">
<label>{{ copy('common.session_code') }} <input [(ngModel)]="sessionCode" /></label>
<label>{{ copy('host.category') }} <input [(ngModel)]="categorySlug" /></label>
<label *ngIf="canStartRound">{{ copy('host.category') }} <input [(ngModel)]="categorySlug" /></label>
<button (click)="refreshSession()" [disabled]="loading">{{ copy('common.refresh') }}</button>
<button (click)="startRound()" [disabled]="loading">{{ copy('host.start_round') }}</button>
<button (click)="showQuestion()" [disabled]="loading || !roundQuestionId">{{ copy('host.show_question') }}</button>
<button (click)="mixAnswers()" [disabled]="loading || !roundQuestionId">{{ copy('host.mix_answers') }}</button>
<button (click)="calculateScores()" [disabled]="loading || !roundQuestionId">{{ copy('host.calculate_scores') }}</button>
<button (click)="loadScoreboard()" [disabled]="loading">{{ copy('host.load_scoreboard') }}</button>
<button (click)="startNextRound()" [disabled]="loading">{{ copy('host.start_next_round') }}</button>
<button (click)="finishGame()" [disabled]="loading">{{ copy('host.finish_game') }}</button>
<button *ngIf="scoreboardError" (click)="loadScoreboard()" [disabled]="loading">{{ copy('host.retry_scoreboard') }}</button>
<button *ngIf="nextRoundError" (click)="startNextRound()" [disabled]="loading">{{ copy('host.retry_next_round') }}</button>
<button *ngIf="finishError" (click)="finishGame()" [disabled]="loading">{{ copy('host.retry_finish') }}</button>
<button *ngIf="canStartRound" (click)="startRound()" [disabled]="loading">{{ copy('host.start_round') }}</button>
<button *ngIf="canShowQuestion" (click)="showQuestion()" [disabled]="loading || !roundQuestionId">{{ copy('host.show_question') }}</button>
<button *ngIf="canMixAnswers" (click)="mixAnswers()" [disabled]="loading || !roundQuestionId">{{ copy('host.mix_answers') }}</button>
<button *ngIf="canCalculateScores" (click)="calculateScores()" [disabled]="loading || !roundQuestionId">{{ copy('host.calculate_scores') }}</button>
<button *ngIf="canRevealScoreboard || scoreboardError" (click)="loadScoreboard()" [disabled]="loading">{{ copy(scoreboardError ? 'host.retry_scoreboard' : 'host.load_scoreboard') }}</button>
<button *ngIf="canStartNextRound || nextRoundError" (click)="startNextRound()" [disabled]="loading">{{ copy(nextRoundError ? 'host.retry_next_round' : 'host.start_next_round') }}</button>
<button *ngIf="canFinishGame || finishError" (click)="finishGame()" [disabled]="loading">{{ copy(finishError ? 'host.retry_finish' : 'host.finish_game') }}</button>
</div>
<p *ngIf="session" class="hint">{{ copy('host.audio_locale_hint') }}: {{ locale }}</p>
@@ -114,6 +122,34 @@ export class HostShellComponent implements OnInit, OnDestroy {
this.unsubscribeLocale = null;
}
get canStartRound(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_start_round ?? !this.session);
}
get canShowQuestion(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_show_question);
}
get canMixAnswers(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_mix_answers);
}
get canCalculateScores(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_calculate_scores);
}
get canRevealScoreboard(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_reveal_scoreboard);
}
get canStartNextRound(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_start_next_round);
}
get canFinishGame(): boolean {
return Boolean(this.session?.phase_view_model?.host?.can_finish_game);
}
copy(key: string): string {
return t(key, this.locale);
}