From b6626c9d4faac0a68ca80ffb508b54d2a30cdcec Mon Sep 17 00:00:00 2001
From: grimsi <9295182+grimsi@users.noreply.github.com>
Date: Mon, 15 Aug 2022 16:10:12 +0200
Subject: [PATCH] Added filter for player perspective
---
.../library-overview.component.html | 12 +++++++
.../library-overview.component.ts | 32 +++++++++++++++++--
.../app/models/dtos/PlayerPerspectiveDto.ts | 2 +-
frontend/src/app/services/games.service.ts | 18 ++++++++++-
4 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/frontend/src/app/components/library-overview/library-overview.component.html b/frontend/src/app/components/library-overview/library-overview.component.html
index 88a3c49..d741353 100644
--- a/frontend/src/app/components/library-overview/library-overview.component.html
+++ b/frontend/src/app/components/library-overview/library-overview.component.html
@@ -100,6 +100,18 @@
color="primary">{{theme.name}}
+
+ 0">
+
+ Player Perspectives
+
+
+
+ {{playerPerspective.name}}
+
+
diff --git a/frontend/src/app/components/library-overview/library-overview.component.ts b/frontend/src/app/components/library-overview/library-overview.component.ts
index 8e9c1b9..a8efcd1 100644
--- a/frontend/src/app/components/library-overview/library-overview.component.ts
+++ b/frontend/src/app/components/library-overview/library-overview.component.ts
@@ -5,6 +5,8 @@ import {GenreDto} from "../../models/dtos/GenreDto";
import {ThemeDto} from "../../models/dtos/ThemeDto";
import {firstValueFrom, forkJoin, Observable, pipe} from "rxjs";
import {SortDirection} from "@angular/material/sort";
+import {CompanyDto} from "../../models/dtos/CompanyDto";
+import {PlayerPerspectiveDto} from "../../models/dtos/PlayerPerspectiveDto";
class SortOption {
title: string;
@@ -48,10 +50,12 @@ export class LibraryOverviewComponent implements AfterContentInit {
lanSupportFilterEnabled: boolean = false;
activeThemeFilters: string[] = [];
activeGenreFilters: string[] = [];
+ activePlayerPerspectiveFilters: string[] = [];
games: DetectedGameDto[] = [];
availableGenres: GenreDto[] = [];
availableThemes: ThemeDto[] = [];
+ availablePlayerPerspectives: PlayerPerspectiveDto[] = [];
loading: boolean = true;
gameLibraryIsEmpty: boolean = false;
@@ -72,10 +76,13 @@ export class LibraryOverviewComponent implements AfterContentInit {
let genreObservable: Observable = this.gameServerService.getAvailableGenres();
let themeObservable: Observable = this.gameServerService.getAvailableThemes();
+ let playerPerspectiveObservable: Observable = this.gameServerService.getAvailablePlayerPerspectives();
+
+ forkJoin([genreObservable, themeObservable, playerPerspectiveObservable]).subscribe(result => {
+ this.availableGenres = result[0];
+ this.availableThemes = result[1];
+ this.availablePlayerPerspectives = result[2];
- forkJoin([themeObservable, genreObservable]).subscribe(result => {
- this.availableThemes = result[0];
- this.availableGenres = result[1];
this.refreshLibraryView().then(() => this.loading = false);
});
}
@@ -109,6 +116,10 @@ export class LibraryOverviewComponent implements AfterContentInit {
games = games.filter(game => this.activeThemeFilters.every(activeThemeFilter => game.themes?.map(g => g.slug).includes(activeThemeFilter)));
}
+ if (this.activePlayerPerspectiveFilters.length > 0) {
+ games = games.filter(game => this.activePlayerPerspectiveFilters.every(activePlayerPerspectiveFilter => game.playerPerspectives?.map(g => g.slug).includes(activePlayerPerspectiveFilter)));
+ }
+
return games;
}
@@ -157,4 +168,19 @@ export class LibraryOverviewComponent implements AfterContentInit {
this.refreshLibraryView();
}
+ togglePlayerPerspectiveFilter(slug: string) {
+ if (this.activePlayerPerspectiveFilters.includes(slug)) {
+
+ const index = this.activePlayerPerspectiveFilters.indexOf(slug, 0);
+ if (index > -1) {
+ this.activePlayerPerspectiveFilters.splice(index, 1);
+ }
+
+ } else {
+ this.activePlayerPerspectiveFilters.push(slug);
+ }
+
+ this.refreshLibraryView();
+ }
+
}
diff --git a/frontend/src/app/models/dtos/PlayerPerspectiveDto.ts b/frontend/src/app/models/dtos/PlayerPerspectiveDto.ts
index ff0ee82..e4f7e0d 100644
--- a/frontend/src/app/models/dtos/PlayerPerspectiveDto.ts
+++ b/frontend/src/app/models/dtos/PlayerPerspectiveDto.ts
@@ -1,4 +1,4 @@
export class PlayerPerspectiveDto {
slug!: string;
- name?: string;
+ name!: string;
}
diff --git a/frontend/src/app/services/games.service.ts b/frontend/src/app/services/games.service.ts
index c91f940..87bd6f4 100644
--- a/frontend/src/app/services/games.service.ts
+++ b/frontend/src/app/services/games.service.ts
@@ -6,6 +6,8 @@ import {DetectedGameDto} from "../models/dtos/DetectedGameDto";
import {GameOverviewDto} from "../models/dtos/GameOverviewDto";
import {GenreDto} from "../models/dtos/GenreDto";
import {ThemeDto} from "../models/dtos/ThemeDto";
+import {CompanyDto} from "../models/dtos/CompanyDto";
+import {PlayerPerspectiveDto} from "../models/dtos/PlayerPerspectiveDto";
@Injectable({
providedIn: 'root'
@@ -64,7 +66,7 @@ export class GamesService implements GamesApi {
return this.getAllGames().pipe(
map(
games => {
- let availableThemesMap: Map = new Map;
+ let availableThemesMap: Map = new Map;
games.map(game => game.themes === undefined ? [] : game.themes).flat().forEach(theme => availableThemesMap.set(theme.slug, theme));
return Array.from(availableThemesMap.values()).sort((t1, t2) => t1.name.localeCompare(t2.name));
}
@@ -72,6 +74,20 @@ export class GamesService implements GamesApi {
);
}
+ // TODO: This method of removing duplicates is most certainly an anti-pattern in RxJS
+ // TODO: However, I did not get the 'distinct()' pipe to work properly, so I have to take another look in the future
+ getAvailablePlayerPerspectives(): Observable {
+ return this.getAllGames().pipe(
+ map(
+ games => {
+ let availablePlayerPerspectivesMap: Map = new Map;
+ games.map(game => game.playerPerspectives === undefined ? [] : game.playerPerspectives).flat().forEach(playerPerspective => availablePlayerPerspectivesMap.set(playerPerspective.slug, playerPerspective));
+ return Array.from(availablePlayerPerspectivesMap.values()).sort((t1, t2) => t1.name.localeCompare(t2.name));
+ }
+ )
+ );
+ }
+
downloadGame(slug: String): void {
window.open(`v1${this.apiPath}/game/${slug}/download`, '_top');
}