mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
Merge branch 'master' into bugfix/beatmods-connection
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { BsModsManagerService } from "../services/mods/bs-mods-manager.service";
|
||||
import { IpcService } from "../services/ipc.service";
|
||||
import { from } from "rxjs";
|
||||
import { BeatModsApiService } from "main/services/mods/beat-mods-api.service";
|
||||
|
||||
const ipc = IpcService.getInstance();
|
||||
|
||||
@@ -34,8 +35,7 @@ ipc.on("bs-mods.uninstall-all-mods", (args, reply) => {
|
||||
reply(modsManager.uninstallAllMods(args));
|
||||
});
|
||||
|
||||
ipc.on("bs-mods.get-mods-grid-status", (_, reply) => {
|
||||
const modsManager = BsModsManagerService.getInstance();
|
||||
reply(from(modsManager.getModsGridStatus()));
|
||||
});
|
||||
|
||||
ipc.on("bs-mods.beatmods-up", (_, reply) => {
|
||||
const beatMods = BeatModsApiService.getInstance();
|
||||
reply(from(beatMods.isUp()));
|
||||
})
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import crypto from "crypto";
|
||||
import { BsmZipExtractor } from "main/models/bsm-zip-extractor.class";
|
||||
import { BsmShellLog, bsmSpawn } from "main/helpers/os.helpers";
|
||||
import { BbmFullMod, BbmModVersion, ExternalMod } from "../../../shared/models/mods/mod.interface";
|
||||
import { ModsGridStatus } from "shared/models/mods/mod-ipc.model";
|
||||
|
||||
export class BsModsManagerService {
|
||||
private static instance: BsModsManagerService;
|
||||
@@ -565,24 +564,6 @@ export class BsModsManagerService {
|
||||
.finally(() => obs.complete());
|
||||
});
|
||||
}
|
||||
|
||||
public async getModsGridStatus(): Promise<ModsGridStatus> {
|
||||
if (process.platform === "linux") {
|
||||
const wineprefix = this.linuxService.getWinePrefixPath();
|
||||
if (!wineprefix) {
|
||||
log.error("Could not find BSManager WINEPREFIX path");
|
||||
return ModsGridStatus.NO_WINEPREFIX;
|
||||
}
|
||||
}
|
||||
|
||||
const beatModsUp = await this.beatModsApi.isUp();
|
||||
if (!beatModsUp) {
|
||||
return ModsGridStatus.BEATMODS_DOWN;
|
||||
}
|
||||
|
||||
|
||||
return ModsGridStatus.OK;
|
||||
}
|
||||
}
|
||||
|
||||
const enum ModsInstallFolder {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
})
|
||||
@@ -35,7 +35,7 @@ type Props = { version: BSVersion; isActive?: boolean, onDisclamerDecline: () =>
|
||||
export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, onDisclamerDecline }, forwaredRef) => {
|
||||
const ACCEPTED_DISCLAIMER_KEY = "accepted-mods-disclaimer";
|
||||
|
||||
const { text: t } = useTranslationV2();
|
||||
const { text: t, element: te } = useTranslationV2();
|
||||
|
||||
const modsManager = useService(BsModsManagerService);
|
||||
const configService = useService(ConfigurationService);
|
||||
@@ -189,7 +189,7 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
setModsSelected(() => []);
|
||||
}
|
||||
|
||||
const getAcceptDisclaimerKey = async () => {
|
||||
const ensureDisclaimerAccepted = async (): Promise<boolean> => {
|
||||
if (configService.get<boolean>(ACCEPTED_DISCLAIMER_KEY)) {
|
||||
return true;
|
||||
}
|
||||
@@ -228,17 +228,16 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
return noop();
|
||||
}
|
||||
|
||||
getAcceptDisclaimerKey()
|
||||
.then(async (canLoad) => {
|
||||
if (!canLoad) {
|
||||
return onDisclamerDecline?.();
|
||||
}
|
||||
ensureDisclaimerAccepted().then(async canLoad => {
|
||||
if (!canLoad) {
|
||||
return onDisclamerDecline?.();
|
||||
}
|
||||
|
||||
const status = await modsManager.getModsGridStatus();
|
||||
setGridStatus(status);
|
||||
const status = await modsManager.getModsGridStatus();
|
||||
setGridStatus(() => status);
|
||||
|
||||
loadMods();
|
||||
});
|
||||
loadMods();
|
||||
});
|
||||
|
||||
return () => {
|
||||
setMoreInfoMod(null);
|
||||
@@ -271,11 +270,9 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
|
||||
const renderStatus = () => {
|
||||
if (gridStatus === ModsGridStatus.BEATMODS_DOWN) {
|
||||
const [ textStart, textEnd ] = t("pages.version-viewer.mods.status.beatmods-down")
|
||||
.split("{links}");
|
||||
return <ModStatus image={BeatConflictImg}>
|
||||
<span className="text-xl text-center px-2 mt-3 italic">
|
||||
{textStart}
|
||||
{te("pages.version-viewer.mods.status.beatmods-down", {links: (<>
|
||||
<BsmLink className="text-blue-500 underline" href={DISCORD_URL}>
|
||||
Discord
|
||||
</BsmLink>
|
||||
@@ -283,7 +280,7 @@ export const ModsSlide = forwardRef<ModsSlideRef, Props>(({ version, isActive, o
|
||||
<BsmLink className="text-blue-500 underline" href={GITHUB_URL}>
|
||||
GitHub
|
||||
</BsmLink>
|
||||
{textEnd}
|
||||
</>)})}
|
||||
</span>
|
||||
</ModStatus>
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -508,7 +508,8 @@ export function SettingsPage() {
|
||||
<SettingContainer className="mt-3" description="pages.settings.discord.description">
|
||||
<div className="flex gap-2">
|
||||
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 !text-white" withBar={false} text="Discord" icon="discord" iconClassName="p-0.5 mr-1" color="#5865f2" onClick={openDiscord} />
|
||||
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 !text-white" withBar={false} text="Twitter" icon="twitter" iconClassName="p-0.5 mr-1" color="#000" onClick={openTwitter} />
|
||||
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 !text-white" withBar={false} text="Twitter" icon="twitter" iconClassName="p-0.5 mr-1" color="#171717" onClick={openTwitter} />
|
||||
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 !text-white" withBar={false} text="GitHub" icon="github" iconClassName="p-0.5 mr-1 h-full w-full" color="#171717" onClick={openGithub} />
|
||||
</div>
|
||||
</SettingContainer>
|
||||
<SettingContainer className="pt-3" description="pages.settings.contribution.description">
|
||||
@@ -519,7 +520,6 @@ export function SettingsPage() {
|
||||
</div>
|
||||
<div className="flex px-2 gap-2">
|
||||
<BsmButton onClick={openLogs} className="shrink-0 whitespace-nowrap px-2 font-bold italic text-sm rounded-md" text="pages.settings.contribution.buttons.open-logs" withBar={false} />
|
||||
<BsmButton onClick={openGithub} className="shrink-0 px-2 rounded-md" icon="github" title="GitHub" withBar={false} />
|
||||
</div>
|
||||
</div>
|
||||
</SettingContainer>
|
||||
|
||||
@@ -9,6 +9,7 @@ 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;
|
||||
@@ -18,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);
|
||||
|
||||
@@ -32,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[]> {
|
||||
@@ -206,11 +209,21 @@ export class BsModsManagerService {
|
||||
}
|
||||
|
||||
public async getModsGridStatus(): Promise<ModsGridStatus> {
|
||||
return lastValueFrom(this.ipcService.sendV2("bs-mods.get-mods-grid-status"))
|
||||
.catch(error => {
|
||||
logRenderError(error);
|
||||
return ModsGridStatus.UNKNOWN;
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
const beatModsUp = await lastValueFrom(this.ipcService.sendV2("bs-mods.beatmods-up")).catch(() => false);
|
||||
if (!beatModsUp) {
|
||||
return ModsGridStatus.BEATMODS_DOWN;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import { LocalBPList, LocalBPListsDetails } from "../playlists/local-playlist.mo
|
||||
import { StaticConfigGetIpcRequestResponse, StaticConfigKeys, StaticConfigSetIpcRequest } from "main/services/static-configuration.service";
|
||||
import { BbmFullMod, BbmModVersion, ExternalMod } from "../mods/mod.interface";
|
||||
import { OculusDownloadInfo } from "main/services/bs-version-download/bs-oculus-downloader.service";
|
||||
import { ModsGridStatus } from "../mods/mod-ipc.model";
|
||||
|
||||
export type IpcReplier<T> = (data: Observable<T>) => void;
|
||||
|
||||
@@ -89,7 +88,7 @@ export interface IpcChannelMapping {
|
||||
"bs-mods.install-mods": { request: { mods: BbmFullMod[]; version: BSVersion }, response: Progression };
|
||||
"bs-mods.uninstall-mods": { request: { mods: BbmFullMod[]; version: BSVersion }, response: Progression };
|
||||
"bs-mods.uninstall-all-mods": { request: BSVersion, response: Progression };
|
||||
"bs-mods.get-mods-grid-status": { request: BSVersion, response: ModsGridStatus };
|
||||
"bs-mods.beatmods-up": { request: void, response: boolean };
|
||||
|
||||
/* ** bs-playlist-ipcs ** */
|
||||
"one-click-install-playlist": { request: string, response: Progression<DownloadPlaylistProgressionData> };
|
||||
@@ -161,6 +160,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 };
|
||||
|
||||
Reference in New Issue
Block a user