feat: prefer to play achievement sound in browser window if available

This commit is contained in:
Zamitto 2025-01-05 13:31:06 -03:00
parent 9bb89a1dee
commit 47f77310f3
7 changed files with 42 additions and 19 deletions

View File

@ -1,9 +1,5 @@
import { DownloadManager, Ludusavi, startMainLoop } from "./services";
import {
downloadQueueRepository,
gameRepository,
userPreferencesRepository,
} from "./repository";
import { downloadQueueRepository, gameRepository } from "./repository";
import { UserPreferences } from "./entity";
import { RealDebridClient } from "./services/download/real-debrid";
import { HydraApi } from "./services/hydra-api";

View File

@ -144,7 +144,7 @@ const processAchievementFileDiff = async (
export class AchievementWatcherManager {
private static hasFinishedMergingWithRemote = false;
public static watchAchievements = () => {
public static watchAchievements() {
if (!this.hasFinishedMergingWithRemote) return;
if (process.platform === "win32") {
@ -152,12 +152,12 @@ export class AchievementWatcherManager {
}
return watchAchievementsWithWine();
};
}
private static preProcessGameAchievementFiles = (
private static preProcessGameAchievementFiles(
game: Game,
gameAchievementFiles: AchievementFile[]
) => {
) {
const unlockedAchievements: UnlockedAchievement[] = [];
for (const achievementFile of gameAchievementFiles) {
const parsedAchievements = parseAchievementFile(
@ -185,9 +185,9 @@ export class AchievementWatcherManager {
}
return mergeAchievements(game, unlockedAchievements, false);
};
}
private static preSearchAchievementsWindows = async () => {
private static async preSearchAchievementsWindows() {
const games = await gameRepository.find({
where: {
isDeleted: false,
@ -213,9 +213,9 @@ export class AchievementWatcherManager {
return this.preProcessGameAchievementFiles(game, gameAchievementFiles);
})
);
};
}
private static preSearchAchievementsWithWine = async () => {
private static async preSearchAchievementsWithWine() {
const games = await gameRepository.find({
where: {
isDeleted: false,
@ -233,9 +233,9 @@ export class AchievementWatcherManager {
return this.preProcessGameAchievementFiles(game, gameAchievementFiles);
})
);
};
}
public static preSearchAchievements = async () => {
public static async preSearchAchievements() {
try {
const newAchievementsCount =
process.platform === "win32"
@ -261,5 +261,5 @@ export class AchievementWatcherManager {
}
this.hasFinishedMergingWithRemote = true;
};
}
}

View File

@ -11,6 +11,7 @@ import { achievementSoundPath } from "@main/constants";
import icon from "@resources/icon.png?asset";
import { NotificationOptions, toXmlString } from "./xml";
import { logger } from "../logger";
import { WindowManager } from "../window-manager";
async function downloadImage(url: string | null) {
if (!url) return undefined;
@ -93,7 +94,9 @@ export const publishCombinedNewAchievementNotification = async (
toastXml: toXmlString(options),
}).show();
if (process.platform !== "linux") {
if (WindowManager.mainWindow) {
WindowManager.mainWindow.webContents.send("on-achievement-unlocked");
} else if (process.platform !== "linux") {
sound.play(achievementSoundPath);
}
};
@ -140,7 +143,9 @@ export const publishNewAchievementNotification = async (info: {
toastXml: toXmlString(options),
}).show();
if (process.platform !== "linux") {
if (WindowManager.mainWindow) {
WindowManager.mainWindow.webContents.send("on-achievement-unlocked");
} else if (process.platform !== "linux") {
sound.play(achievementSoundPath);
}
};

View File

@ -148,6 +148,11 @@ contextBridge.exposeInMainWorld("electron", {
return () =>
ipcRenderer.removeListener("on-library-batch-complete", listener);
},
onAchievementUnlocked: (cb: () => void) => {
const listener = (_event: Electron.IpcRendererEvent) => cb();
ipcRenderer.on("on-achievement-unlocked", listener);
return () => ipcRenderer.removeListener("on-achievement-unlocked", listener);
},
/* Hardware */
getDiskFreeSpace: (path: string) =>

View File

@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef } from "react";
import achievementSound from "@renderer/assets/audio/achievement.wav";
import { Sidebar, BottomPanel, Header, Toast } from "@renderer/components";
import {
@ -233,6 +233,22 @@ export function App() {
downloadSourcesWorker.postMessage(["SYNC_DOWNLOAD_SOURCES", id]);
}, [updateRepacks]);
const playAudio = useCallback(() => {
const audio = new Audio(achievementSound);
audio.volume = 0.2;
audio.play();
}, []);
useEffect(() => {
const unsubscribe = window.electron.onAchievementUnlocked(() => {
playAudio();
});
return () => {
unsubscribe();
};
}, [playAudio]);
const handleToastClose = useCallback(() => {
dispatch(closeToast());
}, [dispatch]);

Binary file not shown.

View File

@ -133,6 +133,7 @@ declare global {
minimized: boolean;
}) => Promise<void>;
authenticateRealDebrid: (apiToken: string) => Promise<RealDebridUser>;
onAchievementUnlocked: (cb: () => void) => () => Electron.IpcRenderer;
/* Download sources */
putDownloadSource: (