mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
Merge branch 'feature/profile-redesign' of github.com:hydralauncher/hydra into feature/profile-redesign
This commit is contained in:
commit
5432ef311a
9 changed files with 85 additions and 25 deletions
|
@ -126,7 +126,9 @@
|
||||||
"stats": "Stats",
|
"stats": "Stats",
|
||||||
"download_count": "Downloads",
|
"download_count": "Downloads",
|
||||||
"player_count": "Active players",
|
"player_count": "Active players",
|
||||||
"download_error": "This download option is not available"
|
"download_error": "This download option is not available",
|
||||||
|
"download": "Download",
|
||||||
|
"executable_path_in_use": "Executable already in use by \"{{game}}\""
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Activate Hydra",
|
"title": "Activate Hydra",
|
||||||
|
|
|
@ -122,7 +122,9 @@
|
||||||
"stats": "Estatísticas",
|
"stats": "Estatísticas",
|
||||||
"download_count": "Downloads",
|
"download_count": "Downloads",
|
||||||
"player_count": "Jogadores ativos",
|
"player_count": "Jogadores ativos",
|
||||||
"download_error": "Essa opção de download falhou"
|
"download_error": "Essa opção de download falhou",
|
||||||
|
"download": "Baixar",
|
||||||
|
"executable_path_in_use": "Executável em uso por \"{{game}}\""
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Ativação",
|
"title": "Ativação",
|
||||||
|
|
|
@ -111,7 +111,9 @@
|
||||||
"download_paused": "Transferência pausada",
|
"download_paused": "Transferência pausada",
|
||||||
"last_downloaded_option": "Última opção transferida",
|
"last_downloaded_option": "Última opção transferida",
|
||||||
"create_shortcut_success": "Atalho criado com sucesso",
|
"create_shortcut_success": "Atalho criado com sucesso",
|
||||||
"create_shortcut_error": "Erro ao criar atalho"
|
"create_shortcut_error": "Erro ao criar atalho",
|
||||||
|
"download": "Transferir",
|
||||||
|
"executable_path_in_use": "Executável em uso por \"{{game}}\""
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Ativação",
|
"title": "Ativação",
|
||||||
|
|
|
@ -22,6 +22,7 @@ import "./library/open-game-executable-path";
|
||||||
import "./library/open-game-installer";
|
import "./library/open-game-installer";
|
||||||
import "./library/open-game-installer-path";
|
import "./library/open-game-installer-path";
|
||||||
import "./library/update-executable-path";
|
import "./library/update-executable-path";
|
||||||
|
import "./library/verify-executable-path";
|
||||||
import "./library/remove-game";
|
import "./library/remove-game";
|
||||||
import "./library/remove-game-from-library";
|
import "./library/remove-game-from-library";
|
||||||
import "./misc/open-external";
|
import "./misc/open-external";
|
||||||
|
|
13
src/main/events/library/verify-executable-path.ts
Normal file
13
src/main/events/library/verify-executable-path.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { gameRepository } from "@main/repository";
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
|
const verifyExecutablePathInUse = async (
|
||||||
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
|
executablePath: string
|
||||||
|
) => {
|
||||||
|
return gameRepository.findOne({
|
||||||
|
where: { executablePath },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("verifyExecutablePathInUse", verifyExecutablePathInUse);
|
|
@ -75,6 +75,8 @@ contextBridge.exposeInMainWorld("electron", {
|
||||||
ipcRenderer.invoke("createGameShortcut", id),
|
ipcRenderer.invoke("createGameShortcut", id),
|
||||||
updateExecutablePath: (id: number, executablePath: string) =>
|
updateExecutablePath: (id: number, executablePath: string) =>
|
||||||
ipcRenderer.invoke("updateExecutablePath", id, executablePath),
|
ipcRenderer.invoke("updateExecutablePath", id, executablePath),
|
||||||
|
verifyExecutablePathInUse: (executablePath: string) =>
|
||||||
|
ipcRenderer.invoke("verifyExecutablePathInUse", executablePath),
|
||||||
getLibrary: () => ipcRenderer.invoke("getLibrary"),
|
getLibrary: () => ipcRenderer.invoke("getLibrary"),
|
||||||
openGameInstaller: (gameId: number) =>
|
openGameInstaller: (gameId: number) =>
|
||||||
ipcRenderer.invoke("openGameInstaller", gameId),
|
ipcRenderer.invoke("openGameInstaller", gameId),
|
||||||
|
|
1
src/renderer/src/declaration.d.ts
vendored
1
src/renderer/src/declaration.d.ts
vendored
|
@ -72,6 +72,7 @@ declare global {
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
createGameShortcut: (id: number) => Promise<boolean>;
|
createGameShortcut: (id: number) => Promise<boolean>;
|
||||||
updateExecutablePath: (id: number, executablePath: string) => Promise<void>;
|
updateExecutablePath: (id: number, executablePath: string) => Promise<void>;
|
||||||
|
verifyExecutablePathInUse: (executablePath: string) => Promise<Game>;
|
||||||
getLibrary: () => Promise<LibraryGame[]>;
|
getLibrary: () => Promise<LibraryGame[]>;
|
||||||
openGameInstaller: (gameId: number) => Promise<boolean>;
|
openGameInstaller: (gameId: number) => Promise<boolean>;
|
||||||
openGameInstallerPath: (gameId: number) => Promise<boolean>;
|
openGameInstallerPath: (gameId: number) => Promise<boolean>;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next";
|
||||||
import * as styles from "./hero-panel-actions.css";
|
import * as styles from "./hero-panel-actions.css";
|
||||||
|
|
||||||
import { gameDetailsContext } from "@renderer/context";
|
import { gameDetailsContext } from "@renderer/context";
|
||||||
|
import { DownloadIcon } from "@renderer/components/sidebar/download-icon";
|
||||||
|
|
||||||
export function HeroPanelActions() {
|
export function HeroPanelActions() {
|
||||||
const [toggleLibraryGameDisabled, setToggleLibraryGameDisabled] =
|
const [toggleLibraryGameDisabled, setToggleLibraryGameDisabled] =
|
||||||
|
@ -25,6 +26,11 @@ export function HeroPanelActions() {
|
||||||
selectGameExecutable,
|
selectGameExecutable,
|
||||||
} = useContext(gameDetailsContext);
|
} = useContext(gameDetailsContext);
|
||||||
|
|
||||||
|
const { lastPacket } = useDownload();
|
||||||
|
|
||||||
|
const isGameDownloading =
|
||||||
|
game?.status === "active" && lastPacket?.game.id === game?.id;
|
||||||
|
|
||||||
const { updateLibrary } = useLibrary();
|
const { updateLibrary } = useLibrary();
|
||||||
|
|
||||||
const { t } = useTranslation("game_details");
|
const { t } = useTranslation("game_details");
|
||||||
|
@ -84,6 +90,47 @@ export function HeroPanelActions() {
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const gameActionButton = () => {
|
||||||
|
if (isGameRunning) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={closeGame}
|
||||||
|
theme="outline"
|
||||||
|
disabled={deleting}
|
||||||
|
className={styles.heroPanelAction}
|
||||||
|
>
|
||||||
|
{t("close")}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (game?.executablePath) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={openGame}
|
||||||
|
theme="outline"
|
||||||
|
disabled={deleting || isGameRunning}
|
||||||
|
className={styles.heroPanelAction}
|
||||||
|
>
|
||||||
|
<PlayIcon />
|
||||||
|
{t("play")}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={() => setShowRepacksModal(true)}
|
||||||
|
theme="outline"
|
||||||
|
disabled={isGameDownloading || !repacks.length}
|
||||||
|
className={styles.heroPanelAction}
|
||||||
|
>
|
||||||
|
<DownloadIcon isDownloading={false} />
|
||||||
|
{t("download")}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
if (repacks.length && !game) {
|
if (repacks.length && !game) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -96,26 +143,7 @@ export function HeroPanelActions() {
|
||||||
if (game) {
|
if (game) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
{isGameRunning ? (
|
{gameActionButton()}
|
||||||
<Button
|
|
||||||
onClick={closeGame}
|
|
||||||
theme="outline"
|
|
||||||
disabled={deleting}
|
|
||||||
className={styles.heroPanelAction}
|
|
||||||
>
|
|
||||||
{t("close")}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
onClick={openGame}
|
|
||||||
theme="outline"
|
|
||||||
disabled={deleting || isGameRunning}
|
|
||||||
className={styles.heroPanelAction}
|
|
||||||
>
|
|
||||||
<PlayIcon />
|
|
||||||
{t("play")}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className={styles.separator} />
|
<div className={styles.separator} />
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,17 @@ export function GameOptionsModal({
|
||||||
const path = await selectGameExecutable();
|
const path = await selectGameExecutable();
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
await window.electron.updateExecutablePath(game.id, path);
|
const gameUsingPath =
|
||||||
updateGame();
|
await window.electron.verifyExecutablePathInUse(path);
|
||||||
|
|
||||||
|
if (gameUsingPath) {
|
||||||
|
showErrorToast(
|
||||||
|
t("executable_path_in_use", { game: gameUsingPath.title })
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.electron.updateExecutablePath(game.id, path).then(updateGame);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue