feat: refactor

This commit is contained in:
Zamitto 2024-10-09 23:11:28 -03:00
parent 3dcdcae9a7
commit c8022896a6
7 changed files with 111 additions and 50 deletions

View File

@ -1,23 +1,81 @@
import type { import type {
AchievementData, AchievementData,
GameAchievement,
GameShop, GameShop,
RemoteUnlockedAchievement,
UnlockedAchievement, UnlockedAchievement,
UserAchievement,
} from "@types"; } from "@types";
import { registerEvent } from "../register-event"; import { registerEvent } from "../register-event";
import { import {
gameAchievementRepository, gameAchievementRepository,
userAuthRepository, userPreferencesRepository,
} from "@main/repository"; } from "@main/repository";
import { getGameAchievementData } from "@main/services/achievements/get-game-achievement-data"; import { getGameAchievementData } from "@main/services/achievements/get-game-achievement-data";
import { HydraApi } from "@main/services"; import { HydraApi, logger } from "@main/services";
const getAchievements = async ( const getAchievementLocalUser = async (shop: string, objectId: string) => {
const cachedAchievements = await gameAchievementRepository.findOne({
where: { objectId, shop },
});
const achievementsData: AchievementData[] = cachedAchievements?.achievements
? JSON.parse(cachedAchievements.achievements)
: await getGameAchievementData(objectId, shop);
const unlockedAchievements = JSON.parse(
cachedAchievements?.unlockedAchievements || "[]"
) as UnlockedAchievement[];
return achievementsData
.map((achievementData) => {
logger.info("unclockedAchievements", unlockedAchievements);
const unlockedAchiementData = unlockedAchievements.find(
(localAchievement) => {
return (
localAchievement.name.toUpperCase() ==
achievementData.name.toUpperCase()
);
}
);
const icongray = achievementData.icongray.endsWith("/")
? achievementData.icon
: achievementData.icongray;
if (unlockedAchiementData) {
return {
...achievementData,
unlocked: true,
unlockTime: unlockedAchiementData.unlockTime,
};
}
return {
...achievementData,
unlocked: false,
unlockTime: null,
icon: icongray,
} as UserAchievement;
})
.sort((a, b) => {
if (a.unlocked && !b.unlocked) return -1;
if (!a.unlocked && b.unlocked) return 1;
if (a.unlocked && b.unlocked) {
return b.unlockTime! - a.unlockTime!;
}
return Number(a.hidden) - Number(b.hidden);
});
};
const getAchievementsRemoteUser = async (
shop: string, shop: string,
objectId: string, objectId: string,
userId?: string userId: string
) => { ) => {
const userAuth = await userAuthRepository.findOne({ where: { userId } }); const userPreferences = await userPreferencesRepository.findOne({
where: { id: 1 },
});
const cachedAchievements = await gameAchievementRepository.findOne({ const cachedAchievements = await gameAchievementRepository.findOne({
where: { objectId, shop }, where: { objectId, shop },
@ -27,31 +85,9 @@ const getAchievements = async (
? JSON.parse(cachedAchievements.achievements) ? JSON.parse(cachedAchievements.achievements)
: await getGameAchievementData(objectId, shop); : await getGameAchievementData(objectId, shop);
if (!userId || userAuth) { const unlockedAchievements = await HydraApi.get<RemoteUnlockedAchievement[]>(
const unlockedAchievements = JSON.parse(
cachedAchievements?.unlockedAchievements || "[]"
) as UnlockedAchievement[];
return { achievementsData, unlockedAchievements };
}
const unlockedAchievements = await HydraApi.get<UnlockedAchievement[]>(
`/users/${userId}/games/achievements`, `/users/${userId}/games/achievements`,
{ shop, objectId, language: "en" } { shop, objectId, language: userPreferences?.language || "en" }
);
return { achievementsData, unlockedAchievements };
};
export const getGameAchievements = async (
objectId: string,
shop: GameShop,
userId?: string
): Promise<GameAchievement[]> => {
const { achievementsData, unlockedAchievements } = await getAchievements(
shop,
objectId,
userId
); );
return achievementsData return achievementsData
@ -74,7 +110,6 @@ export const getGameAchievements = async (
...achievementData, ...achievementData,
unlocked: true, unlocked: true,
unlockTime: unlockedAchiementData.unlockTime, unlockTime: unlockedAchiementData.unlockTime,
icongray,
}; };
} }
@ -82,8 +117,8 @@ export const getGameAchievements = async (
...achievementData, ...achievementData,
unlocked: false, unlocked: false,
unlockTime: null, unlockTime: null,
icongray, icon: icongray,
} as GameAchievement; } as UserAchievement;
}) })
.sort((a, b) => { .sort((a, b) => {
if (a.unlocked && !b.unlocked) return -1; if (a.unlocked && !b.unlocked) return -1;
@ -95,12 +130,24 @@ export const getGameAchievements = async (
}); });
}; };
export const getGameAchievements = async (
objectId: string,
shop: GameShop,
userId?: string
): Promise<UserAchievement[]> => {
if (!userId) {
return getAchievementLocalUser(shop, objectId);
}
return getAchievementsRemoteUser(shop, objectId, userId);
};
const getGameAchievementsEvent = async ( const getGameAchievementsEvent = async (
_event: Electron.IpcMainInvokeEvent, _event: Electron.IpcMainInvokeEvent,
objectId: string, objectId: string,
shop: GameShop, shop: GameShop,
userId?: string userId?: string
): Promise<GameAchievement[]> => { ): Promise<UserAchievement[]> => {
return getGameAchievements(objectId, shop, userId); return getGameAchievements(objectId, shop, userId);
}; };

View File

@ -12,11 +12,11 @@ import { useAppDispatch, useAppSelector, useDownload } from "@renderer/hooks";
import type { import type {
Game, Game,
GameAchievement,
GameRepack, GameRepack,
GameShop, GameShop,
GameStats, GameStats,
ShopDetails, ShopDetails,
UserAchievement,
} from "@types"; } from "@types";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@ -64,7 +64,7 @@ export function GameDetailsContextProvider({
shop, shop,
}: GameDetailsContextProps) { }: GameDetailsContextProps) {
const [shopDetails, setShopDetails] = useState<ShopDetails | null>(null); const [shopDetails, setShopDetails] = useState<ShopDetails | null>(null);
const [achievements, setAchievements] = useState<GameAchievement[]>([]); const [achievements, setAchievements] = useState<UserAchievement[]>([]);
const [game, setGame] = useState<Game | null>(null); const [game, setGame] = useState<Game | null>(null);
const [hasNSFWContentBlocked, setHasNSFWContentBlocked] = useState(false); const [hasNSFWContentBlocked, setHasNSFWContentBlocked] = useState(false);

View File

@ -1,10 +1,10 @@
import type { import type {
Game, Game,
GameAchievement,
GameRepack, GameRepack,
GameShop, GameShop,
GameStats, GameStats,
ShopDetails, ShopDetails,
UserAchievement,
} from "@types"; } from "@types";
export interface GameDetailsContext { export interface GameDetailsContext {
@ -20,7 +20,7 @@ export interface GameDetailsContext {
showRepacksModal: boolean; showRepacksModal: boolean;
showGameOptionsModal: boolean; showGameOptionsModal: boolean;
stats: GameStats | null; stats: GameStats | null;
achievements: GameAchievement[]; achievements: UserAchievement[];
hasNSFWContentBlocked: boolean; hasNSFWContentBlocked: boolean;
setGameColor: React.Dispatch<React.SetStateAction<string>>; setGameColor: React.Dispatch<React.SetStateAction<string>>;
selectGameExecutable: () => Promise<string | null>; selectGameExecutable: () => Promise<string | null>;

View File

@ -28,6 +28,7 @@ import type {
GameAchievement, GameAchievement,
GameArtifact, GameArtifact,
LudusaviBackup, LudusaviBackup,
UserAchievement,
} from "@types"; } from "@types";
import type { AxiosProgressEvent } from "axios"; import type { AxiosProgressEvent } from "axios";
import type { DiskSpace } from "check-disk-space"; import type { DiskSpace } from "check-disk-space";
@ -68,7 +69,7 @@ declare global {
objectId: string, objectId: string,
shop: GameShop, shop: GameShop,
userId?: string userId?: string
) => Promise<GameAchievement[]>; ) => Promise<UserAchievement[]>;
onAchievementUnlocked: ( onAchievementUnlocked: (
cb: ( cb: (
objectId: string, objectId: string,

View File

@ -1,7 +1,7 @@
import { setHeaderTitle } from "@renderer/features"; import { setHeaderTitle } from "@renderer/features";
import { useAppDispatch, useDate } from "@renderer/hooks"; import { useAppDispatch, useDate } from "@renderer/hooks";
import { steamUrlBuilder } from "@shared"; import { steamUrlBuilder } from "@shared";
import type { GameAchievement, GameShop } from "@types"; import type { GameShop, UserAchievement } from "@types";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate, useSearchParams } from "react-router-dom"; import { useNavigate, useSearchParams } from "react-router-dom";
@ -28,7 +28,7 @@ export function Achievement() {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [achievements, setAchievements] = useState<GameAchievement[]>([]); const [achievements, setAchievements] = useState<UserAchievement[]>([]);
useEffect(() => { useEffect(() => {
if (objectId && shop) { if (objectId && shop) {
@ -130,9 +130,7 @@ export function Achievement() {
className={styles.listItemImage({ className={styles.listItemImage({
unlocked: achievement.unlocked, unlocked: achievement.unlocked,
})} })}
src={ src={achievement.icon}
achievement.unlocked ? achievement.icon : achievement.icongray
}
alt={achievement.displayName} alt={achievement.displayName}
loading="lazy" loading="lazy"
/> />

View File

@ -91,11 +91,7 @@ export function Sidebar() {
className={styles.listItemImage({ className={styles.listItemImage({
unlocked: achievement.unlocked, unlocked: achievement.unlocked,
})} })}
src={ src={achievement.icon}
achievement.unlocked
? achievement.icon
: achievement.icongray
}
alt={achievement.displayName} alt={achievement.displayName}
loading="lazy" loading="lazy"
/> />

View File

@ -37,15 +37,34 @@ export interface AchievementData {
hidden: boolean; hidden: boolean;
} }
export interface UserAchievement {
name: string;
hidden: boolean;
displayName: string;
description?: string;
unlocked: boolean;
unlockTime: number | null;
icon: string;
}
export interface RemoteUnlockedAchievement {
name: string;
hidden: boolean;
icon: string;
displayName: string;
description?: string;
unlockTime: number;
}
export interface GameAchievement { export interface GameAchievement {
name: string; name: string;
hidden: boolean;
displayName: string; displayName: string;
description?: string; description?: string;
unlocked: boolean; unlocked: boolean;
unlockTime: number | null; unlockTime: number | null;
icon: string; icon: string;
icongray: string; icongray: string;
hidden: boolean;
} }
export type ShopDetails = SteamAppDetails & { export type ShopDetails = SteamAppDetails & {