mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
Merge pull request #586 from silentrald/feat/578
[feat-578] remove dotnet and screen dependency on linux
This commit is contained in:
+1
-1
@@ -75,7 +75,7 @@ export const AskInstallPathModal: ModalComponent<{ installPath: string }, {}> =
|
||||
<BsmButton
|
||||
onClick={selectInstallPath}
|
||||
className="shrink-0 whitespace-nowrap mr-2 px-2 font-bold italic text-sm rounded-md"
|
||||
text="modals.ask-install-path.choose-folder"
|
||||
text="misc.choose-folder"
|
||||
withBar={false}
|
||||
/>
|
||||
</div>
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook";
|
||||
import { useService } from "renderer/hooks/use-service.hook";
|
||||
|
||||
import { IpcService } from "renderer/services/ipc.service";
|
||||
import { ModalComponent, ModalExitCode } from "renderer/services/modale.service";
|
||||
import { NotificationService } from "renderer/services/notification.service";
|
||||
import { StaticConfigurationService } from "renderer/services/static-configuration.service";
|
||||
|
||||
import { BsmButton } from "renderer/components/shared/bsm-button.component";
|
||||
|
||||
export const ChooseProtonFolderModal: ModalComponent<{}, {}> = ({ resolver }) => {
|
||||
|
||||
const t = useTranslation();
|
||||
const ipcService = useService(IpcService);
|
||||
const notificationService = useService(NotificationService);
|
||||
const staticConfigService = useService(StaticConfigurationService);
|
||||
|
||||
const [protonFolder, setProtonFolder] = useState(null);
|
||||
|
||||
const selectProtonPath = async () => {
|
||||
const response = await lastValueFrom(ipcService.sendV2("choose-folder", {
|
||||
parent: "home",
|
||||
defaultPath: ".local/share/Steam/steamapps/common",
|
||||
showHidden: true,
|
||||
}));
|
||||
|
||||
if (response.canceled || !response.filePaths?.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const path = response.filePaths[0];
|
||||
|
||||
await staticConfigService.set("proton-folder", path).then(() => {
|
||||
setProtonFolder(path);
|
||||
}).catch(err => {
|
||||
notificationService.notifyError({
|
||||
title: "pages.settings.proton-folder.errors.title",
|
||||
desc: ["invalid-folder"].includes(err?.code)
|
||||
? `pages.settings.proton-folder.errors.${err.code}`
|
||||
: "misc.unknown"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const onConfirmButtonPressed = async () => {
|
||||
resolver({
|
||||
exitCode: ModalExitCode.COMPLETED
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<form
|
||||
className="max-w-lg w-max flex flex-col gap-3"
|
||||
onSubmit={event => {
|
||||
event.preventDefault();
|
||||
onConfirmButtonPressed();
|
||||
}}>
|
||||
|
||||
<h1 className="tracking-wide w-full uppercase text-3xl text-center mb-4">{t("modals.choose-proton-folder.title")}</h1>
|
||||
|
||||
<p>{t("modals.choose-proton-folder.proton-folder-description")}</p>
|
||||
|
||||
<a className="underline" href="https://github.com/ValveSoftware/Proton/wiki/Proton-FAQ#where-is-proton-installed" target="_blank">{t("modals.choose-proton-folder.where-is-proton-installed")}</a>
|
||||
<div className="relative flex items-center justify-between w-full h-8 bg-light-main-color-1 dark:bg-main-color-1 rounded-md pl-2 py-1">
|
||||
{protonFolder ? (
|
||||
<span
|
||||
className="block text-ellipsis overflow-hidden min-w-0 whitespace-nowrap"
|
||||
title={protonFolder}
|
||||
>
|
||||
{protonFolder}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-gray-500 italic font-bold">{t("modals.choose-proton-folder.proton-folder-placeholder")}</span>
|
||||
)}
|
||||
<BsmButton
|
||||
onClick={selectProtonPath}
|
||||
className="shrink-0 whitespace-nowrap mr-2 px-2 font-bold italic text-sm rounded-md"
|
||||
text="misc.choose-folder"
|
||||
withBar={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="h-8 grid grid-flow-col grid-cols-1">
|
||||
<BsmButton
|
||||
typeColor="primary"
|
||||
className="rounded-md text-center transition-all"
|
||||
type="submit"
|
||||
withBar={false}
|
||||
text="misc.confirm"
|
||||
disabled={!protonFolder}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -47,7 +47,9 @@ export const ShareFoldersModal: ModalComponent<void, BSVersion> = ({ options: {d
|
||||
|
||||
const addFolder = async () => {
|
||||
const versionPath = await lastValueFrom(versionManager.getVersionPath(data));
|
||||
const folder = await lastValueFrom(ipc.sendV2("choose-folder", versionPath));
|
||||
const folder = await lastValueFrom(ipc.sendV2("choose-folder", {
|
||||
defaultPath: versionPath
|
||||
}));
|
||||
|
||||
if (!folder || folder.canceled || !folder.filePaths?.length) {
|
||||
return;
|
||||
|
||||
@@ -90,7 +90,7 @@ export const BsmButton = forwardRef<unknown, Props>(({ className, style, iconSty
|
||||
{icon && <BsmIcon icon={icon} className={iconClassName ?? "size-full text-gray-800 dark:text-white"} style={{ ...(iconStyle ?? {}), color: (iconColor || textColor) }} />}
|
||||
{text &&
|
||||
(type === "submit" ? (
|
||||
<button type="submit" className={textClassName || "size-full"} style={{ ...(!!textColor && { color: textColor }) }}>
|
||||
<button type="submit" className={textClassName || "size-full"} style={{ ...(!!textColor && { color: textColor }) }} disabled={disabled}>
|
||||
{t(text)}
|
||||
</button>
|
||||
) : (
|
||||
|
||||
@@ -66,7 +66,6 @@ export function LaunchSlide({ version }: Props) {
|
||||
desktop: desktopMode,
|
||||
debug: debugMode,
|
||||
additionalArgs: advancedLaunch ? additionalArgs : [],
|
||||
protonPath: bsLauncherService.getProtonPath(),
|
||||
});
|
||||
|
||||
return lastValueFrom(launch$).catch(() => {});
|
||||
|
||||
@@ -43,7 +43,6 @@ 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";
|
||||
@@ -57,7 +56,6 @@ export function SettingsPage() {
|
||||
const ipcService = useService(IpcService);
|
||||
const modalService = useService(ModalService);
|
||||
const bsDownloader = useService(BsDownloaderService);
|
||||
const bsLauncher = useService(BSLauncherService);
|
||||
const steamDownloader = useService(SteamDownloaderService);
|
||||
const progressBarService = useService(ProgressBarService);
|
||||
const notificationService = useService(NotificationService);
|
||||
@@ -94,7 +92,7 @@ export function SettingsPage() {
|
||||
const downloadStore = useObservable(() => bsDownloader.defaultStore$);
|
||||
|
||||
const [installationFolder, setInstallationFolder] = useState(null);
|
||||
const [protonPath, setProtonPath] = useState(bsLauncher.getProtonPath());
|
||||
const [protonFolder, setProtonFolder] = useState("");
|
||||
const [showSupporters, setShowSupporters] = useState(false);
|
||||
const [mapDeepLinksEnabled, setMapDeepLinksEnabled] = useState(false);
|
||||
const [playlistsDeepLinkEnabled, setPlaylistsDeepLinkEnabled] = useState(false);
|
||||
@@ -116,6 +114,7 @@ export function SettingsPage() {
|
||||
|
||||
staticConfig.get("disable-hadware-acceleration").then(disabled =>setHardwareAccelerationEnabled(() => disabled !== true));
|
||||
staticConfig.get("use-symlinks").then(useSymlinks => setUseSymlink(() => useSymlinks));
|
||||
staticConfig.get("proton-folder").then(setProtonFolder);
|
||||
}, []);
|
||||
|
||||
const allDeepLinkEnabled = mapDeepLinksEnabled && playlistsDeepLinkEnabled && modelsDeepLinkEnabled;
|
||||
@@ -180,18 +179,36 @@ export function SettingsPage() {
|
||||
clearTimeout(timeoutId);
|
||||
};
|
||||
|
||||
const setDefaultProtonPath = () => {
|
||||
const setDefaultProtonFolder = async () => {
|
||||
if (!progressBarService.require()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastValueFrom(ipcService.sendV2("choose-file")).then(res => {
|
||||
if (!res.canceled && res.filePaths?.length) {
|
||||
const protonPath = res.filePaths[0];
|
||||
setProtonPath(protonPath);
|
||||
bsLauncher.setProtonPath(protonPath);
|
||||
try {
|
||||
const pathResponse = await lastValueFrom(ipcService.sendV2("choose-folder", {
|
||||
parent: "home",
|
||||
defaultPath: ".local/share/Steam/steamapps/common",
|
||||
showHidden: true,
|
||||
}));
|
||||
if (
|
||||
pathResponse.canceled
|
||||
|| !pathResponse.filePaths
|
||||
|| pathResponse.filePaths.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
const folder = pathResponse.filePaths[0];
|
||||
await staticConfig.set("proton-folder", folder);
|
||||
setProtonFolder(folder);
|
||||
} catch (error: any) {
|
||||
notificationService.notifyError({
|
||||
title: "pages.settings.proton-folder.errors.title",
|
||||
desc: ["invalid-folder"].includes(error?.code)
|
||||
? `pages.settings.proton-folder.errors.${error.code}`
|
||||
: "misc.unknown",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const setDefaultInstallationFolder = () => {
|
||||
@@ -390,16 +407,16 @@ export function SettingsPage() {
|
||||
<span className="block text-ellipsis overflow-hidden min-w-0" title={installationFolder}>
|
||||
{installationFolder}
|
||||
</span>
|
||||
<BsmButton onClick={setDefaultInstallationFolder} className="shrink-1 whitespace-nowrap mr-2 px-2 font-bold italic text-sm rounded-md" text="pages.settings.installation-folder.choose-folder" withBar={false} />
|
||||
<BsmButton onClick={setDefaultInstallationFolder} className="shrink-1 whitespace-nowrap mr-2 px-2 font-bold italic text-sm rounded-md" text="misc.choose-folder" withBar={false} />
|
||||
</div>
|
||||
</SettingContainer>
|
||||
|
||||
<SettingContainer os="linux" title="pages.settings.proton-path.title" description="pages.settings.proton-path.description">
|
||||
<SettingContainer os="linux" title="pages.settings.proton-folder.title" description="pages.settings.proton-folder.description">
|
||||
<div className="relative flex items-center justify-between w-full h-8 bg-light-main-color-1 dark:bg-main-color-1 rounded-md pl-2 py-1">
|
||||
<span className="block text-ellipsis overflow-hidden min-w-0 whitespace-nowrap" title={protonPath}>
|
||||
{protonPath}
|
||||
<span className="block text-ellipsis overflow-hidden min-w-0 whitespace-nowrap" title={protonFolder}>
|
||||
{protonFolder}
|
||||
</span>
|
||||
<BsmButton onClick={setDefaultProtonPath} className="shrink-0 whitespace-nowrap mr-2 px-2 font-bold italic text-sm rounded-md" text="pages.settings.proton-path.choose-file" withBar={false} />
|
||||
<BsmButton onClick={setDefaultProtonFolder} className="shrink-0 whitespace-nowrap mr-2 px-2 font-bold italic text-sm rounded-md" text="misc.choose-folder" withBar={false} />
|
||||
</div>
|
||||
</SettingContainer>
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ export class BSLauncherService {
|
||||
|
||||
public readonly versionRunning$: BehaviorSubject<BSVersion> = new BehaviorSubject(null);
|
||||
|
||||
private readonly PROTON_PATH_KEY = "protonPath";
|
||||
|
||||
public static getInstance(){
|
||||
if(!BSLauncherService.instance){ BSLauncherService.instance = new BSLauncherService(); }
|
||||
return BSLauncherService.instance;
|
||||
@@ -38,14 +36,6 @@ export class BSLauncherService {
|
||||
this.modals = ModalService.getInstance();
|
||||
}
|
||||
|
||||
public setProtonPath(protonPath: string|undefined): void {
|
||||
this.config.set(this.PROTON_PATH_KEY, protonPath);
|
||||
}
|
||||
|
||||
public getProtonPath(): string|undefined {
|
||||
return this.config.get<string>(this.PROTON_PATH_KEY);
|
||||
}
|
||||
|
||||
private notRewindBackupOculus(): boolean{
|
||||
return this.config.get<boolean>("not-rewind-backup-oculus");
|
||||
}
|
||||
@@ -93,7 +83,6 @@ export class BSLauncherService {
|
||||
}
|
||||
|
||||
public doLaunch(launchOptions: LaunchOption): Observable<BSLaunchEventData>{
|
||||
launchOptions.protonPath = this.getProtonPath();
|
||||
return this.ipcService.sendV2("bs-launch.launch", launchOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ import { InstallationLocationService } from "./installation-location.service";
|
||||
import { IpcService } from "./ipc.service";
|
||||
import { ModalService } from "./modale.service";
|
||||
|
||||
import { AskInstallPathModal } from "renderer/components/modal/modal-types/ask-install-path.component";
|
||||
import { AskInstallPathModal } from "renderer/components/modal/modal-types/setup/ask-install-path.component";
|
||||
import { ChooseProtonFolderModal } from "renderer/components/modal/modal-types/setup/choose-proton-folder-modal.component";
|
||||
|
||||
// Handle setup modals/prompts, ordering of the modals/prompts may be done here
|
||||
export class SetupService {
|
||||
@@ -35,6 +36,10 @@ export class SetupService {
|
||||
try {
|
||||
// NOTE: for modal sequencing
|
||||
await this.checkInstallationPath();
|
||||
|
||||
if (window.electron.platform === "linux") {
|
||||
await this.checkProtonFolder();
|
||||
}
|
||||
} catch (error) {
|
||||
logRenderError(error);
|
||||
}
|
||||
@@ -61,4 +66,20 @@ export class SetupService {
|
||||
}
|
||||
}
|
||||
|
||||
private async checkProtonFolder(): Promise<void> {
|
||||
try {
|
||||
const valid = await lastValueFrom(this.ipcService.sendV2("linux.verify-proton-folder"));
|
||||
if (valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.modalService.openModal(
|
||||
ChooseProtonFolderModal,
|
||||
{ closable: false }
|
||||
);
|
||||
} catch (error) {
|
||||
logRenderError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user