Skip to content

Commit

Permalink
Merge pull request #25 from game-node-app/dev
Browse files Browse the repository at this point in the history
- Added icons for platforms groups
  • Loading branch information
Lamarcke authored Feb 28, 2024
2 parents ba8b45c + 1375983 commit 5746664
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 63 deletions.
1 change: 0 additions & 1 deletion docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ services:

volumes:
- gamenode:/app/public/uploads
- gamenode:/app/public/icons

command: ["yarn", "start"]

Expand Down
Binary file added public/icons/nintendo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/playstation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/sega.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/steam.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/xbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion server_swagger.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IsArray, IsNotEmpty, IsString } from "class-validator";

export class IconNamesForPlatformRequestDto {
@IsNotEmpty()
@IsArray()
@IsString({ each: true })
platformAbbreviations: string[];
}
16 changes: 11 additions & 5 deletions src/game/game-repository/game-repository.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ import {
Param,
Post,
Query,
UseInterceptors,
} from "@nestjs/common";
import {
GameRepositoryService,
TAllowedResource,
} from "./game-repository.service";
import { ApiOkResponse, ApiTags } from "@nestjs/swagger";
import { PaginationInterceptor } from "../../interceptor/pagination.interceptor";
import { GameRepositoryFindAllDto } from "./dto/game-repository-find-all.dto";
import { GameRepositoryPaginatedResponseDto } from "./dto/game-repository-paginated-response.dto";
import { GameRepositoryFindOneDto } from "./dto/game-repository-find-one.dto";
import { Game } from "./entities/game.entity";
import { ApiTags } from "@nestjs/swagger";
import { IconNamesForPlatformRequestDto } from "./dto/icon-names-for-platform-request.dto";

@Controller("game/repository")
@ApiTags("game-repository")
Expand All @@ -31,6 +28,15 @@ export class GameRepositoryController {
return await this.gameRepositoryService.getResource(resourceName);
}

@Post("platforms/icon")
getIconNamesForPlatformAbbreviations(
@Body() dto: IconNamesForPlatformRequestDto,
) {
return this.gameRepositoryService.getIconNamesForPlatformAbbreviations(
dto.platformAbbreviations,
);
}

@Post(":id")
@HttpCode(200)
async findOneById(
Expand Down
17 changes: 17 additions & 0 deletions src/game/game-repository/game-repository.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { GameMode } from "./entities/game-mode.entity";
import { GamePlayerPerspective } from "./entities/game-player-perspective.entity";
import { GameRepositoryFilterDto } from "./dto/game-repository-filter.dto";
import { buildFilterFindOptions } from "../../sync/igdb/utils/build-filter-find-options";
import { platformAbbreviationToIconMap } from "./game-repository.utils";

const resourceToEntityMap = {
platforms: GamePlatform,
Expand Down Expand Up @@ -113,4 +114,20 @@ export class GameRepositoryService {
this.dataSource.getRepository(resourceAsEntity);
return await resourceRepository.find();
}

getIconNamesForPlatformAbbreviations(platformAbbreviations: string[]) {
const iconsNames: string[] = [];
for (const [iconName, platforms] of Object.entries(
platformAbbreviationToIconMap,
)) {
const abbreviationPresent = platformAbbreviations.some(
(abbreviation) => platforms.includes(abbreviation),
);
if (abbreviationPresent) {
iconsNames.push(iconName);
}
}

return iconsNames;
}
}
14 changes: 14 additions & 0 deletions src/game/game-repository/game-repository.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const platformAbbreviationToIconMap: { [p: string]: string[] } = {
steam: ["PC", "Linux"],
playstation: ["PS1", "PS2", "PS3", "PS4", "PS5", "PSP", "PSVR", "PSVR2"],
xbox: ["XBOX", "X360", "XONE"],
nintendo: ["N64", "NES", "NDS", "NGC", "SNES", "3DS", "Switch"],
sega: [
"SMS",
"segacd",
"Sega32",
"Saturn",
"Genesis/Megadrive",
"Game Gear",
],
};
6 changes: 5 additions & 1 deletion src/statistics/dto/find-statistics-trending-games.dto.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { BaseFindDto } from "../../utils/base-find.dto";
import { Statistics } from "../entity/statistics.entity";
import { GameRepositoryFilterDto } from "../../game/game-repository/dto/game-repository-filter.dto";
import { IsOptional } from "class-validator";
import { IsEnum, IsNotEmpty, IsOptional } from "class-validator";
import { StatisticsPeriod } from "../statistics.constants";

export class FindStatisticsTrendingGamesDto extends BaseFindDto<Statistics> {
@IsOptional()
criteria?: GameRepositoryFilterDto;
@IsNotEmpty()
@IsEnum(StatisticsPeriod)
period: StatisticsPeriod;
}
6 changes: 5 additions & 1 deletion src/statistics/dto/find-statistics-trending-reviews.dto.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { IsNumber, IsOptional } from "class-validator";
import { IsEnum, IsNotEmpty, IsNumber, IsOptional } from "class-validator";
import { BaseFindDto } from "../../utils/base-find.dto";
import { Statistics } from "../entity/statistics.entity";
import { StatisticsPeriod } from "../statistics.constants";

export class FindStatisticsTrendingReviewsDto extends BaseFindDto<Statistics> {
@IsOptional()
@IsNumber()
gameId?: number;
@IsNotEmpty()
@IsEnum(StatisticsPeriod)
period: StatisticsPeriod;
}
85 changes: 31 additions & 54 deletions src/statistics/statistics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { UserLike } from "./entity/user-like.entity";
import { UserView } from "./entity/user-view.entity";
import {
StatisticsActionType,
StatisticsPeriod,
StatisticsPeriodToMinusDays,
StatisticsSourceType,
} from "./statistics.constants";
Expand All @@ -29,7 +30,6 @@ import { TPaginationData } from "../utils/pagination/pagination-response.dto";

@Injectable()
export class StatisticsService {
private readonly DEFAULT_TRENDING_LIMIT = 20;
constructor(
@InjectRepository(Statistics)
private readonly statisticsRepository: Repository<Statistics>,
Expand Down Expand Up @@ -217,64 +217,41 @@ export class StatisticsService {

private async findTrendingItems(
baseFindOptions: FindManyOptions<Statistics>,
period: StatisticsPeriod = StatisticsPeriod.WEEK,
findWhereOptions?: FindOptionsWhere<Statistics>,
limit: number = this.DEFAULT_TRENDING_LIMIT,
): Promise<TPaginationData<Statistics>> {
// Avoids timezone-related issues
// Just trust me
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const periods = Object.values(StatisticsPeriodToMinusDays);
const lastPeriod = periods[periods.length - 1];
const minimumItems =
limit > this.DEFAULT_TRENDING_LIMIT
? this.DEFAULT_TRENDING_LIMIT
: limit;
for (const period of periods) {
const periodDate = this.getPreviousDate(period);
const [statistics, totalCount] =
await this.statisticsRepository.findAndCount({
...baseFindOptions,
where: [
{
...findWhereOptions,
views: {
createdAt: Between(periodDate, tomorrow),
},
},
{
...findWhereOptions,
likes: {
createdAt: Between(periodDate, tomorrow),
},
},
{
...findWhereOptions,
likesCount: 0,
},
{
...findWhereOptions,
viewsCount: 0,
},
],
order: {
likesCount: "DESC",
viewsCount: "DESC",
const periodMinusDays = StatisticsPeriodToMinusDays[period];
const periodDate = this.getPreviousDate(periodMinusDays);
return await this.statisticsRepository.findAndCount({
...baseFindOptions,
where: [
{
...findWhereOptions,
views: {
createdAt: Between(periodDate, tomorrow),
},
});
const itemsWithLikesOrViews = statistics.filter(
(s) => s.likesCount > 0 || s.viewsCount > 0,
);
if (
itemsWithLikesOrViews.length < minimumItems &&
period < lastPeriod
) {
continue;
}
return [statistics, totalCount];
}

return [[], 0];
},
{
...findWhereOptions,
likes: {
createdAt: Between(periodDate, tomorrow),
},
},
{
...findWhereOptions,
likesCount: 0,
viewsCount: 0,
},
],
order: {
likesCount: "DESC",
viewsCount: "DESC",
},
});
}

async findTrendingGames(dto: FindStatisticsTrendingGamesDto) {
Expand All @@ -286,8 +263,8 @@ export class StatisticsService {
};
return await this.findTrendingItems(
findOptions,
dto.period,
findOptionsWhere,
dto.limit,
);
}

Expand All @@ -305,8 +282,8 @@ export class StatisticsService {
};
return await this.findTrendingItems(
baseFindOptions,
dto.period,
findOptionsWhere,
dto.limit,
);
}

Expand Down

0 comments on commit 5746664

Please sign in to comment.