From bd3321c489509ff0706898603ccec57bc9e4a73b Mon Sep 17 00:00:00 2001 From: Ben Stein <115497763+sei-bstein@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:36:50 -0500 Subject: [PATCH] v3.24.0 (#203) * Fix tracking of active prac challenge * Minor cleanup and improved console logging * Bug fixes and challenge report tags filter. * Fix event horizon, game center teams, enrollment report stat summary, progress widget * Fix issue with past games not showing ongoing ones * WIP question sets * More question set stuff * Improvements to OIDC experience and support for auto log in/out. * merge from next * Add favicon defaults. Update theme * Fix settings link bug, more thing * Theme stuff * Add settings link to user menu * Theme stuff * Revert "Theme stuff" This reverts commit a26c715cc3d8189bddcee6dadfa021eec98ab708. * Revert "Add settings link to user menu" This reverts commit d640ee80025f01185bee6c3a5918ebf8aba3b3af. * Revert "Theme stuff" This reverts commit c3e3b69b652224cac176dedebc0c66b8899cf490. * Revert "Fix settings link bug, more thing" This reverts commit f96dc596b83743e501fdf1c6b3a603fcda5e7ba3. * Revert "Add favicon defaults. Update theme" This reverts commit 1b2e5a7bfe8df33772e12c017d4d592b363ec6c8. * Rollback and reimplement oauth changes * Update oidc settings to match topo * Cleanup * Update dev env settings * Improvements to OIDC experience and support for auto log in/out. * Restore ux improvements * More retheme * Retheming and initial work on name improvements. * Update gh action versions * Retheming and name mgmt * Styling stuff * Styling stuff * Move challenge markdown * Un 'fix' start practice button * minor name fixes * Name cleanup * Finish merge from main * More theming and fix to GBAPI#502 * More theming and markdown fix * More style fixes * Partially address GBAPI#254 * Return question example answers * Auto-select first available uncompleted tab * Standard challenge panel sticky enhancements * Styling * Roll back login experience changes * Settings bug fix and hide rename cert * Minor theme stuff * Theming * Add additional sticky panel toggle button --- .../challenge-browser.component.html | 10 ++-- .../active-challenges-modal.component.html | 11 +++-- .../game-center-practice.component.html | 6 ++- .../game-center-teams.component.html | 8 ++-- .../game-center-teams.component.ts | 14 ++++-- .../game-center/game-center.component.ts | 5 +- .../src/app/core/pipes/pluralizer.pipe.ts | 3 +- .../gameboard-ui/src/app/game/game.module.ts | 3 +- .../pages/game-page/game-page.component.html | 4 +- .../player-session.component.html | 2 +- ...ice-challenge-state-summary.component.html | 8 +++- ...ice-challenge-state-summary.component.scss | 7 ++- ...ctice-challenge-state-summary.component.ts | 13 +++-- .../enrollment-report.models.ts | 2 +- .../scoreboard-page.component.html | 15 ++++++ .../scoreboard-page.component.scss | 0 .../scoreboard-page.component.ts | 35 ++++++++++++++ .../scoreboard/scoreboard.component.html | 2 +- .../src/app/scoreboard/scoreboard.module.ts | 4 +- .../src/app/services/user-settings.service.ts | 8 ++++ .../src/app/services/window.service.ts | 4 +- .../challenge-questions.component.html | 7 ++- .../games/components/play/play.component.html | 28 +++++------ .../games/components/play/play.component.scss | 2 +- .../games/components/play/play.component.ts | 25 +++++++--- .../src/app/users/users.models.ts | 6 ++- projects/gameboard-ui/src/polyfills.ts | 48 ------------------- 27 files changed, 166 insertions(+), 114 deletions(-) create mode 100644 projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.html create mode 100644 projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.scss create mode 100644 projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.ts create mode 100644 projects/gameboard-ui/src/app/services/user-settings.service.ts diff --git a/projects/gameboard-ui/src/app/admin/challenge-browser/challenge-browser.component.html b/projects/gameboard-ui/src/app/admin/challenge-browser/challenge-browser.component.html index 3edfe164c..61ae18e50 100644 --- a/projects/gameboard-ui/src/app/admin/challenge-browser/challenge-browser.component.html +++ b/projects/gameboard-ui/src/app/admin/challenge-browser/challenge-browser.component.html @@ -15,7 +15,7 @@

Challenges

-
+
Current
@@ -56,7 +56,8 @@

Challenges

- @@ -92,8 +93,9 @@

Challenge

-
- +
@@ -51,6 +52,7 @@ -
No one has attempted challenges from this game in the Practice Area yet. +
+ No one has attempted challenges from this game in the Practice Area yet.
diff --git a/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.html b/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.html index 2f1465010..a5d276c4e 100644 --- a/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.html +++ b/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.html @@ -1,7 +1,7 @@ There are {{results?.namesPendingApproval}} {{ "player" | pluralizer:results?.namesPendingApproval}} in this game - who have pending name change requests. Click here + who have pending name change requests. Click + here to review them. @@ -114,7 +114,7 @@
Playing now
- {{ team.session.end | epochMsToDateTime | datetimeToDate | dateToCountdown | async }} @@ -125,7 +125,7 @@
Not playing yet
- (Registered {{ team.registeredOn | epochMsToDateTime | shortdate }}) diff --git a/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.ts b/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.ts index fed53c4d8..a67a11ccc 100644 --- a/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.ts +++ b/projects/gameboard-ui/src/app/admin/components/game-center/game-center-teams/game-center-teams.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; -import { debounceTime, firstValueFrom, map, Subject, tap } from 'rxjs'; +import { ActivatedRoute } from '@angular/router'; +import { debounceTime, firstValueFrom, map, Subject } from 'rxjs'; import { AdminService } from '@/api/admin.service'; import { fa } from '@/services/font-awesome.service'; import { Game } from '@/api/game-models'; @@ -19,7 +20,6 @@ import { LocalStorageService, StorageKey } from '@/services/local-storage.servic import { NowService } from '@/services/now.service'; import { GameCenterTeamDetailComponent } from '../game-center-team-detail/game-center-team-detail.component'; import { TeamService } from '@/api/team.service'; -import { ActivatedRoute } from '@angular/router'; interface GameCenterTeamsFilterSettings { advancement?: GameCenterTeamsAdvancementFilter; @@ -61,9 +61,13 @@ export class GameCenterTeamsComponent implements OnInit { this.unsub.add( this.route.data.subscribe(async d => await this.load(d.gameId)), - this.searchInput$.pipe( - debounceTime(300) - ).subscribe(async event => { + this.route.queryParams.subscribe(async qp => { + if (qp.search) { + this.filterSettings.searchTerm = qp.search.toString().trim(); + await this.load(this.game?.id); + } + }), + this.searchInput$.pipe(debounceTime(300)).subscribe(async event => { this.filterSettings.searchTerm = (event.target as HTMLInputElement).value; await this.load(this.game?.id); }), diff --git a/projects/gameboard-ui/src/app/admin/components/game-center/game-center.component.ts b/projects/gameboard-ui/src/app/admin/components/game-center/game-center.component.ts index 723e112c5..831cd8bb1 100644 --- a/projects/gameboard-ui/src/app/admin/components/game-center/game-center.component.ts +++ b/projects/gameboard-ui/src/app/admin/components/game-center/game-center.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { AdminService } from '@/api/admin.service'; import { Game } from '@/api/game-models'; import { GameService } from '@/api/game.service'; @@ -29,8 +29,7 @@ export class GameCenterComponent { private adminService: AdminService, private appTitle: AppTitleService, private gameService: GameService, - private localUserService: UserService, - private router: Router) { + private localUserService: UserService) { unsub.add(this.activatedRoute.paramMap.subscribe(async paramMap => { const gameId = paramMap.get("gameId") || this.gameCenterCtx?.id; diff --git a/projects/gameboard-ui/src/app/core/pipes/pluralizer.pipe.ts b/projects/gameboard-ui/src/app/core/pipes/pluralizer.pipe.ts index 58baef564..39fae160e 100644 --- a/projects/gameboard-ui/src/app/core/pipes/pluralizer.pipe.ts +++ b/projects/gameboard-ui/src/app/core/pipes/pluralizer.pipe.ts @@ -2,8 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'pluralizer' }) export class PluralizerPipe implements PipeTransform { - - transform(label: string, count: any = 0, addE: boolean = false): string { + transform(label: string, count: number = 0, addE: boolean = false): string { if (!label) return ""; diff --git a/projects/gameboard-ui/src/app/game/game.module.ts b/projects/gameboard-ui/src/app/game/game.module.ts index 332ea4127..ddc58da54 100644 --- a/projects/gameboard-ui/src/app/game/game.module.ts +++ b/projects/gameboard-ui/src/app/game/game.module.ts @@ -37,8 +37,8 @@ import { HasPendingNamePipe } from './pipes/has-pending-name.pipe'; import { ChallengeQuestionsComponent } from "../standalone/games/components/challenge-questions/challenge-questions.component"; import { SpinnerComponent } from '@/standalone/core/components/spinner/spinner.component'; import { ErrorDivComponent } from '@/standalone/core/components/error-div/error-div.component'; -import { VmLinkComponent } from '@/standalone/games/components/vm-link/vm-link.component'; import { SafeUrlPipe } from '@/standalone/core/pipes/safe-url.pipe'; +import { ScoreboardPageComponent } from '@/scoreboard/components/scoreboard-page/scoreboard-page.component'; const MODULE_DECLARATIONS = [ CertificateComponent, @@ -75,6 +75,7 @@ const MODULE_DECLARATIONS = [ { path: 'board/:playerId', canActivate: [AuthGuard, GameIsStarted, UserIsPlayingGuard], component: GameboardPageComponent }, { path: 'external/:gameId/start/:playerId', canActivate: [AuthGuard, UserIsPlayingGuard], component: ExternalGameLoadingPageComponent }, { path: 'external/:gameId/:teamId', canActivate: [AuthGuard, UserIsPlayingGuard, ExternalGameGuard], component: ExternalGamePageComponent }, + { path: ":gameId/scoreboard", component: ScoreboardPageComponent }, { path: ':id', component: GamePageComponent, children: [] } ]), CoreModule, diff --git a/projects/gameboard-ui/src/app/game/pages/game-page/game-page.component.html b/projects/gameboard-ui/src/app/game/pages/game-page/game-page.component.html index ebc67ea41..78b46597b 100644 --- a/projects/gameboard-ui/src/app/game/pages/game-page/game-page.component.html +++ b/projects/gameboard-ui/src/app/game/pages/game-page/game-page.component.html @@ -9,7 +9,7 @@
- + Scoreboard @@ -87,7 +87,7 @@

Info

Scoreboard   - + diff --git a/projects/gameboard-ui/src/app/game/player-session/player-session.component.html b/projects/gameboard-ui/src/app/game/player-session/player-session.component.html index 96e0eb700..a60274c08 100644 --- a/projects/gameboard-ui/src/app/game/player-session/player-session.component.html +++ b/projects/gameboard-ui/src/app/game/player-session/player-session.component.html @@ -49,7 +49,7 @@ [playerId]="ctx.player.id">
- + View Scoreboard diff --git a/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.html b/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.html index c0e113680..ba980080c 100644 --- a/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.html +++ b/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.html @@ -36,7 +36,7 @@ - +
+ +
diff --git a/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.scss b/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.scss index da4435178..c98923686 100644 --- a/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.scss +++ b/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.scss @@ -1,3 +1,8 @@ a:hover { - text-decoration: none; + text-decoration: none; +} + +table, +thead { + border-top-width: 0; } diff --git a/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.ts b/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.ts index 17a6cfa6b..2fab9e455 100644 --- a/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.ts +++ b/projects/gameboard-ui/src/app/prac/components/practice-challenge-state-summary/practice-challenge-state-summary.component.ts @@ -8,6 +8,7 @@ import { ActiveChallengesRepo } from '@/stores/active-challenges.store'; import { slug } from '@/../tools/functions'; import { TeamService } from '@/api/team.service'; import { ToastService } from '@/utility/services/toast.service'; +import { UserSettingsService } from '@/services/user-settings.service'; @Component({ selector: 'app-practice-challenge-state-summary', @@ -23,11 +24,13 @@ export class PracticeChallengeStateSummaryComponent { protected isChangingSessionEnd = false; protected fa = fa; protected slug = slug; + protected userSettings$ = this.userSettings.updated$; constructor( activeChallengesRepo: ActiveChallengesRepo, private teamService: TeamService, - private toastService: ToastService) { + private toastService: ToastService, + private userSettings: UserSettingsService) { this.activeChallenge$ = activeChallengesRepo.activePracticeChallenge$; } @@ -48,12 +51,8 @@ export class PracticeChallengeStateSummaryComponent { this.isChangingSessionEnd = false; } - private getExtendTooltip(msRemaining: number) { - if (msRemaining < this.msPerHour) { - return "If you want more time to practice, you can extend your session. Sessions extend to a maximum remaining time of 60 minutes."; - } - - return "You can't extend your practice session because you have more than 60 minutes remaining."; + protected handleToggleStickyPanel(enable: boolean) { + this.userSettings.updated$.next({ useStickyChallengePanel: enable }); } private showExtensionToast(sessionEnd: DateTime, isAutomatic = false) { diff --git a/projects/gameboard-ui/src/app/reports/components/reports/enrollment-report/enrollment-report.models.ts b/projects/gameboard-ui/src/app/reports/components/reports/enrollment-report/enrollment-report.models.ts index 420dcd837..6fe6e0d1b 100644 --- a/projects/gameboard-ui/src/app/reports/components/reports/enrollment-report/enrollment-report.models.ts +++ b/projects/gameboard-ui/src/app/reports/components/reports/enrollment-report/enrollment-report.models.ts @@ -70,7 +70,7 @@ export interface EnrollmentReportByGameSponsor { id: string; name: string; logoFileName: string; - playerCount: string; + playerCount: number; } export interface EnrollmentReportStatSummary { diff --git a/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.html b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.html new file mode 100644 index 000000000..3fe4d1f93 --- /dev/null +++ b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.html @@ -0,0 +1,15 @@ +
+ +

Scoreboard

+

+ {{ game.name }} +

+ + +
+ +
+ + + Loading the score... + diff --git a/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.scss b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.ts b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.ts new file mode 100644 index 000000000..33c43026d --- /dev/null +++ b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard-page/scoreboard-page.component.ts @@ -0,0 +1,35 @@ +import { ActivatedRoute } from '@angular/router'; +import { firstValueFrom } from 'rxjs'; +import { GameService } from '@/api/game.service'; +import { SimpleEntity } from '@/api/models'; +import { AppTitleService } from '@/services/app-title.service'; +import { UnsubscriberService } from '@/services/unsubscriber.service'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-scoreboard-page', + providers: [UnsubscriberService], + templateUrl: './scoreboard-page.component.html', + styleUrls: ['./scoreboard-page.component.scss'] +}) +export class ScoreboardPageComponent { + protected game?: SimpleEntity; + + constructor( + private appTitle: AppTitleService, + private gameService: GameService, + private route: ActivatedRoute, + private unsub: UnsubscriberService) { + this.unsub.add(this.route.params.subscribe(async params => this.loadGame(params.gameId))); + } + + private async loadGame(gameId: string) { + if (!gameId) { + this.game = undefined; + return; + } + + this.game = await firstValueFrom(this.gameService.retrieve(gameId)); + this.appTitle.set(`Scoreboard | ${this.game.name}`); + } +} diff --git a/projects/gameboard-ui/src/app/scoreboard/components/scoreboard/scoreboard.component.html b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard/scoreboard.component.html index 9aee2063e..e51b9d496 100644 --- a/projects/gameboard-ui/src/app/scoreboard/components/scoreboard/scoreboard.component.html +++ b/projects/gameboard-ui/src/app/scoreboard/components/scoreboard/scoreboard.component.html @@ -1,5 +1,5 @@ - + This game is still being played. Check back after the round ends ({{ scoreboardData.game.isLiveUntil?.toJSDate() | friendlyDateAndTime }}) to see who came out on top and view complete score breakdowns for diff --git a/projects/gameboard-ui/src/app/scoreboard/scoreboard.module.ts b/projects/gameboard-ui/src/app/scoreboard/scoreboard.module.ts index 18e12569b..de1ee7a1e 100644 --- a/projects/gameboard-ui/src/app/scoreboard/scoreboard.module.ts +++ b/projects/gameboard-ui/src/app/scoreboard/scoreboard.module.ts @@ -7,6 +7,7 @@ import { ScoreboardComponent } from './components/scoreboard/scoreboard.componen import { ScoreboardTeamDetailModalComponent } from './components/scoreboard-team-detail-modal/scoreboard-team-detail-modal.component'; import { ScoreToTooltipPipe } from './pipes/score-to-tooltip.pipe'; import { SpinnerComponent } from '@/standalone/core/components/spinner/spinner.component'; +import { ScoreboardPageComponent } from './components/scoreboard-page/scoreboard-page.component'; const PUBLIC_DECLARATIONS = [ ScoreboardComponent, @@ -17,7 +18,8 @@ const PUBLIC_DECLARATIONS = [ @NgModule({ declarations: [ ...PUBLIC_DECLARATIONS, - ChallengeBonusesToTooltip + ChallengeBonusesToTooltip, + ScoreboardPageComponent ], imports: [ CommonModule, diff --git a/projects/gameboard-ui/src/app/services/user-settings.service.ts b/projects/gameboard-ui/src/app/services/user-settings.service.ts new file mode 100644 index 000000000..a6c804e7b --- /dev/null +++ b/projects/gameboard-ui/src/app/services/user-settings.service.ts @@ -0,0 +1,8 @@ +import { UserAppSettings } from "@/users/users.models"; +import { Injectable } from "@angular/core"; +import { BehaviorSubject } from "rxjs"; + +@Injectable({ providedIn: 'root' }) +export class UserSettingsService { + public updated$ = new BehaviorSubject({ useStickyChallengePanel: false }); +} diff --git a/projects/gameboard-ui/src/app/services/window.service.ts b/projects/gameboard-ui/src/app/services/window.service.ts index 9b7ac62be..b4b2964b4 100644 --- a/projects/gameboard-ui/src/app/services/window.service.ts +++ b/projects/gameboard-ui/src/app/services/window.service.ts @@ -37,6 +37,8 @@ export class WindowService implements OnDestroy { } scrollToBottom() { - this.document.defaultView?.scrollTo(0, this.document.body.scrollHeight); + setTimeout(() => { + this.document.defaultView?.scrollTo(0, this.document.body.scrollHeight); + }, 500); } } diff --git a/projects/gameboard-ui/src/app/standalone/games/components/challenge-questions/challenge-questions.component.html b/projects/gameboard-ui/src/app/standalone/games/components/challenge-questions/challenge-questions.component.html index 9410aeb1f..0b55bf666 100644 --- a/projects/gameboard-ui/src/app/standalone/games/components/challenge-questions/challenge-questions.component.html +++ b/projects/gameboard-ui/src/app/standalone/games/components/challenge-questions/challenge-questions.component.html @@ -120,7 +120,12 @@

{{ context.section.name | formControlName="s{{ context.index }}q{{ questionIndex }}" [readOnly]="question.isCorrect" placeholder="Enter your answer for question {{ questionIndex + 1 }} here">

-
e.g. {{question.example}}
+
+ + Example: + + {{question.example}} +

diff --git a/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.html b/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.html index 5ae1e421a..721ae585f 100644 --- a/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.html +++ b/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.html @@ -16,7 +16,8 @@

Check out the new challenge resources panel!

- Click here + Click here to "sticky" the Challenge panel so it's always visible as you scroll down the page. (You can return the panel to the bottom of the page at any time by clicking the appropriate link in the panel.) @@ -30,7 +31,7 @@

Check out the new challenge resources panel!

-

+

Challenge Consoles

  • @@ -57,17 +58,17 @@

    Challenge Questions

-
+
-
Support Code: - {{ { id: challenge.id } | toSupportCode }} @@ -76,8 +77,8 @@

Challenge Questions

Having trouble? - + Create Ticket
@@ -97,7 +98,7 @@

Challenge Questions

-
+
Challenge Consoles
    @@ -148,7 +149,8 @@
    Need help?

    - Click here + Click here to deactivate the sticky Challenge panel
    @@ -158,10 +160,6 @@
    Need help?
    Loading your challenge... - - Challenge {{ "Console" | pluralizer:vmUrls }} - -

    Solution Guide

    diff --git a/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.scss b/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.scss index 02d4d70ec..8ee775a70 100644 --- a/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.scss +++ b/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.scss @@ -9,7 +9,7 @@ margin-top: 80px; padding: 1rem; position: sticky; - top: 50px; + top: 48px; min-width: 420px; width: 420px; diff --git a/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.ts b/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.ts index 70d5c4332..3def41e04 100644 --- a/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.ts +++ b/projects/gameboard-ui/src/app/standalone/games/components/play/play.component.ts @@ -20,6 +20,7 @@ import { ChallengeDeployCountdownComponent } from '@/game/components/challenge-d import { ErrorDivComponent } from '@/standalone/core/components/error-div/error-div.component'; import { VmLinkComponent } from "../vm-link/vm-link.component"; import { UserService } from '@/utility/user.service'; +import { UserSettingsService } from '@/services/user-settings.service'; @Component({ selector: 'app-play', @@ -59,13 +60,14 @@ export class PlayComponent implements OnChanges { protected windowWidth$: Observable; constructor( - windowService: WindowService, private activeChallengesRepo: ActiveChallengesRepo, private challengesService: ChallengesService, private localStorage: LocalStorageService, private localUser: UserService, private routerService: RouterService, - private unsub: UnsubscriberService) { + private unsub: UnsubscriberService, + private userAppSettings: UserSettingsService, + private windowService: WindowService) { this.windowWidth$ = windowService.resize$; this.unsub.add( windowService.resize$.subscribe(width => { @@ -74,8 +76,10 @@ export class PlayComponent implements OnChanges { this.showMiniPlayerPrompt = this.localStorage.get(StorageKey.UsePlayPane) === null; if (!this.isMiniPlayerAvailable && this.isMiniPlayerSelected) - this.toggleMiniPlayer(); - }) + this.setIsStickyPanelEnabled(this.isMiniPlayerSelected, false); + }), + + userAppSettings.updated$.subscribe(settings => this.setIsStickyPanelEnabled(settings.useStickyChallengePanel, false)) ); } @@ -106,10 +110,11 @@ export class PlayComponent implements OnChanges { this.isUndeploying = false; } - protected toggleMiniPlayer() { + protected setIsStickyPanelEnabled(isEnabled: boolean, notify = true) { this.showMiniPlayerPrompt = false; + if (this.isMiniPlayerAvailable) { - this.isMiniPlayerSelected = !this.isMiniPlayerSelected; + this.isMiniPlayerSelected = isEnabled; this.localStorage.add(StorageKey.UsePlayPane, this.isMiniPlayerSelected); } @@ -117,6 +122,14 @@ export class PlayComponent implements OnChanges { this.isMiniPlayerSelected = false; this.localStorage.add(StorageKey.UsePlayPane, false); } + + if (notify) { + this.userAppSettings.updated$.next({ useStickyChallengePanel: this.isMiniPlayerSelected }); + } + + if (!this.isMiniPlayerSelected) { + this.windowService.scrollToBottom(); + } } private buildVmLinks(challenge: UserActiveChallenge | null) { diff --git a/projects/gameboard-ui/src/app/users/users.models.ts b/projects/gameboard-ui/src/app/users/users.models.ts index 7f5928592..ffe2a613f 100644 --- a/projects/gameboard-ui/src/app/users/users.models.ts +++ b/projects/gameboard-ui/src/app/users/users.models.ts @@ -1,6 +1,6 @@ +import { Duration } from "luxon"; import { SimpleEntity } from "@/api/models"; import { PlayerMode } from "@/api/player-models"; -import { Duration } from "luxon"; export interface PracticeModeCertificate { challenge: { @@ -31,3 +31,7 @@ export interface PublishedCertificateViewModel { ownerUser: SimpleEntity; mode: PlayerMode; } + +export interface UserAppSettings { + useStickyChallengePanel: boolean; +} diff --git a/projects/gameboard-ui/src/polyfills.ts b/projects/gameboard-ui/src/polyfills.ts index dcd18eace..f22ab65e9 100644 --- a/projects/gameboard-ui/src/polyfills.ts +++ b/projects/gameboard-ui/src/polyfills.ts @@ -1,53 +1,5 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ import 'zone.js'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */