mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-02-01 07:11:02 +00:00
feat: add If-Modified-Since header to get-game-achievement-data
This commit is contained in:
@@ -3,6 +3,9 @@ import type { GameShop, SteamAchievement } from "@types";
|
|||||||
import { UserNotLoggedInError } from "@shared";
|
import { UserNotLoggedInError } from "@shared";
|
||||||
import { logger } from "../logger";
|
import { logger } from "../logger";
|
||||||
import { db, gameAchievementsSublevel, levelKeys } from "@main/level";
|
import { db, gameAchievementsSublevel, levelKeys } from "@main/level";
|
||||||
|
import { AxiosError } from "axios";
|
||||||
|
|
||||||
|
const LOCAL_CACHE_EXPIRATION = 1000 * 60 * 30; // 30 minutes
|
||||||
|
|
||||||
export const getGameAchievementData = async (
|
export const getGameAchievementData = async (
|
||||||
objectId: string,
|
objectId: string,
|
||||||
@@ -18,7 +21,7 @@ export const getGameAchievementData = async (
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
cachedAchievements?.achievements &&
|
cachedAchievements?.achievements &&
|
||||||
Date.now() < (cachedAchievements.cacheExpiresTimestamp ?? 0)
|
Date.now() < (cachedAchievements.updatedAt ?? 0) + LOCAL_CACHE_EXPIRATION
|
||||||
) {
|
) {
|
||||||
return cachedAchievements.achievements;
|
return cachedAchievements.achievements;
|
||||||
}
|
}
|
||||||
@@ -29,18 +32,24 @@ export const getGameAchievementData = async (
|
|||||||
})
|
})
|
||||||
.then((language) => language || "en");
|
.then((language) => language || "en");
|
||||||
|
|
||||||
return HydraApi.get<SteamAchievement[]>("/games/achievements", {
|
return HydraApi.get<SteamAchievement[]>(
|
||||||
shop,
|
"/games/achievements",
|
||||||
objectId,
|
{
|
||||||
language,
|
shop,
|
||||||
})
|
objectId,
|
||||||
|
language,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ifModifiedSince: cachedAchievements?.updatedAt
|
||||||
|
? new Date(cachedAchievements?.updatedAt)
|
||||||
|
: undefined,
|
||||||
|
}
|
||||||
|
)
|
||||||
.then(async (achievements) => {
|
.then(async (achievements) => {
|
||||||
await gameAchievementsSublevel.put(gameKey, {
|
await gameAchievementsSublevel.put(gameKey, {
|
||||||
unlockedAchievements: cachedAchievements?.unlockedAchievements ?? [],
|
unlockedAchievements: cachedAchievements?.unlockedAchievements ?? [],
|
||||||
achievements,
|
achievements,
|
||||||
cacheExpiresTimestamp: achievements.length
|
updatedAt: Date.now() + LOCAL_CACHE_EXPIRATION,
|
||||||
? Date.now() + 1000 * 60 * 30 // 30 minutes
|
|
||||||
: undefined,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return achievements;
|
return achievements;
|
||||||
@@ -50,6 +59,12 @@ export const getGameAchievementData = async (
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isNotModified = (err as AxiosError)?.response?.status === 304;
|
||||||
|
|
||||||
|
if (isNotModified) {
|
||||||
|
return cachedAchievements?.achievements ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
logger.error("Failed to get game achievements for", objectId, err);
|
logger.error("Failed to get game achievements for", objectId, err);
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const saveAchievementsOnLocal = async (
|
|||||||
await gameAchievementsSublevel.put(levelKey, {
|
await gameAchievementsSublevel.put(levelKey, {
|
||||||
achievements: gameAchievement?.achievements ?? [],
|
achievements: gameAchievement?.achievements ?? [],
|
||||||
unlockedAchievements: unlockedAchievements,
|
unlockedAchievements: unlockedAchievements,
|
||||||
cacheExpiresTimestamp: gameAchievement?.cacheExpiresTimestamp,
|
updatedAt: gameAchievement?.updatedAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!sendUpdateEvent) return;
|
if (!sendUpdateEvent) return;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import axios, { AxiosError, AxiosInstance } from "axios";
|
import axios, { AxiosError, AxiosHeaders, AxiosInstance } from "axios";
|
||||||
import { WindowManager } from "./window-manager";
|
import { WindowManager } from "./window-manager";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
import { uploadGamesBatch } from "./library-sync";
|
import { uploadGamesBatch } from "./library-sync";
|
||||||
@@ -16,6 +16,7 @@ import { WSClient } from "./ws/ws-client";
|
|||||||
interface HydraApiOptions {
|
interface HydraApiOptions {
|
||||||
needsAuth?: boolean;
|
needsAuth?: boolean;
|
||||||
needsSubscription?: boolean;
|
needsSubscription?: boolean;
|
||||||
|
ifModifiedSince?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HydraApiUserAuth {
|
interface HydraApiUserAuth {
|
||||||
@@ -337,8 +338,13 @@ export class HydraApi {
|
|||||||
) {
|
) {
|
||||||
await this.validateOptions(options);
|
await this.validateOptions(options);
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
...this.getAxiosConfig().headers,
|
||||||
|
"If-Modified-Since": options?.ifModifiedSince?.toUTCString(),
|
||||||
|
};
|
||||||
|
|
||||||
return this.instance
|
return this.instance
|
||||||
.get<T>(url, { params, ...this.getAxiosConfig() })
|
.get<T>(url, { params, ...this.getAxiosConfig(), headers })
|
||||||
.then((response) => response.data)
|
.then((response) => response.data)
|
||||||
.catch(this.handleUnauthorizedError);
|
.catch(this.handleUnauthorizedError);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export interface Download {
|
|||||||
export interface GameAchievement {
|
export interface GameAchievement {
|
||||||
achievements: SteamAchievement[];
|
achievements: SteamAchievement[];
|
||||||
unlockedAchievements: UnlockedAchievement[];
|
unlockedAchievements: UnlockedAchievement[];
|
||||||
cacheExpiresTimestamp: number | undefined;
|
updatedAt: number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AchievementCustomNotificationPosition =
|
export type AchievementCustomNotificationPosition =
|
||||||
|
|||||||
Reference in New Issue
Block a user