mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feat] disable symlink settings non Windows OS
This commit is contained in:
@@ -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<string> {
|
||||
|
||||
@@ -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<void, BSVersion> = ({ options: { data: version } }) => {
|
||||
const config = useService(ConfigurationService);
|
||||
|
||||
@@ -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 (
|
||||
<div id={id} className={className || "relative mb-5"}>
|
||||
{title && <h1 className="mb-1 text-2xl font-bold tracking-wide">{t(title)}</h1>}
|
||||
{minorTitle && <h2 className="mb-1 font-bold tracking-wide text-gray-600 dark:text-gray-300">{t(minorTitle)}</h2>}
|
||||
{description && <p className="mb-3 text-sm text-gray-600 dark:text-gray-400">{t(description)}</p>}
|
||||
{title && <h1 className="mb-1 text-2xl font-bold tracking-wide">{t.text(title)}</h1>}
|
||||
{minorTitle && <h2 className="mb-1 font-bold tracking-wide text-gray-600 dark:text-gray-300">{t.text(minorTitle)}</h2>}
|
||||
{description && <p className="mb-3 text-sm text-gray-600 dark:text-gray-400">{t.text(description)}</p>}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ToogleSwitch } from "../shared/toogle-switch.component";
|
||||
|
||||
type Item = {
|
||||
export type Item = {
|
||||
text: string;
|
||||
desc?: string;
|
||||
checked?: boolean;
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -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() {
|
||||
</SettingContainer>
|
||||
</SettingContainer>
|
||||
|
||||
<SettingContainer title="pages.settings.advanced.title" description="pages.settings.advanced.description">
|
||||
<SettingToogleSwitchGrid items={[
|
||||
{ checked: hardwareAccelerationEnabled, text: t("pages.settings.advanced.hardware-acceleration.title"), desc: t("pages.settings.advanced.hardware-acceleration.description"), onChange: onChangeHardwareAcceleration },
|
||||
{ checked: useSymlink, text: t("pages.settings.advanced.use-symlinks.title"), desc: t("pages.settings.advanced.use-symlinks.description"), onChange: onChangeUseSymlinks },
|
||||
]}/>
|
||||
</SettingContainer>
|
||||
<AdvancedSettings />
|
||||
|
||||
<span className="bg-light-main-color-1 dark:bg-main-color-1 rounded-md py-1 px-2 font-bold float-right mb-5">v{appVersion}</span>
|
||||
</div>
|
||||
@@ -598,3 +529,104 @@ export function SettingsPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 <SettingContainer title="pages.settings.advanced.title" description="pages.settings.advanced.description">
|
||||
<SettingToogleSwitchGrid items={advancedItems}/>
|
||||
</SettingContainer>
|
||||
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user