mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
Merge branch 'master' into feature/fileSizes+OversizeWarning
This commit is contained in:
@@ -33,3 +33,4 @@ ipc.on("bs-mods.uninstall-all-mods", (args, reply) => {
|
||||
const modsManager = BsModsManagerService.getInstance();
|
||||
reply(modsManager.uninstallAllMods(args));
|
||||
});
|
||||
|
||||
|
||||
@@ -9,3 +9,8 @@ ipc.on("linux.verify-proton-folder", (_, reply) => {
|
||||
reply(of(linuxService.verifyProtonPath()));
|
||||
});
|
||||
|
||||
ipc.on("linux.get-wine-prefix-path", (_, reply) => {
|
||||
const linuxService = LinuxService.getInstance();
|
||||
reply(of(linuxService.getWinePrefixPath()));
|
||||
});
|
||||
|
||||
|
||||
@@ -106,10 +106,10 @@ export class BSLocalVersionService {
|
||||
|
||||
const versionFilePath = path.join(bsPath, 'Beat Saber_Data', 'globalgamemanagers');
|
||||
const folderVersion = await this.getVersionFromGlobalGameManagerFile(versionFilePath);
|
||||
folderVersion.path = bsPath;
|
||||
|
||||
if(!folderVersion){ return null; }
|
||||
|
||||
folderVersion.path = bsPath;
|
||||
|
||||
if(options?.steam || options?.oculus){
|
||||
return {...folderVersion, ...options};
|
||||
}
|
||||
|
||||
@@ -158,11 +158,10 @@ export class BsModsManagerService {
|
||||
winePath = `"${winePathResult}"`;
|
||||
|
||||
const winePrefix = this.linuxService.getWinePrefixPath();
|
||||
if (winePrefix) {
|
||||
env.WINEPREFIX = winePrefix;
|
||||
} else {
|
||||
log.warn("Could not find BSManager WINEPREFIX path, using system's default value instead");
|
||||
if (!winePrefix) {
|
||||
throw new CustomError("Could not find BSManager WINEPREFIX path", "no-wineprefix");
|
||||
}
|
||||
env.WINEPREFIX = winePrefix;
|
||||
}
|
||||
|
||||
return new Promise<boolean>(resolve => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { FranceIcon } from "./flags/france-icon.component";
|
||||
import { SpainIcon } from "./flags/spain-icon.component";
|
||||
import { ItalyIcon } from "./flags/italy-icon.component";
|
||||
import { UsaIcon } from "./flags/usa-icon.component";
|
||||
import { UkIcon } from "./flags/uk-icon.component";
|
||||
import { UkraineIcon } from "./flags/ukraine-icon.component";
|
||||
import { TaskIcon } from "./icons/task-icon.component";
|
||||
import { CopyIcon } from "./icons/copy-icon.component";
|
||||
import { SteamIcon } from "./icons/steam-icon.component";
|
||||
@@ -70,10 +70,12 @@ import { AddFileIcon } from "./icons/add-file-icon.component";
|
||||
import { CancelIcon } from "./icons/cancel-icon.component";
|
||||
import { WarningIcon } from "./icons/warning-icon.component";
|
||||
import { ArrowUpwardIcon } from "./icons/arrow-upward-icon.component";
|
||||
import { UkIcon } from "./flags/uk-icon.component";
|
||||
import { PhilippineIcon } from "./flags/philippine-icon.component";
|
||||
|
||||
|
||||
export type BsmIconType = SongDetailDiffCharactertistic | ("settings" | "trash" | "favorite" | "folder" | "bsNote" | "check" | "three-dots" | "twitch" | "eye" | "play" | "checkCircleIcon" | "discord" | "info" | "eye-cross" | "terminal" | "desktop" | "oculus" | "add" | "cross" | "task" | "github" | "close" | "thumbUpFill" | "timerFill" | "pause" | "twitter" | "sync" | "chevron-top" | "copy" | "steam" | "edit" | "export" | "patreon" | "search" | "bsMapDifficulty" | "link" | "unlink" | "download" | "filter" | "mee6" | "volume-up" | "volume-off" | "volume-down" | "shortcut" | "backup-restore" | "web-site" | "clean" | "browse" | "add-file" | "arrow-upward" | "cancel" | "warning" | "fr-FR-flag" | "es-ES-flag" | "it-IT-flag" | "en-US-flag" | "en-EN-flag" | "de-DE-flag" | "ru-RU-flag" | "zh-CN-flag" | "zh-TW-flag" | "ja-JP-flag" | "ko-KR-flag" | "pt-BR-flag" | "uk-UA-flag" | "tl-PH-flag" | "null" );
|
||||
|
||||
export type BsmIconType = SongDetailDiffCharactertistic | ("settings" | "trash" | "favorite" | "folder" | "bsNote" | "check" | "three-dots" | "twitch" | "eye" | "play" | "checkCircleIcon" | "discord" | "info" | "eye-cross" | "terminal" | "desktop" | "oculus" | "add" | "cross" | "task" | "github" | "close" | "thumbUpFill" | "timerFill" | "pause" | "twitter" | "sync" | "chevron-top" | "copy" | "steam" | "edit" | "export" | "patreon" | "search" | "bsMapDifficulty" | "link" | "unlink" | "download" | "filter" | "mee6" | "volume-up" | "volume-off" | "volume-down" | "shortcut" | "backup-restore" | "web-site" | "clean" | "browse" | "add-file" | "arrow-upward" | "cancel" | "warning" | "fr-FR-flag" | "es-ES-flag" | "it-IT-flag" | "en-US-flag" | "en-EN-flag" | "de-DE-flag" | "ru-RU-flag" | "zh-CN-flag" | "zh-TW-flag" | "ja-JP-flag" | "ko-KR-flag" | "pt-BR-flag" | "null" );
|
||||
|
||||
export const BsmIcon = memo(({ className, icon, style }: { className?: string; icon: BsmIconType; style?: CSSProperties }) => {
|
||||
// TODO : Very ugly very messy, need to find a better way to do this
|
||||
@@ -146,6 +148,12 @@ export const BsmIcon = memo(({ className, icon, style }: { className?: string; i
|
||||
if (icon === "pt-BR-flag"){
|
||||
return <BrazilIcon className={className} style={style} />;
|
||||
}
|
||||
if (icon === "uk-UA-flag"){
|
||||
return <UkraineIcon className={className} style={style} />;
|
||||
}
|
||||
if (icon === "tl-PH-flag") {
|
||||
return <PhilippineIcon className={className} style={style} />;
|
||||
}
|
||||
|
||||
if (icon === "task") {
|
||||
return <TaskIcon className={className} style={style} />;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { createSvgIcon } from "../svg-icon.type";
|
||||
|
||||
export const PhilippineIcon = createSvgIcon((props, ref) => {
|
||||
return (
|
||||
<svg ref={ref} {...props} width="71" height="48" viewBox="0 0 71 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none">
|
||||
<path d="M63.89.12H6.61A6.36 6.36 0 0 0 .25 6.48v17.64h70V6.48A6.36 6.36 0 0 0 63.89.12" fill="#4758A9"/>
|
||||
<path d="M.25 40.75a6.36 6.36 0 0 0 6.36 6.36h57.27a6.36 6.36 0 0 0 6.36-6.36V24.12h-70z" fill="#ED5565"/>
|
||||
<path d="M2.15 1.95a6.34 6.34 0 0 0-1.9 4.54v34.27a6.34 6.34 0 0 0 1.95 4.57l23.05-21.21z" fill="#FFF"/>
|
||||
<circle fill="#F6D660" cx="10.25" cy="23.62" r="4"/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { createSvgIcon } from "../svg-icon.type";
|
||||
|
||||
// Uploaded from: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools
|
||||
|
||||
export const UkraineIcon = createSvgIcon((props, ref) => {
|
||||
return (
|
||||
<svg ref={ref} {...props} width="71" height="48" viewBox="0 0 71 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none">
|
||||
<path d="M64.27 47.7H7a6.36 6.36 0 0 1-6.36-6.36V23.7h70v17.64a6.36 6.36 0 0 1-6.37 6.36" fill="#F6D660"/>
|
||||
<path d="M.63 7.06A6.36 6.36 0 0 1 7 .7h57.27a6.36 6.36 0 0 1 6.36 6.36V23.7h-70z" fill="#4A89DC"/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
})
|
||||
@@ -22,6 +22,7 @@ import { UninstallAllModsModal } from "renderer/components/modal/modal-types/uni
|
||||
import Tippy from "@tippyjs/react";
|
||||
import { ProgressBarService } from "renderer/services/progress-bar.service";
|
||||
import { Dropzone } from "renderer/components/shared/dropzone.component";
|
||||
import { ModsGridStatus } from "shared/models/mods/mod-ipc.model";
|
||||
|
||||
export type ModsSlideRef = {
|
||||
loadMods: () => Promise<void>;
|
||||
@@ -42,6 +43,7 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
const os = useService(OsDiagnosticService);
|
||||
const progress = useService(ProgressBarService);
|
||||
|
||||
const [gridStatus, setGridStatus] = useState(ModsGridStatus.OK);
|
||||
const [modsAvailable, setModsAvailable] = useState(null as Map<BbmCategories, BbmFullMod[]>);
|
||||
const [modsInstalled, setModsInstalled] = useState(null as Map<BbmCategories, BbmFullMod[]>);
|
||||
const [modsSelected, setModsSelected] = useState([] as BbmFullMod[]);
|
||||
@@ -185,8 +187,23 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
setModsSelected(() => []);
|
||||
}
|
||||
|
||||
const ensureDisclaimerAccepted = async (): Promise<boolean> => {
|
||||
if (configService.get<boolean>(ACCEPTED_DISCLAIMER_KEY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const res = await modals.openModal(ModsDisclaimerModal);
|
||||
const haveAccepted = res.exitCode === ModalExitCode.COMPLETED;
|
||||
|
||||
if (haveAccepted) {
|
||||
configService.set(ACCEPTED_DISCLAIMER_KEY, true);
|
||||
}
|
||||
|
||||
return haveAccepted;
|
||||
}
|
||||
|
||||
const loadMods = async (): Promise<void> => {
|
||||
if (os.isOffline) {
|
||||
if (os.isOffline || gridStatus !== ModsGridStatus.OK) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -209,24 +226,14 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
return noop();
|
||||
}
|
||||
|
||||
(async () => {
|
||||
if (configService.get<boolean>(ACCEPTED_DISCLAIMER_KEY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const res = await modals.openModal(ModsDisclaimerModal);
|
||||
const haveAccepted = res.exitCode === ModalExitCode.COMPLETED;
|
||||
|
||||
if (haveAccepted) {
|
||||
configService.set(ACCEPTED_DISCLAIMER_KEY, true);
|
||||
}
|
||||
|
||||
return haveAccepted;
|
||||
})().then(canLoad => {
|
||||
ensureDisclaimerAccepted().then(async canLoad => {
|
||||
if (!canLoad) {
|
||||
return onDisclamerDecline?.();
|
||||
}
|
||||
|
||||
const status = await modsManager.getModsGridStatus();
|
||||
setGridStatus(() => status);
|
||||
|
||||
loadMods();
|
||||
});
|
||||
|
||||
@@ -234,6 +241,7 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
setMoreInfoMod(null);
|
||||
setModsAvailable(null);
|
||||
setModsInstalled(null);
|
||||
setGridStatus(ModsGridStatus.OK);
|
||||
};
|
||||
}, [isActive, isOnline, version]);
|
||||
|
||||
@@ -262,6 +270,9 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
if (!isOnline) {
|
||||
return <ModStatus text="pages.version-viewer.mods.no-internet" image={BeatConflictImg} />;
|
||||
}
|
||||
if (gridStatus !== ModsGridStatus.OK) {
|
||||
return <ModStatus text={`pages.version-viewer.mods.status.${gridStatus}`} image={BeatConflictImg} />;
|
||||
}
|
||||
if (!modsAvailable) {
|
||||
return <ModStatus text="pages.version-viewer.mods.loading-mods" image={BeatWaitingImg} spin />;
|
||||
}
|
||||
@@ -337,7 +348,7 @@ function ModStatus({ text, image, spin = false, children }: { text: string; imag
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col items-center justify-center text-gray-800 dark:text-gray-200">
|
||||
<img className={`w-32 h-32 ${spin ? "spin-loading" : ""}`} src={image} alt=" " />
|
||||
<span className="text-xl mt-3 italic">{t(text)}</span>
|
||||
<span className="text-xl mt-3 italic text-center">{t(text)}</span>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ export const defaultConfiguration: {
|
||||
"second-color": "#ff4444",
|
||||
theme: "os",
|
||||
language: window.navigator.language.length <= 2 ? `${window.navigator.language}-${window.navigator.language.toLocaleUpperCase()}` : window.navigator.language,
|
||||
supported_languages: ["en-US", "en-EN", "fr-FR", "es-ES", "it-IT", "de-DE", "ru-RU", "zh-CN", "zh-TW", "ja-JP", "ko-KR", "pt-BR"],
|
||||
supported_languages: ["en-US", "en-EN", "fr-FR", "es-ES", "it-IT", "de-DE", "ru-RU", "zh-CN", "zh-TW", "ja-JP", "ko-KR", "pt-BR", "uk-UA", "tl-PH"],
|
||||
default_mods: ["SongCore", "WhyIsThereNoLeaderboard", "BeatSaverDownloader", "BeatSaverVoting", "PlaylistManager"],
|
||||
"default-shared-folders": [
|
||||
window.electron.path.join("Beat Saber_Data", "CustomLevels"),
|
||||
|
||||
@@ -8,6 +8,8 @@ import { Progression } from "main/helpers/fs.helpers";
|
||||
import { ProgressionInterface } from "shared/models/progress-bar";
|
||||
import { BbmFullMod, BbmModVersion } from "shared/models/mods/mod.interface";
|
||||
import { logRenderError } from "renderer";
|
||||
import { ModsGridStatus } from "shared/models/mods/mod-ipc.model";
|
||||
import { LinuxService } from "./linux.service";
|
||||
|
||||
export class BsModsManagerService {
|
||||
private static instance: BsModsManagerService;
|
||||
@@ -17,6 +19,7 @@ export class BsModsManagerService {
|
||||
private readonly ipcService: IpcService;
|
||||
private readonly progressBar: ProgressBarService;
|
||||
private readonly notifications: NotificationService;
|
||||
private readonly linux: LinuxService
|
||||
|
||||
public readonly isUninstalling$: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||
|
||||
@@ -31,6 +34,7 @@ export class BsModsManagerService {
|
||||
this.ipcService = IpcService.getInstance();
|
||||
this.progressBar = ProgressBarService.getInstance();
|
||||
this.notifications = NotificationService.getInstance();
|
||||
this.linux = LinuxService.getInstance();
|
||||
}
|
||||
|
||||
public getAvailableMods(version: BSVersion): Observable<BbmFullMod[]> {
|
||||
@@ -204,4 +208,17 @@ export class BsModsManagerService {
|
||||
return { available: (available ?? []), installed: (installedMods ?? []) };
|
||||
}
|
||||
|
||||
public async getModsGridStatus(): Promise<ModsGridStatus> {
|
||||
|
||||
if(window.electron.platform === "linux"){
|
||||
const winePrefix = await lastValueFrom(this.linux.getWinePrefixPath());
|
||||
if(!winePrefix){
|
||||
logRenderError("Could not find BSManager WINEPREFIX path");
|
||||
return ModsGridStatus.NO_WINEPREFIX;
|
||||
}
|
||||
}
|
||||
|
||||
return ModsGridStatus.OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Observable } from "rxjs";
|
||||
import { IpcService } from "./ipc.service";
|
||||
|
||||
export class LinuxService {
|
||||
|
||||
private static instance: LinuxService;
|
||||
|
||||
public static getInstance(): LinuxService {
|
||||
if (!LinuxService.instance) {
|
||||
LinuxService.instance = new LinuxService();
|
||||
}
|
||||
return LinuxService.instance;
|
||||
}
|
||||
|
||||
private readonly ipc: IpcService;
|
||||
|
||||
private constructor() {
|
||||
this.ipc = IpcService.getInstance();
|
||||
}
|
||||
|
||||
public getWinePrefixPath(): Observable<string> {
|
||||
return this.ipc.sendV2("linux.get-wine-prefix-path");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -159,6 +159,7 @@ export interface IpcChannelMapping {
|
||||
|
||||
/* ** linux.ipcs ** */
|
||||
"linux.verify-proton-folder": { request: void, response: boolean };
|
||||
"linux.get-wine-prefix-path": { request: void, response: string };
|
||||
|
||||
/* ** oculus.ipcs ** */
|
||||
"is-oculus-sideloaded-apps-enabled": { request: void, response: boolean };
|
||||
|
||||
@@ -12,3 +12,10 @@ export interface UninstallModsResult {
|
||||
nbModsToUninstall: number;
|
||||
nbUninstalledMods: number;
|
||||
}
|
||||
|
||||
export enum ModsGridStatus {
|
||||
OK = "",
|
||||
NO_WINEPREFIX = "no-wineprefix",
|
||||
UNKNOWN = "unknown"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user