From c4e742c201cf8f38f537cc57565b028755830afc Mon Sep 17 00:00:00 2001 From: silentrald Date: Wed, 11 Dec 2024 22:57:13 +0800 Subject: [PATCH] [feat] disable symlink settings non Windows OS --- src/main/services/folder-linker.service.ts | 19 +- .../share-folders-modal.component.tsx | 15 +- .../settings/setting-container.component.tsx | 12 +- .../setting-toogle-switch-grid.component.tsx | 2 +- .../config/default-configuration.config.ts | 15 -- .../pages/settings-page.component.tsx | 176 +++++++++++------- src/renderer/preload.d.ts | 2 +- 7 files changed, 138 insertions(+), 103 deletions(-) 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/modal-types/share-folders-modal.component.tsx b/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx index b5cd56f3..d5ca412d 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 @@ -14,12 +14,25 @@ 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 { SHARED_FOLDER_BLACKLIST } from "renderer/config/default-configuration.config"; import { NotificationService } from "renderer/services/notification.service"; import { BasicModal } from "../basic-modal.component"; import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png"; 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); 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/config/default-configuration.config.ts b/src/renderer/config/default-configuration.config.ts index 90eac9ca..fedbfcdc 100644 --- a/src/renderer/config/default-configuration.config.ts +++ b/src/renderer/config/default-configuration.config.ts @@ -35,18 +35,3 @@ export const defaultConfiguration: { export type ThemeConfig = "dark" | "light" | "os"; -export const SHARED_FOLDER_BLACKLIST = { - error: [ - ".DepotDownloader", - "Beat Saber_Data", - "IPA", - "Libs", - "Plugins", - "MonoBleedingEdge", - ], - warn: [ - "DLC", - "Logs", - ], -}; - diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index faf4210d..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" }, - { 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){ - 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" }, - { 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){ - 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;