diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index 89a76ea6..60ca1267 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -601,6 +601,10 @@ "ENOSPC": "Die Festplatte ist voll, machen Sie Platz und versuchen Sie es erneut.", "UNKNOWN_ERROR": "Ein unbekannter Fehler ist beim Verknüpfen des Ordners aufgetreten." } + }, + "adding-error": { + "title": "Das Hinzufügen des freigegebenen Ordners ist fehlgeschlagen", + "msg": "Sie können \"{folder}\" nicht zu freigegebenen Ordnern hinzufügen." } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "Ordner hinzufügen", "link-folder": "Ordner verknüpfen", "unlink-folder": "Ordner-Verknüpfung aufheben", - "link-all": "Alle verlinken" + "link-all": "Alle verlinken", + "remove-from-the-list": "Aus der Liste entfernen" } }, + "adding-shared-folder": { + "title": "Freigegebenen Ordner hinzufügen", + "description": "Beim Verknüpfen des Ordners \"{folder}\" können Probleme auftreten. Möchten Sie ihn wirklich hinzufügen?" + }, "create-launch-shortcut": { "title": "Verknüpfung erstellen", "desc": "Das Erstellen einer Verknüpfung ermöglicht es dir, Beat Saber mit den ausgewählten Optionen zu starten, ohne durch BSManager zu gehen.", diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 12ff1c77..2b11836a 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -601,6 +601,10 @@ "ENOSPC": "The disk is full, make some space and try again.", "UNKNOWN_ERROR": "An unknown error has occurred while linking the folder." } + }, + "adding-error": { + "title": "Adding shared folder failed", + "msg": "You can't add \"{folder}\" to shared folders." } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "Add Folder", "link-folder": "Link Folder", "unlink-folder": "Unlink Folder", - "link-all": "Link all" + "link-all": "Link all", + "remove-from-the-list": "Remove from the list" } }, + "adding-shared-folder": { + "title": "Adding Shared Folder", + "description": "You might experience issues when linking the \"{folder}\" folder. Are you sure you want to add it?" + }, "create-launch-shortcut": { "title": "Create a shortcut", "desc": "Creating a shortcut will allow you to start Beat Saber with the chosen options without going through BSManager.", diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 8eeb518a..553cf1cb 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -601,6 +601,10 @@ "ENOSPC": "El disco está lleno, libera espacio e inténtalo de nuevo.", "UNKNOWN_ERROR": "Se ha producido un error desconocido al enlazar la carpeta." } + }, + "adding-error": { + "title": "Error al agregar una carpeta compartida", + "msg": "No puedes agregar \"{folder}\" a las carpetas compartidas." } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "Añadir Carpeta", "link-folder": "Enlazar Carpeta", "unlink-folder": "Desenlazar Carpeta", - "link-all": "Enlazar todo" + "link-all": "Enlazar todo", + "remove-from-the-list": "Eliminar de la lista" } }, + "adding-shared-folder": { + "title": "Agregar una carpeta compartida", + "description": "Es posible que experimentes problemas al vincular la carpeta \"{folder}\". ¿Estás seguro de que deseas agregarla?" + }, "create-launch-shortcut": { "title": "Crear un atajo", "desc": "Crear un atajo te permitirá iniciar Beat Saber con las opciones seleccionadas sin pasar por BSManager.", diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 81bc6068..c064e8e8 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -601,6 +601,10 @@ "ENOSPC": "Le disque est plein, faites de la place et réessayez.", "UNKNOWN_ERROR": "Une erreur inconnue est survenue lors de la liaison du dossier." } + }, + "adding-error": { + "title": "L'ajout du dossier partagé a échoué", + "msg": "Vous ne pouvez pas ajouter \"{folder}\" aux dossiers partagés." } }, @@ -803,9 +807,14 @@ "add-folder": "Ajouter un dossier", "link-folder": "Lier le dossier", "unlink-folder": "Délier le dossier", - "link-all": "Tout lier" + "link-all": "Tout lier", + "remove-from-the-list": "Retirer de la liste" } }, + "adding-shared-folder": { + "title": "Ajout d'un dossier partagé", + "description": "Vous pourriez rencontrer des problèmes lors de la liaison du dossier \"{folder}\". Êtes-vous sûr de vouloir l'ajouter ?" + }, "create-launch-shortcut": { "title": "Créer un raccourci", "desc": "Créer un raccourci te permettra de démarrer Beat Saber avec les options choisies sans passer par BSManager.", diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 207b822e..3f21e71c 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -601,6 +601,10 @@ "ENOSPC": "ディスクがいっぱいです。空き容量を作ってもう一度試してください。", "UNKNOWN_ERROR": "フォルダをリンク中に不明なエラーが発生しました。" } + }, + "adding-error": { + "title": "共有フォルダの追加に失敗しました", + "msg": "「{folder}」を共有フォルダに追加することはできません。" } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "フォルダーを追加", "link-folder": "フォルダーをリンク", "unlink-folder": "フォルダーのリンクを解除", - "link-all": "すべてリンク" + "link-all": "すべてリンク", + "remove-from-the-list": "リストから削除" } }, + "adding-shared-folder": { + "title": "共有フォルダの追加", + "description": "「{folder}」フォルダをリンクするときに問題が発生する可能性があります。追加してもよろしいですか?" + }, "create-launch-shortcut": { "title": "ショートカットを作成", "desc": "ショートカットを作成すると、BSManagerを起動せずに、直接Beat Saberを起動できます。", diff --git a/assets/jsons/translations/ko.json b/assets/jsons/translations/ko.json index dc40fd30..68e89ad8 100644 --- a/assets/jsons/translations/ko.json +++ b/assets/jsons/translations/ko.json @@ -601,6 +601,10 @@ "ENOSPC": "디스크가 가득 찼습니다. 공간을 확보하고 다시 시도하세요.", "UNKNOWN_ERROR": "폴더를 연결하는 중 알 수 없는 오류가 발생했습니다." } + }, + "adding-error": { + "title": "공유 폴더 추가에 실패했습니다.", + "msg": "공유 폴더에 「{folder}」을 추가할 수 없습니다." } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "폴더 추가", "link-folder": "폴더 연결", "unlink-folder": "폴더 연결 해제", - "link-all": "모두 연결" + "link-all": "모두 연결", + "remove-from-the-list": "목록에서 제거" } }, + "adding-shared-folder": { + "title": "공유 폴더 추가", + "description": "「{folder}」폴더를 연결할 때 문제가 발생할 수 있습니다. 정말 추가하시겠습니까?" + }, "create-launcher-shortcut": { "title": "런처 바로가기 만들기", "description": "바탕화면에 실행 파일의 바로가기를 만들어 BSManager를 손쉽게 실행하세요.", diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 013e151a..fea3a471 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -601,6 +601,10 @@ "ENOSPC": "Диск заполнен, освободите место и попробуйте снова.", "UNKNOWN_ERROR": "Произошла неизвестная ошибка при связывании папки." } + }, + "adding-error": { + "title": "Не удалось добавить общую папку.", + "msg": "Вы не можете добавлять \"{folder}\" в общие папки." } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "Добавить папку", "link-folder": "Связать папку", "unlink-folder": "Отвязать папку", - "link-all": "Связать всё" + "link-all": "Связать всё", + "remove-from-the-list": "Удалить из списка" } }, + "adding-shared-folder": { + "title": "Добавление общей папки", + "description": "У вас могут возникнуть проблемы при связывании папки \"{folder}\". Вы уверены, что хотите ее добавить?" + }, "create-launch-shortcut": { "title": "Создать ярлык", "desc": "Ярлык позволит вам запустить Beat Saber без помощи BSManager.", diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index d8016865..631d5ad1 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -601,6 +601,10 @@ "ENOSPC": "磁碟已滿,請騰出空間後再試。", "UNKNOWN_ERROR": "連結文件夾時發生未知錯誤。" } + }, + "adding-error": { + "title": "添加共享文件夹失败", + "msg": "您无法将\"{folder}\"添加到共享文件夹。" } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "新增文件夾", "link-folder": "關聯文件夾", "unlink-folder": "取消關聯文件夾", - "link-all": "關聯所有" + "link-all": "關聯所有", + "remove-from-the-list": "從列表中移除" } }, + "adding-shared-folder": { + "title": "添加共享文件夹", + "description": "链接\"{folder}\"文件夹时可能会遇到问题。您确定要添加它吗?" + }, "create-launch-shortcut": { "title": "創建捷徑", "desc": "創建捷徑使得你可以在不通過 BSManager 的情況下以特定選項啟動 BeatSaber", diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 999685f1..0779d711 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -601,6 +601,10 @@ "ENOSPC": "磁盘已满,请腾出空间后再试。", "UNKNOWN_ERROR": "链接文件夹时发生未知错误。" } + }, + "adding-error": { + "title": "添加共享文件夹失败", + "msg": "您无法将\"{folder}\"添加到共享文件夹。" } }, "create-launch-shortcut": { @@ -802,9 +806,14 @@ "add-folder": "添加文件夹", "link-folder": "关联文件夹", "unlink-folder": "取消关联文件夹", - "link-all": "关联所有" + "link-all": "关联所有", + "remove-from-the-list": "从列表中移除" } }, + "adding-shared-folder": { + "title": "添加共享文件夹", + "description": "链接\"{folder}\"文件夹时可能会遇到问题。您确定要添加它吗?" + }, "create-launch-shortcut": { "title": "创建快捷方式", "desc": "创建快捷方式使得你可以在不通过 BSManager 的情况下以特定选项启动 BeatSaber", diff --git a/src/main/services/folder-linker.service.ts b/src/main/services/folder-linker.service.ts index 3aa79353..55c70c49 100644 --- a/src/main/services/folder-linker.service.ts +++ b/src/main/services/folder-linker.service.ts @@ -21,19 +21,24 @@ export class FolderLinkerService { private readonly installLocationService = InstallationLocationService.getInstance(); private readonly staticConfig: StaticConfigurationService; - private linkingType: "junction" | "symlink" = "junction"; + // Only Windows support "junction", this is disregarded in other os'es + private linkingType: "junction" | "symlink" = + process.platform === "win32" ? "junction" : "symlink"; private constructor() { this.installLocationService = InstallationLocationService.getInstance(); this.staticConfig = StaticConfigurationService.getInstance(); - this.linkingType = this.staticConfig.get("use-symlinks") === true ? "symlink" : "junction"; - log.info(`Linking type is set to ${this.linkingType}`); + if (process.platform === "win32") { + // Only Windows support "junction", this is disregarded in other os'es + this.linkingType = this.staticConfig.get("use-symlinks") === true ? "symlink" : "junction"; + log.info(`Linking type is set to ${this.linkingType}`); - this.staticConfig.$watch("use-symlinks").subscribe((useSymlink) => { - this.linkingType = useSymlink === true ? "symlink" : "junction"; - log.info(`Linking type set to ${this.linkingType}`); - }); + this.staticConfig.$watch("use-symlinks").subscribe((useSymlink) => { + this.linkingType = useSymlink === true ? "symlink" : "junction"; + log.info(`Linking type set to ${this.linkingType}`); + }); + } } private async sharedFolder(): Promise { diff --git a/src/renderer/components/modal/basic-modal.component.tsx b/src/renderer/components/modal/basic-modal.component.tsx index 0e68ab16..d1acbce0 100644 --- a/src/renderer/components/modal/basic-modal.component.tsx +++ b/src/renderer/components/modal/basic-modal.component.tsx @@ -1,7 +1,7 @@ import { BsmButton, BsmButtonType } from "renderer/components/shared/bsm-button.component"; import { BsmImage } from "renderer/components/shared/bsm-image.component"; import { cn } from "renderer/helpers/css-class.helpers"; -import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { useTranslationV2 } from "renderer/hooks/use-translation.hook"; import { ModalComponent, ModalExitCode } from "renderer/services/modale.service"; type BasicModalOptions = { @@ -12,7 +12,11 @@ type BasicModalOptions = { id: string; text: string; type: BsmButtonType, - isCancel?: boolean; + /** + * true - ModalExitCode.COMPLETED + * undefined/false - ModalExitCode.CANCELED + */ + onClick?: () => boolean; }[]; buttonsLayout?: "row" | "column"; }; @@ -21,20 +25,32 @@ export const BasicModal: ModalComponent { - const t = useTranslation(); + const t = useTranslationV2(); const handleClick = (button: BasicModalOptions["buttons"][0]) => { - resolver({ exitCode: button.isCancel ? ModalExitCode.CANCELED : ModalExitCode.COMPLETED, data: button.id }); + resolver({ + exitCode: button.onClick?.() + ? ModalExitCode.COMPLETED + : ModalExitCode.CANCELED, + data: button.id + }); } return (
-

{t(title)}

+

{t.text(title)}

- { body &&

{t(body)}

} + { body &&

{t.text(body)}

}
{buttons.map(button => ( - handleClick(button)} withBar={false} text={button.text} /> + handleClick(button)} + withBar={false} + text={button.text} + /> ))}
diff --git a/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx b/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx index b685a3fe..db4eca3a 100644 --- a/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx @@ -6,30 +6,45 @@ import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { useObservable } from "renderer/hooks/use-observable.hook"; import { useService } from "renderer/hooks/use-service.hook"; import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; -import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { useTranslationV2 } from "renderer/hooks/use-translation.hook"; import { BSVersionManagerService } from "renderer/services/bs-version-manager.service"; import { ConfigurationService } from "renderer/services/configuration.service"; import { IpcService } from "renderer/services/ipc.service"; -import { ModalComponent } from "renderer/services/modale.service"; +import { ModalComponent, ModalService } from "renderer/services/modale.service"; import { FolderLinkState, VersionFolderLinkerService, VersionLinkerActionType } from "renderer/services/version-folder-linker.service"; import { lastValueFrom } from "rxjs"; import { BSVersion } from "shared/bs-version.interface"; +import { NotificationService } from "renderer/services/notification.service"; +import { BasicModal } from "../basic-modal.component"; +import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png"; -export const ShareFoldersModal: ModalComponent = ({ options: {data} }) => { - const SHARED_FOLDERS_KEY = "default-shared-folders"; +const SHARED_FOLDERS_KEY = "default-shared-folders"; +const SHARED_FOLDER_BLACKLIST = { + error: [ + ".DepotDownloader", + "Beat Saber_Data", + "IPA", + "Libs", + "Plugins", + "MonoBleedingEdge", + ], + warn: [ + "DLC", + "Logs", + ], +}; +export const ShareFoldersModal: ModalComponent = ({ options: { data: version } }) => { const config = useService(ConfigurationService); - const ipc = useService(IpcService); const linker = useService(VersionFolderLinkerService); - const versionManager = useService(BSVersionManagerService); - const t = useTranslation(); + const t = useTranslationV2(); const [folders, setFolders] = useState(Array.from(new Set([...config.get(SHARED_FOLDERS_KEY)]).values())); useEffect(() => { linker - .getLinkedFolders(data, { relative: true }) + .getLinkedFolders(version, { relative: true }) .toPromise() .then(linkedFolders => { setFolders(prev => Array.from(new Set([...prev, ...linkedFolders]).values())); @@ -45,42 +60,24 @@ export const ShareFoldersModal: ModalComponent = ({ options: {d config.set(SHARED_FOLDERS_KEY, folders); }, [folders]); - const addFolder = async () => { - const versionPath = await lastValueFrom(versionManager.getVersionPath(data)); - const folder = await lastValueFrom(ipc.sendV2("choose-folder", { - defaultPath: versionPath - })); - - if (!folder || folder.canceled || !folder.filePaths?.length) { - return; - } - - const relativeFolder = await lastValueFrom(ipc.sendV2("full-version-path-to-relative", { version: data, fullPath: folder.filePaths[0] })); - - if (folders.includes(relativeFolder)) { - return; - } - - setFolders(pre => [...pre, relativeFolder]); - }; const removeFolder = (index: number) => { setFolders(prev => prev.filter((_, i) => i !== index)); }; const linkAll = () => { - folders.forEach(relativeFolder => linker.linkVersionFolder({ version: data, relativeFolder, type: VersionLinkerActionType.Link })); + folders.forEach(relativeFolder => linker.linkVersionFolder({ version, relativeFolder, type: VersionLinkerActionType.Link })); }; return (
-

