mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature] disable hardware acceleration and use symlinks work, just still need to translate
This commit is contained in:
@@ -153,7 +153,7 @@ export async function copyDirectoryWithJunctions(src: string, dest: string, opti
|
||||
const symlinkTarget = await readlink(sourcePath);
|
||||
const relativePath = path.relative(src, symlinkTarget);
|
||||
const newTarget = path.join(dest, relativePath);
|
||||
await symlink(newTarget, destinationPath, "junction");
|
||||
await symlink(newTarget, destinationPath, "junction"); // Only junction to avoid right issues while copying content of BSManager folder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,3 +12,4 @@ import "./bs-playlist-ipcs";
|
||||
import "./model-saber.ipcs";
|
||||
import "./bs-model-ipcs";
|
||||
import "./bs-version-download/bs-download-ipcs";
|
||||
import "./static-configuration.ipcs";
|
||||
|
||||
@@ -3,6 +3,7 @@ import { NotificationService } from "../services/notification.service";
|
||||
import { IpcService } from "../services/ipc.service";
|
||||
import { from, of } from "rxjs";
|
||||
import { readFileSync } from "fs-extra";
|
||||
import log from "electron-log";
|
||||
|
||||
// TODO IMPROVE WINDOW CONTROL BY USING WINDOW SERVICE
|
||||
|
||||
@@ -16,7 +17,7 @@ ipc.on("choose-folder", (args, reply) => {
|
||||
reply(from(dialog.showOpenDialog({ properties: ["openDirectory"], defaultPath: args ?? "" })));
|
||||
});
|
||||
|
||||
ipc.on<string>("choose-file", async (args, reply) => {
|
||||
ipc.on("choose-file", async (args, reply) => {
|
||||
reply(from(dialog.showOpenDialog({ properties: ["openFile"], defaultPath: args ?? "" })));
|
||||
});
|
||||
|
||||
@@ -62,3 +63,12 @@ ipc.on("choose-image", (args, reply) => {
|
||||
return res.filePaths;
|
||||
})));
|
||||
});
|
||||
|
||||
ipc.on("restart-app", (_, reply) => {
|
||||
log.info("App was requested to restart");
|
||||
|
||||
reply(of()); // Reply before restarting to avoid any issue
|
||||
|
||||
app.relaunch();
|
||||
app.quit();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { of } from "rxjs";
|
||||
import { IpcService } from "../services/ipc.service";
|
||||
import { StaticConfigurationService } from "../services/static-configuration.service";
|
||||
|
||||
const ipc = IpcService.getInstance();
|
||||
const staticConfig = StaticConfigurationService.getInstance();
|
||||
|
||||
ipc.on("static-configuration.get", (args, reply) => {
|
||||
reply(of(staticConfig.get(args)));
|
||||
});
|
||||
|
||||
ipc.on("static-configuration.set", (args, reply) => {
|
||||
reply(of(staticConfig.set(args.key, args.value)));
|
||||
});
|
||||
+10
-1
@@ -24,8 +24,10 @@ import { SteamLauncherService } from "./services/bs-launcher/steam-launcher.serv
|
||||
import { FileAssociationService } from "./services/file-association.service";
|
||||
import { SongDetailsCacheService } from "./services/additional-content/maps/song-details-cache.service";
|
||||
import { readdirSync, statSync, unlinkSync } from "fs-extra";
|
||||
import { StaticConfigurationService } from "./services/static-configuration.service";
|
||||
|
||||
const isDebug = process.env.NODE_ENV === "development" || process.env.DEBUG_PROD === "true";
|
||||
const staticConfig = StaticConfigurationService.getInstance();
|
||||
|
||||
export const filterStrings = new Set<string>();
|
||||
export const filterPatterns = new Set<RegExp>();
|
||||
@@ -37,6 +39,13 @@ initLogger();
|
||||
deleteOlestLogs();
|
||||
deleteOldLogs();
|
||||
|
||||
staticConfig.take("disable-hadware-acceleration", disabled => {
|
||||
if(disabled === true){ // strictly check for true
|
||||
log.info("Disabling hardware acceleration");
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
const sourceMapSupport = require("source-map-support");
|
||||
@@ -108,7 +117,7 @@ if (!gotTheLock) {
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
// C:\\Users\\Mathieu\\Desktop\\BSManager\\BSInstances\\My Version\\UserData\\SongDetailsCache.proto
|
||||
|
||||
|
||||
app.setAppUserModelId(APP_NAME);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import path from "path";
|
||||
import { ensureDirSync, existsSync, readFile, writeFile } from "fs-extra";
|
||||
import { BehaviorSubject, Observable, catchError, filter, lastValueFrom, of, take, timeout } from "rxjs";
|
||||
import { ConfigurationService } from "../../configuration.service";
|
||||
import { RequestService } from "../../request.service";
|
||||
import { tryit } from "shared/helpers/error.helpers";
|
||||
import { CACHE_PATH, HTTP_STATUS_CODES } from "main/constants";
|
||||
@@ -12,6 +11,7 @@ import { SongDetails } from "shared/models/maps/song-details-cache/song-details-
|
||||
import { inflate } from "pako";
|
||||
import { RawSongDetailsCache } from "shared/models/maps/song-details-cache/raw-song-details-cache.model";
|
||||
import { RawSongDetailsDeserializer } from "shared/models/maps/song-details-cache/raw-song-details-deserializer.class";
|
||||
import { StaticConfigurationService } from "main/services/static-configuration.service";
|
||||
|
||||
export class SongDetailsCacheService {
|
||||
|
||||
@@ -32,7 +32,7 @@ export class SongDetailsCacheService {
|
||||
private readonly PROTO_CACHE_PATH = path.join(CACHE_PATH, "song-details-cache");
|
||||
private readonly etagKey = "song-details-cache-etag";
|
||||
|
||||
private readonly config: ConfigurationService;
|
||||
private readonly staticConfig: StaticConfigurationService;
|
||||
private readonly request: RequestService;
|
||||
private readonly utils: UtilsService;
|
||||
|
||||
@@ -41,7 +41,7 @@ export class SongDetailsCacheService {
|
||||
private readonly _loaded$ = new BehaviorSubject<boolean>(null);
|
||||
|
||||
private constructor(){
|
||||
this.config = ConfigurationService.getInstance();
|
||||
this.staticConfig = StaticConfigurationService.getInstance();
|
||||
this.request = RequestService.getInstance();
|
||||
this.utils = UtilsService.getInstance();
|
||||
this.loadCache()
|
||||
@@ -49,10 +49,10 @@ export class SongDetailsCacheService {
|
||||
|
||||
private async loadCache(): Promise<void> {
|
||||
const protoCacheExists = existsSync(this.PROTO_CACHE_PATH);
|
||||
const etag = protoCacheExists ? this.config.get<string>(this.etagKey) : null;
|
||||
const etag = protoCacheExists ? this.staticConfig.get(this.etagKey) : null;
|
||||
|
||||
await this.downloadCacheFile(etag).then(etag => {
|
||||
this.config.set(this.etagKey, etag);
|
||||
this.staticConfig.set(this.etagKey, etag);
|
||||
log.info("SongDetailsCache downloaded");
|
||||
this.songDetailsIdIndex = this.createIdIndex(this.songDetailsCache);
|
||||
log.info("SongDetailsIdIndex created");
|
||||
|
||||
@@ -6,6 +6,7 @@ import path from "path";
|
||||
import { copy, readlink } from "fs-extra";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import { noop } from "shared/helpers/function.helpers";
|
||||
import { StaticConfigurationService } from "./static-configuration.service";
|
||||
|
||||
export class FolderLinkerService {
|
||||
private static instance: FolderLinkerService;
|
||||
@@ -18,9 +19,20 @@ export class FolderLinkerService {
|
||||
}
|
||||
|
||||
private readonly installLocationService = InstallationLocationService.getInstance();
|
||||
private readonly staticConfig: StaticConfigurationService;
|
||||
|
||||
private linkingType: "junction" | "symlink" = "junction";
|
||||
|
||||
private constructor() {
|
||||
this.installLocationService = InstallationLocationService.getInstance();
|
||||
this.staticConfig = StaticConfigurationService.getInstance();
|
||||
|
||||
this.linkingType = this.staticConfig.get("use-symlinks") === true ? "symlink" : "junction";
|
||||
|
||||
this.staticConfig.$watch("use-symlinks").subscribe(({ newValue: useSymlink }) => {
|
||||
this.linkingType = useSymlink === true ? "symlink" : "junction";
|
||||
log.info(`Linking type set to ${this.linkingType}`);
|
||||
});
|
||||
}
|
||||
|
||||
private async sharedFolder(): Promise<string> {
|
||||
@@ -51,6 +63,10 @@ export class FolderLinkerService {
|
||||
});
|
||||
}
|
||||
|
||||
private getLinkingType(): "junction" | undefined {
|
||||
return this.linkingType === "junction" ? "junction" : undefined;
|
||||
}
|
||||
|
||||
public async linkFolder(folderPath: string, options?: LinkOptions): Promise<void> {
|
||||
const sharedPath = await this.getSharedFolder(folderPath, options?.intermediateFolder);
|
||||
|
||||
@@ -62,7 +78,9 @@ export class FolderLinkerService {
|
||||
return;
|
||||
}
|
||||
await unlinkPath(folderPath);
|
||||
return symlink(sharedPath, folderPath, "junction");
|
||||
|
||||
log.info(`Linking ${folderPath} to ${sharedPath}; type: ${this.linkingType}`);
|
||||
return symlink(sharedPath, folderPath, this.getLinkingType());
|
||||
}
|
||||
|
||||
await ensureFolderExist(sharedPath);
|
||||
@@ -79,7 +97,8 @@ export class FolderLinkerService {
|
||||
|
||||
await deleteFolder(folderPath);
|
||||
|
||||
return symlink(sharedPath, folderPath, "junction");
|
||||
log.info(`Linking ${folderPath} to ${sharedPath}; type: ${this.linkingType}`);
|
||||
return symlink(sharedPath, folderPath, this.getLinkingType());
|
||||
}
|
||||
|
||||
public async unlinkFolder(folderPath: string, options?: UnlinkOptions): Promise<void> {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import path from "path";
|
||||
import { app } from "electron";
|
||||
import ElectronStore from "electron-store";
|
||||
import { copyDirectoryWithJunctions, deleteFolder, ensureFolderExist } from "../helpers/fs.helpers";
|
||||
import { tryit } from "../../shared/helpers/error.helpers";
|
||||
import { pathExistsSync } from "fs-extra";
|
||||
import { StaticConfigurationService } from "./static-configuration.service";
|
||||
|
||||
export class InstallationLocationService {
|
||||
private static instance: InstallationLocationService;
|
||||
@@ -23,15 +23,15 @@ export class InstallationLocationService {
|
||||
|
||||
private readonly STORE_INSTALLATION_PATH_KEY = "installation-folder";
|
||||
|
||||
private readonly installPathConfig: ElectronStore;
|
||||
private readonly staticConfig: StaticConfigurationService;
|
||||
private readonly updateListeners: Set<Listener> = new Set();
|
||||
|
||||
private _installationDirectory: string;
|
||||
|
||||
private constructor() {
|
||||
this.installPathConfig = new ElectronStore({ watch: true });
|
||||
this.staticConfig = StaticConfigurationService.getInstance();
|
||||
|
||||
this.installPathConfig.onDidChange(this.STORE_INSTALLATION_PATH_KEY, () => {
|
||||
this.staticConfig.$watch(this.STORE_INSTALLATION_PATH_KEY).subscribe(() => {
|
||||
this.triggerListeners();
|
||||
});
|
||||
}
|
||||
@@ -48,7 +48,7 @@ export class InstallationLocationService {
|
||||
await copyDirectoryWithJunctions(oldDir, path.join(newDir, this.INSTALLATION_FOLDER), { overwrite: true });
|
||||
|
||||
this._installationDirectory = newDir;
|
||||
this.installPathConfig.set(this.STORE_INSTALLATION_PATH_KEY, newDir);
|
||||
this.staticConfig.set(this.STORE_INSTALLATION_PATH_KEY, newDir);
|
||||
|
||||
deleteFolder(oldDir);
|
||||
|
||||
@@ -66,8 +66,8 @@ export class InstallationLocationService {
|
||||
return this._installationDirectory;
|
||||
}
|
||||
|
||||
if(this.installPathConfig.has(this.STORE_INSTALLATION_PATH_KEY)) {
|
||||
return this.installPathConfig.get(this.STORE_INSTALLATION_PATH_KEY) as string;
|
||||
if(this.staticConfig.has(this.STORE_INSTALLATION_PATH_KEY)) {
|
||||
return this.staticConfig.get(this.STORE_INSTALLATION_PATH_KEY) as string;
|
||||
}
|
||||
|
||||
const { result: oldPath } = tryit(() => path.join(app.getPath("documents"), this.INSTALLATION_FOLDER));
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import ElectronStore from "electron-store";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
export class StaticConfigurationService {
|
||||
private static instance: StaticConfigurationService;
|
||||
|
||||
public static getInstance(): StaticConfigurationService {
|
||||
if (!StaticConfigurationService.instance) {
|
||||
StaticConfigurationService.instance = new StaticConfigurationService();
|
||||
}
|
||||
return StaticConfigurationService.instance;
|
||||
}
|
||||
|
||||
private readonly store: ElectronStore;
|
||||
|
||||
private constructor() {
|
||||
this.store = new ElectronStore({ watch: true });
|
||||
}
|
||||
|
||||
public has<K extends StaticConfigKeys>(key: K): boolean {
|
||||
return this.store.has(key);
|
||||
}
|
||||
|
||||
public get<K extends StaticConfigKeys>(key: K): StaticConfigKeyValues[K] {
|
||||
return this.store.get<K>(key) as StaticConfigKeyValues[K];
|
||||
}
|
||||
|
||||
public take<K extends StaticConfigKeys>(key: K, cb: (val: StaticConfigKeyValues[K]) => void): void {
|
||||
cb(this.get(key));
|
||||
}
|
||||
|
||||
public set<K extends StaticConfigKeys>(key: K, value: StaticConfigKeyValues[K]): void {
|
||||
this.store.set(key, value);
|
||||
}
|
||||
|
||||
public delete<K extends StaticConfigKeys>(key: K): void {
|
||||
this.store.delete(key);
|
||||
}
|
||||
|
||||
public getStore(): ElectronStore {
|
||||
return this.store;
|
||||
}
|
||||
|
||||
public $watch<K extends StaticConfigKeys>(key: K): Observable<{ newValue: StaticConfigKeyValues[K], oldValue: StaticConfigKeyValues[K] }> {
|
||||
return new Observable(obs => {
|
||||
const unsub = this.store.onDidChange(key, (newValue, oldValue) => {
|
||||
obs.next({ newValue, oldValue } as { newValue: StaticConfigKeyValues[K], oldValue: StaticConfigKeyValues[K] });
|
||||
});
|
||||
|
||||
return () => unsub();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export interface StaticConfigKeyValues {
|
||||
"installation-folder": string;
|
||||
"song-details-cache-etag": string;
|
||||
"disable-hadware-acceleration": boolean;
|
||||
"use-symlinks": boolean;
|
||||
}
|
||||
|
||||
export type StaticConfigKeys = keyof StaticConfigKeyValues;
|
||||
|
||||
export type StaticConfigGetIpcRequestResponse<K extends StaticConfigKeys> = {
|
||||
request: K;
|
||||
response: StaticConfigKeyValues[K];
|
||||
};
|
||||
|
||||
export type StaticConfigSetIpcRequest<K extends StaticConfigKeys> = {
|
||||
request: { key: K, value: StaticConfigKeyValues[K] };
|
||||
response: void;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
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 { ModalComponent, ModalExitCode } from "renderer/services/modale.service";
|
||||
|
||||
type BasicModalOptions = {
|
||||
title: string;
|
||||
image: string;
|
||||
body?: string;
|
||||
buttons?: {
|
||||
id: string;
|
||||
text: string;
|
||||
type: BsmButtonType,
|
||||
isCancel?: boolean;
|
||||
}[];
|
||||
buttonsLayout?: "row" | "column";
|
||||
};
|
||||
|
||||
export const BasicModal: ModalComponent<BasicModalOptions["buttons"][0]["id"], BasicModalOptions> = ({ resolver, options: {
|
||||
data: { title, image, body, buttons, buttonsLayout = "column" }
|
||||
} }) => {
|
||||
|
||||
const t = useTranslation();
|
||||
|
||||
const handleClick = (button: BasicModalOptions["buttons"][0]) => {
|
||||
resolver({ exitCode: button.isCancel ? ModalExitCode.CANCELED : ModalExitCode.COMPLETED, data: button.id });
|
||||
}
|
||||
|
||||
return (
|
||||
<form className="text-gray-800 dark:text-gray-200">
|
||||
<h1 className="text-3xl uppercase tracking-wide w-full text-center">{t(title)}</h1>
|
||||
<BsmImage className="mx-auto h-24" image={image} />
|
||||
{ body && <p className="max-w-sm w-full">{t(body)}</p> }
|
||||
<div className={cn("grid gap-2 mt-4")} style={{ gridAutoFlow: buttonsLayout, ...(buttonsLayout === "row" ? { gridTemplateRows: `repeat(${buttons.length}, 1fr)` } : { gridTemplateColumns: `repeat(${buttons.length}, 1fr)` }) }}>
|
||||
{buttons.map(button => (
|
||||
<BsmButton key={button.id} typeColor={button.type} className="h-8 rounded-md text-center flex justify-center items-center" onClick={() => handleClick(button)} withBar={false} text={button.text} />
|
||||
))}
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -34,36 +34,36 @@ export function ToogleSwitch({ checked, className, classNames, bgColor, onChange
|
||||
}, [dotColor]);
|
||||
|
||||
useEffect(() => {
|
||||
if (checked !== undefined) {
|
||||
setIsChecked(checked);
|
||||
}
|
||||
setIsChecked(checked);
|
||||
}, [checked]);
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
onChange(isChecked);
|
||||
}
|
||||
}, [isChecked]);
|
||||
|
||||
const handleCheckboxChange = () => {
|
||||
if (middleWare) {
|
||||
setIsChecked(prev => {
|
||||
const newState = !prev;
|
||||
console.log('newState', newState);
|
||||
const result = middleWare(newState);
|
||||
if (isPromise(result)) {
|
||||
result.then(shouldChange => {
|
||||
if (shouldChange) {
|
||||
setIsChecked(newState);
|
||||
setIsChecked(() => {
|
||||
onChange?.(newState);
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
}).catch(noop);
|
||||
} else if (result) {
|
||||
setIsChecked(newState);
|
||||
setIsChecked(() => {
|
||||
onChange?.(newState);
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
} else {
|
||||
setIsChecked(prev => !prev);
|
||||
setIsChecked(prev => {
|
||||
onChange?.(!prev);
|
||||
return !prev;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,13 @@ import { OculusIcon } from "renderer/components/svgs/icons/oculus-icon.component
|
||||
import { BsDownloaderService } from "renderer/services/bs-version-download/bs-downloader.service";
|
||||
import { AutoUpdaterService } from "renderer/services/auto-updater.service";
|
||||
import BeatWaitingImg from "../../../assets/images/apngs/beat-waiting.png";
|
||||
import BeatConflict from "../../../assets/images/apngs/beat-conflict.png";
|
||||
import { logRenderError } from "renderer";
|
||||
import { BSLauncherService } from "renderer/services/bs-launcher.service";
|
||||
import { 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";
|
||||
|
||||
export function SettingsPage() {
|
||||
|
||||
@@ -63,6 +67,7 @@ export function SettingsPage() {
|
||||
const modelsManager = useService(ModelsManagerService);
|
||||
const versionLinker = useService(VersionFolderLinkerService);
|
||||
const autoUpdater = useService(AutoUpdaterService);
|
||||
const staticConfig = useService(StaticConfigurationService);
|
||||
|
||||
const { firstColor, secondColor } = useThemeColor();
|
||||
|
||||
@@ -93,7 +98,7 @@ export function SettingsPage() {
|
||||
const [playlistsDeepLinkEnabled, setPlaylistsDeepLinkEnabled] = useState(false);
|
||||
const [modelsDeepLinkEnabled, setModelsDeepLinkEnabled] = useState(false);
|
||||
const [hasDownloaderSession, setHasDownloaderSession] = useState(false);
|
||||
const [hardwareAcceleration, setHardwareAcceleration] = useState(true);
|
||||
const [hardwareAccelerationEnabled, setHardwareAccelerationEnabled] = useState(true);
|
||||
const [useSymlink, setUseSymlink] = useState(false);
|
||||
const appVersion = useObservable(() => ipcService.sendV2("current-version"));
|
||||
|
||||
@@ -106,6 +111,9 @@ export function SettingsPage() {
|
||||
mapsManager.isDeepLinksEnabled().then(enabled => setMapDeepLinksEnabled(() => enabled));
|
||||
playlistsManager.isDeepLinksEnabled().then(enabled => setPlaylistsDeepLinkEnabled(() => enabled));
|
||||
modelsManager.isDeepLinksEnabled().then(enabled => setModelsDeepLinkEnabled(() => enabled));
|
||||
|
||||
staticConfig.get("disable-hadware-acceleration").then(disabled =>setHardwareAccelerationEnabled(() => disabled === false));
|
||||
staticConfig.get("use-symlinks").then(useSymlinks => setUseSymlink(() => useSymlinks));
|
||||
}, []);
|
||||
|
||||
const allDeepLinkEnabled = mapDeepLinksEnabled && playlistsDeepLinkEnabled && modelsDeepLinkEnabled;
|
||||
@@ -222,14 +230,77 @@ export function SettingsPage() {
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeHardwareAcceleration = async (enabled: boolean): Promise<boolean> => {
|
||||
if(enabled === hardwareAcceleration){ return false; }
|
||||
const onAboutToChangeHardwareAcceleration = async (enabled: boolean): Promise<boolean> => {
|
||||
if(enabled === hardwareAccelerationEnabled){ return false; }
|
||||
|
||||
const res = await modalService.openModal(BasicModal, { data: {
|
||||
title: "Restart Needed",
|
||||
body: "Changing hardware acceleration setting will quit and re-launch BSManager. Are you sure you want to do this?",
|
||||
image: BeatConflict,
|
||||
buttons: [
|
||||
{ id: "cancel", text: "Cancel", type: "cancel", isCancel: true },
|
||||
{ id: "confirm", text: "Yes I'm sure", type: "error" }
|
||||
]
|
||||
}});
|
||||
|
||||
if(res.exitCode !== ModalExitCode.COMPLETED || res.data !== "confirm"){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const onChangeHardwareAcceleration = async (enabled: boolean) => {
|
||||
|
||||
const { error } = await tryit(() => staticConfig.set("disable-hadware-acceleration", !enabled));
|
||||
|
||||
if(error){
|
||||
notificationService.notifyError({ title: "notifications.types.error", desc: "An error occur, unable to disable hardware acceleration" });
|
||||
return;
|
||||
}
|
||||
|
||||
setHardwareAccelerationEnabled(() => enabled);
|
||||
|
||||
if(!progressBarService.require()){
|
||||
return;
|
||||
}
|
||||
|
||||
await lastValueFrom(ipcService.sendV2("restart-app"));
|
||||
};
|
||||
|
||||
const onAboutToChangeUseSymlinks = async (newUseSymlink: boolean): Promise<boolean> => {
|
||||
if(newUseSymlink === useSymlink){ return false; }
|
||||
if(!newUseSymlink){ return true; } // If we are disabling symlinks, no need to inform about admin rights
|
||||
|
||||
const res = await modalService.openModal(BasicModal, { data: {
|
||||
title: "Permission Needed",
|
||||
body: "In order to create symlinks, BSManager will need to run as administrator or your system will need to have developer mode enabled. Are you sure you want to do this?",
|
||||
image: BeatConflict,
|
||||
buttons: [
|
||||
{ id: "cancel", text: "Cancel", type: "cancel", isCancel: true },
|
||||
{ id: "confirm", text: "Yes I'm sure", type: "error" }
|
||||
]
|
||||
}});
|
||||
|
||||
if(res.exitCode !== ModalExitCode.COMPLETED || res.data !== "confirm"){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const onChangeUseSymlinks = async (useSymlink: boolean) => {
|
||||
const { error } = await tryit(() => staticConfig.set("use-symlinks", useSymlink));
|
||||
|
||||
if(error){
|
||||
notificationService.notifyError({ title: "notifications.types.error", desc: "An error occur, unable to change symlinks settings" });
|
||||
return;
|
||||
}
|
||||
|
||||
setUseSymlink(() => useSymlink);
|
||||
}
|
||||
|
||||
const toogleShowSupporters = () => {
|
||||
setShowSupporters(show => !show);
|
||||
};
|
||||
@@ -514,8 +585,8 @@ export function SettingsPage() {
|
||||
|
||||
<SettingContainer title="Advanced" description="Changes these stettings only if your are sure of what you are doing">
|
||||
<SettingToogleSwitchGrid items={[
|
||||
{ checked: hardwareAcceleration, text: "Hadware Acceleration", desc: "Enable Hardware Acceleration to use your GPU and improve BSManager's performance. Turn this off if you're experiencing frame drops.", middleWare: onChangeHardwareAcceleration },
|
||||
{ checked: useSymlink, text: "Use Symlink", desc: "Use Symlinks instead of Junctions to link folders. Turn this on only if you really need it.", onChange: () => {} },
|
||||
{ checked: hardwareAccelerationEnabled, text: "Hadware Acceleration", desc: "Enable Hardware Acceleration to use your GPU and improve BSManager's performance. Turn this off if you're experiencing frame drops.", middleWare: onAboutToChangeHardwareAcceleration, onChange: onChangeHardwareAcceleration },
|
||||
{ checked: useSymlink, text: "Use Symlinks", desc: "Use Symlinks instead of Junctions to link folders. Turn this on only if you really need it.", middleWare: onAboutToChangeUseSymlinks, onChange: onChangeUseSymlinks },
|
||||
]}/>
|
||||
</SettingContainer>
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { StaticConfigKeys, StaticConfigKeyValues } from "main/services/static-configuration.service";
|
||||
import { IpcService } from "./ipc.service";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
|
||||
export class StaticConfigurationService {
|
||||
|
||||
private static instance: StaticConfigurationService;
|
||||
|
||||
public static getInstance(): StaticConfigurationService {
|
||||
if (!StaticConfigurationService.instance) {
|
||||
StaticConfigurationService.instance = new StaticConfigurationService();
|
||||
}
|
||||
return StaticConfigurationService.instance;
|
||||
}
|
||||
|
||||
private readonly ipc: IpcService;
|
||||
|
||||
private constructor(){
|
||||
this.ipc = IpcService.getInstance();
|
||||
}
|
||||
|
||||
public get<K extends StaticConfigKeys>(key: K): Promise<StaticConfigKeyValues[K]> {
|
||||
return lastValueFrom(this.ipc.sendV2("static-configuration.get", key)) as Promise<StaticConfigKeyValues[K]>;
|
||||
}
|
||||
|
||||
public set<K extends StaticConfigKeys>(key: K, value: StaticConfigKeyValues[K]): Promise<void> {
|
||||
return lastValueFrom(this.ipc.sendV2("static-configuration.set", { key, value }));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import { SystemNotificationOptions } from "../notification/system-notification.m
|
||||
import { Supporter } from "../supporters";
|
||||
import { AppWindow } from "../window-manager/app-window.model";
|
||||
import { LocalBPList, LocalBPListsDetails } from "../playlists/local-playlist.models";
|
||||
import { StaticConfigGetIpcRequestResponse, StaticConfigKeys, StaticConfigSetIpcRequest } from "main/services/static-configuration.service";
|
||||
|
||||
export type IpcReplier<T> = (data: Observable<T>) => void;
|
||||
|
||||
@@ -124,6 +125,7 @@ export interface IpcChannelMapping {
|
||||
"open-logs": { request: void, response: string };
|
||||
"notify-system": { request: SystemNotificationOptions, response: void };
|
||||
"view-path-in-explorer": { request: string, response: void };
|
||||
"restart-app": { request: void, response: void };
|
||||
|
||||
/* ** supporters-ipcs ** */
|
||||
"get-supporters": { request: void, response: Supporter[] };
|
||||
@@ -136,6 +138,10 @@ export interface IpcChannelMapping {
|
||||
"open-window-then-close-all": { request: AppWindow, response: void };
|
||||
"open-window-or-focus": { request: AppWindow, response: void };
|
||||
|
||||
/* ** static-configuration.ipcs ** */
|
||||
"static-configuration.get": StaticConfigGetIpcRequestResponse<StaticConfigKeys>;
|
||||
"static-configuration.set": StaticConfigSetIpcRequest<StaticConfigKeys>;
|
||||
|
||||
/* ** OTHERS (if your IPC channel is not in a "-ipcs" file, put it here) ** */
|
||||
"shortcut-launch-options": { request: void, response: LaunchOption };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user