mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
feat: prefer to play achievement sound in browser window if available
This commit is contained in:
parent
39572702a0
commit
6d86002977
7 changed files with 42 additions and 19 deletions
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) =>
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
BIN
src/renderer/src/assets/audio/achievement.wav
Normal file
BIN
src/renderer/src/assets/audio/achievement.wav
Normal file
Binary file not shown.
1
src/renderer/src/declaration.d.ts
vendored
1
src/renderer/src/declaration.d.ts
vendored
|
@ -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: (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue