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 39572702a0
commit 6d86002977
7 changed files with 42 additions and 19 deletions

View file

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

View file

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

View file

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

View file

@ -148,6 +148,11 @@ contextBridge.exposeInMainWorld("electron", {
return () => return () =>
ipcRenderer.removeListener("on-library-batch-complete", listener); 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 */ /* Hardware */
getDiskFreeSpace: (path: string) => getDiskFreeSpace: (path: string) =>

View file

@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef } from "react"; import { useCallback, useEffect, useRef } from "react";
import achievementSound from "@renderer/assets/audio/achievement.wav";
import { Sidebar, BottomPanel, Header, Toast } from "@renderer/components"; import { Sidebar, BottomPanel, Header, Toast } from "@renderer/components";
import { import {
@ -233,6 +233,22 @@ export function App() {
downloadSourcesWorker.postMessage(["SYNC_DOWNLOAD_SOURCES", id]); downloadSourcesWorker.postMessage(["SYNC_DOWNLOAD_SOURCES", id]);
}, [updateRepacks]); }, [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(() => { const handleToastClose = useCallback(() => {
dispatch(closeToast()); dispatch(closeToast());
}, [dispatch]); }, [dispatch]);

Binary file not shown.

View file

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