{t("modals.shared-folders.title")}

-

{t("modals.shared-folders.description")}

+

{t.text("modals.shared-folders.title")}

+

{t.text("modals.shared-folders.description")}

    {folders.map((folder, index) => ( { removeFolder(index); @@ -89,13 +86,93 @@ export const ShareFoldersModal: ModalComponent = ({ options: {d ))}
- +
); }; +function AddFolderButton({ + version, + folders, + setFolders, +}: Readonly<{ + version: BSVersion; + folders: string[]; + setFolders: (value: string[]) => void; +}>) { + const config = useService(ConfigurationService); + const ipc = useService(IpcService); + const versionManager = useService(BSVersionManagerService); + const notification = useService(NotificationService); + const modal = useService(ModalService); + + const t = useTranslationV2(); + + const addFolder = async () => { + const versionPath = await lastValueFrom(versionManager.getVersionPath(version)); + const folder = await lastValueFrom(ipc.sendV2("choose-folder", { + defaultPath: versionPath + })); + + if (!folder || folder.canceled || !folder.filePaths?.length) { + return; + } + + const relativeFolder = await lastValueFrom(ipc.sendV2("full-version-path-to-relative", { version, fullPath: folder.filePaths[0] })); + if (folders.includes(relativeFolder)) { + return; + } + + if (SHARED_FOLDER_BLACKLIST.error.includes(relativeFolder)) { + notification.notifyError({ + title: "notifications.shared-folder.adding-error.title", + desc: t.text("notifications.shared-folder.adding-error.msg", { + folder: relativeFolder + }), + }); + return; + } + + if (SHARED_FOLDER_BLACKLIST.warn.includes(relativeFolder)) { + await modal.openModal(BasicModal, { data: { + title: "modals.adding-shared-folder.title", + body: t.text("modals.adding-shared-folder.description", { + folder: relativeFolder + }), + image: BeatConflict, + buttons: [ + { id: "cancel", text: "misc.cancel", type: "cancel" }, + { + id: "confirm", text: "misc.confirm", type: "primary", + onClick() { + config.set(SHARED_FOLDERS_KEY, [...folders, relativeFolder]); + return true; + }, + } + ] + }}); + return; + } + + setFolders([...folders, relativeFolder]); + }; + + return ; +} + // -------- FOLDER ITEM -------- type FolderProps = { @@ -107,7 +184,7 @@ type FolderProps = { const FolderItem = ({ version, relativeFolder, onDelete }: FolderProps) => { const linker = useService(VersionFolderLinkerService); - const t = useTranslation(); + const t = useTranslationV2(); const color = useThemeColor("first-color"); const state = useObservable(() => linker.$folderLinkedState(version, relativeFolder), FolderLinkState.Unlinked, [version, relativeFolder]); @@ -139,7 +216,7 @@ const FolderItem = ({ version, relativeFolder, onDelete }: FolderProps) => { {name}
- + { ); } return ( - { - e.preventDefault(); - onDelete?.(); - }} - /> + + { + e.preventDefault(); + onDelete?.(); + }} + /> + ); })()}
diff --git a/src/renderer/components/settings/setting-container.component.tsx b/src/renderer/components/settings/setting-container.component.tsx index 00aba9b7..0ed25deb 100644 --- a/src/renderer/components/settings/setting-container.component.tsx +++ b/src/renderer/components/settings/setting-container.component.tsx @@ -1,5 +1,5 @@ import { ReactNode } from "react"; -import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { useTranslationV2 } from "renderer/hooks/use-translation.hook"; type Props = { id?: string; @@ -8,11 +8,11 @@ type Props = { minorTitle?: string; description?: string; children?: ReactNode; - os?: string; + os?: "win32" | "linux"; }; export function SettingContainer({ id, className, title, minorTitle, description, children, os }: Props) { - const t = useTranslation(); + const t = useTranslationV2(); if (os && os !== window.electron.platform) { return undefined; @@ -20,9 +20,9 @@ export function SettingContainer({ id, className, title, minorTitle, description return (
- {title &&

{t(title)}

} - {minorTitle &&

{t(minorTitle)}

} - {description &&

{t(description)}

} + {title &&

{t.text(title)}

} + {minorTitle &&

{t.text(minorTitle)}

} + {description &&

{t.text(description)}

} {children}
); diff --git a/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx b/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx index cba43faf..a5b6bda0 100644 --- a/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx +++ b/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx @@ -1,6 +1,6 @@ import { ToogleSwitch } from "../shared/toogle-switch.component"; -type Item = { +export type Item = { text: string; desc?: string; checked?: boolean; diff --git a/src/renderer/components/shared/link-button.component.tsx b/src/renderer/components/shared/link-button.component.tsx index 3f8446d7..dce72ee7 100644 --- a/src/renderer/components/shared/link-button.component.tsx +++ b/src/renderer/components/shared/link-button.component.tsx @@ -1,9 +1,9 @@ import { motion } from "framer-motion"; import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; import { BsmIcon } from "../svgs/bsm-icon.component"; -import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { useTranslationV2 } from "renderer/hooks/use-translation.hook"; import { FolderLinkState } from "renderer/services/version-folder-linker.service"; -import React from "react"; +import React, { forwardRef } from "react"; export type LinkBtnProps = { className?: string; @@ -12,8 +12,8 @@ export type LinkBtnProps = { onClick?: () => unknown; }; -export function LinkButton({className, title, state, onClick}: LinkBtnProps) { - const t = useTranslation(); +export const LinkButton = forwardRef(({className, title, state, onClick}, forwardedRef) => { + const { text: t } = useTranslationV2(); const color = useThemeColor("first-color"); const disabled = state === FolderLinkState.Processing || state === FolderLinkState.Pending; @@ -41,6 +41,7 @@ export function LinkButton({className, title, state, onClick}: LinkBtnProps) { return ( ); -} +}); diff --git a/src/renderer/config/default-configuration.config.ts b/src/renderer/config/default-configuration.config.ts index 2e4316ad..fedbfcdc 100644 --- a/src/renderer/config/default-configuration.config.ts +++ b/src/renderer/config/default-configuration.config.ts @@ -34,3 +34,4 @@ export const defaultConfiguration: { }; export type ThemeConfig = "dark" | "light" | "os"; + diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index 27f43e73..991c4ece 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -29,7 +29,7 @@ import Tippy from "@tippyjs/react"; import { MapsManagerService } from "renderer/services/maps-manager.service"; import { PlaylistsManagerService } from "renderer/services/playlists-manager.service"; import { ModelsManagerService } from "renderer/services/models-management/models-manager.service"; -import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { useTranslation, useTranslationV2 } from "renderer/hooks/use-translation.hook"; import { VersionFolderLinkerService } from "renderer/services/version-folder-linker.service"; import { useService } from "renderer/hooks/use-service.hook"; import { lastValueFrom } from "rxjs"; @@ -40,7 +40,7 @@ import { SteamIcon } from "renderer/components/svgs/icons/steam-icon.component"; import { OculusIcon } from "renderer/components/svgs/icons/oculus-icon.component"; import { BsDownloaderService } from "renderer/services/bs-version-download/bs-downloader.service"; import BeatConflict from "../../../assets/images/apngs/beat-conflict.png"; -import { SettingToogleSwitchGrid } from "renderer/components/settings/setting-toogle-switch-grid.component"; +import { Item, SettingToogleSwitchGrid } from "renderer/components/settings/setting-toogle-switch-grid.component"; import { BasicModal } from "renderer/components/modal/basic-modal.component"; import { StaticConfigurationService } from "renderer/services/static-configuration.service"; import { tryit } from "shared/helpers/error.helpers"; @@ -96,8 +96,6 @@ export function SettingsPage() { const [playlistsDeepLinkEnabled, setPlaylistsDeepLinkEnabled] = useState(false); const [modelsDeepLinkEnabled, setModelsDeepLinkEnabled] = useState(false); const [hasDownloaderSession, setHasDownloaderSession] = useState(false); - const [hardwareAccelerationEnabled, setHardwareAccelerationEnabled] = useState(true); - const [useSymlink, setUseSymlink] = useState(false); const appVersion = useObservable(() => autoUpdater.getAppVersion()); useEffect(() => { @@ -107,8 +105,6 @@ export function SettingsPage() { playlistsManager.isDeepLinksEnabled().then(enabled => setPlaylistsDeepLinkEnabled(() => enabled)); modelsManager.isDeepLinksEnabled().then(enabled => setModelsDeepLinkEnabled(() => enabled)); - staticConfig.get("disable-hadware-acceleration").then(disabled =>setHardwareAccelerationEnabled(() => disabled !== true)); - staticConfig.get("use-symlinks").then(useSymlinks => setUseSymlink(() => useSymlinks)); staticConfig.get("proton-folder").then(setProtonFolder); }, []); @@ -233,66 +229,6 @@ export function SettingsPage() { }); }; - const onChangeHardwareAcceleration = async (newHardwareAccelerationEnabled: boolean) => { - if(newHardwareAccelerationEnabled === hardwareAccelerationEnabled){ return; } - - const res = await modalService.openModal(BasicModal, { data: { - title: "pages.settings.advanced.hardware-acceleration.modal.title", - body: "pages.settings.advanced.hardware-acceleration.modal.body", - image: BeatConflict, - buttons: [ - { id: "cancel", text: "misc.cancel", type: "cancel", isCancel: true }, - { id: "confirm", text: "pages.settings.advanced.hardware-acceleration.modal.confirm-btn", type: "error" } - ] - }}); - - if(res.exitCode !== ModalExitCode.COMPLETED || res.data !== "confirm"){ return; } - - const { error } = await tryit(() => staticConfig.set("disable-hadware-acceleration", !newHardwareAccelerationEnabled)); - - if(error){ - notificationService.notifyError({ title: "notifications.types.error", desc: "pages.settings.advanced.hardware-acceleration.error-notification.message" }); - setHardwareAccelerationEnabled(() => !newHardwareAccelerationEnabled); - return; - } - - setHardwareAccelerationEnabled(() => newHardwareAccelerationEnabled); - - if(!progressBarService.require()){ - return; - } - - await lastValueFrom(ipcService.sendV2("restart-app")); - }; - - const onChangeUseSymlinks = async (newUseSymlink: boolean) => { - - if(newUseSymlink === useSymlink){ return; } - - if(newUseSymlink){ - const res = await modalService.openModal(BasicModal, { data: { - title: "pages.settings.advanced.use-symlinks.modal.title", - body: "pages.settings.advanced.use-symlinks.modal.body", - image: BeatConflict, - buttons: [ - { id: "cancel", text: "misc.cancel", type: "cancel", isCancel: true }, - { id: "confirm", text: "pages.settings.advanced.use-symlinks.modal.confirm-btn", type: "error" } - ] - }}); - - if(res.exitCode !== ModalExitCode.COMPLETED || res.data !== "confirm"){ return; } - } - - const { error } = await tryit(() => staticConfig.set("use-symlinks", newUseSymlink)); - - if(error){ - notificationService.notifyError({ title: "notifications.types.error", desc: "pages.settings.advanced.use-symlinks.error-notification.message" }); - return; - } - - setUseSymlink(() => newUseSymlink); - } - const toogleShowSupporters = () => { setShowSupporters(show => !show); }; @@ -585,12 +521,7 @@ export function SettingsPage() { - - - + v{appVersion} @@ -598,3 +529,104 @@ export function SettingsPage() { ); } + +function AdvancedSettings() { + const ipc = useService(IpcService); + const modal = useService(ModalService); + const notification = useService(NotificationService); + const progressBar = useService(ProgressBarService); + const staticConfig = useService(StaticConfigurationService); + + const t = useTranslationV2(); + + const [hardwareAccelerationEnabled, setHardwareAccelerationEnabled] = useState(true); + const [useSymlink, setUseSymlink] = useState(false); + + useEffect(() => { + staticConfig.get("disable-hadware-acceleration").then(disabled =>setHardwareAccelerationEnabled(() => disabled !== true)); + staticConfig.get("use-symlinks").then(useSymlinks => setUseSymlink(() => useSymlinks)); + }, []); + + const onChangeHardwareAcceleration = async (newHardwareAccelerationEnabled: boolean) => { + if(newHardwareAccelerationEnabled === hardwareAccelerationEnabled){ return; } + + const res = await modal.openModal(BasicModal, { data: { + title: "pages.settings.advanced.hardware-acceleration.modal.title", + body: "pages.settings.advanced.hardware-acceleration.modal.body", + image: BeatConflict, + buttons: [ + { id: "cancel", text: "misc.cancel", type: "cancel" }, + { id: "confirm", text: "pages.settings.advanced.hardware-acceleration.modal.confirm-btn", type: "error", onClick: () => true }, + ] + }}); + + if(res.exitCode !== ModalExitCode.COMPLETED || res.data !== "confirm"){ return; } + + const { error } = await tryit(() => staticConfig.set("disable-hadware-acceleration", !newHardwareAccelerationEnabled)); + + if(error){ + notification.notifyError({ title: "notifications.types.error", desc: "pages.settings.advanced.hardware-acceleration.error-notification.message" }); + setHardwareAccelerationEnabled(() => !newHardwareAccelerationEnabled); + return; + } + + setHardwareAccelerationEnabled(() => newHardwareAccelerationEnabled); + + if(!progressBar.require()){ + return; + } + + await lastValueFrom(ipc.sendV2("restart-app")); + }; + + const onChangeUseSymlinks = async (newUseSymlink: boolean) => { + + if (window.electron.platform !== "win32" || newUseSymlink === useSymlink) { + return; + } + + if(newUseSymlink){ + const res = await modal.openModal(BasicModal, { data: { + title: "pages.settings.advanced.use-symlinks.modal.title", + body: "pages.settings.advanced.use-symlinks.modal.body", + image: BeatConflict, + buttons: [ + { id: "cancel", text: "misc.cancel", type: "cancel" }, + { id: "confirm", text: "pages.settings.advanced.use-symlinks.modal.confirm-btn", type: "error", onClick: () => true } + ] + }}); + + if(res.exitCode !== ModalExitCode.COMPLETED || res.data !== "confirm"){ return; } + } + + const { error } = await tryit(() => staticConfig.set("use-symlinks", newUseSymlink)); + + if(error){ + notification.notifyError({ title: "notifications.types.error", desc: "pages.settings.advanced.use-symlinks.error-notification.message" }); + return; + } + + setUseSymlink(() => newUseSymlink); + } + + const advancedItems: Item[] = [{ + checked: hardwareAccelerationEnabled, + text: t.text("pages.settings.advanced.hardware-acceleration.title"), + desc: t.text("pages.settings.advanced.hardware-acceleration.description"), + onChange: onChangeHardwareAcceleration + }]; + if (window.electron.platform === "win32") { + advancedItems.push({ + checked: useSymlink, + text: t.text("pages.settings.advanced.use-symlinks.title"), + desc: t.text("pages.settings.advanced.use-symlinks.description"), + onChange: onChangeUseSymlinks + }); + } + + return + + + +} + diff --git a/src/renderer/preload.d.ts b/src/renderer/preload.d.ts index 23e2b0ac..0c8cd4c6 100644 --- a/src/renderer/preload.d.ts +++ b/src/renderer/preload.d.ts @@ -3,7 +3,7 @@ import { webUtils } from "electron"; declare global { interface Window { electron: { - platform: "win32"|"linux"|"darwin", + platform: "win32" | "linux", ipcRenderer: { sendMessage(channel: string, args: any): void; on(channel: string, func: (...args: any) => void): (() => void) | undefined;