mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feat] add editor launch option
This commit is contained in:
@@ -54,7 +54,9 @@
|
||||
"placeholder": "Weitere Argumente, bspw: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "Steam überspringen",
|
||||
"skipsteam-description": "Verhindert, dass Steam automatisch mit Beat Saber geöffnet wird. Aktivieren Sie dies, wenn Sie eine andere VR-Laufzeit wie WiVRn oder Monado verwenden, mit der SteamVR interferieren könnte."
|
||||
"skipsteam-description": "Verhindert, dass Steam automatisch mit Beat Saber geöffnet wird. Aktivieren Sie dies, wenn Sie eine andere VR-Laufzeit wie WiVRn oder Monado verwenden, mit der SteamVR interferieren könnte.",
|
||||
"map-editor": "Karteneditor",
|
||||
"map-editor-description": "Starte den offiziellen Beat Saber-Karteneditor anstelle des Spiels."
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
"placeholder": "Additional arguments ex: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "Skip Steam",
|
||||
"skipsteam-description": "Stops Steam from opening automatically with Beat Saber, enable if you are using a different VR runtime like WiVRn or Monado that SteamVR may interfere with."
|
||||
"skipsteam-description": "Stops Steam from opening automatically with Beat Saber, enable if you are using a different VR runtime like WiVRn or Monado that SteamVR may interfere with.",
|
||||
"map-editor": "Map Editor",
|
||||
"map-editor-description": "Start the official Beat Saber map editor instead of the game."
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -64,7 +64,9 @@
|
||||
"delete-duplicate-maps": "Borrar duplicados"
|
||||
},
|
||||
"skipsteam": "Saltar Steam",
|
||||
"skipsteam-description": "Evita que Steam se abra automáticamente con Beat Saber, habilita esto si estás usando un runtime de VR diferente como WiVRn o Monado que SteamVR podría interferir."
|
||||
"skipsteam-description": "Evita que Steam se abra automáticamente con Beat Saber, habilita esto si estás usando un runtime de VR diferente como WiVRn o Monado que SteamVR podría interferir.",
|
||||
"map-editor": "Editor de mapas",
|
||||
"map-editor-description": "Inicia el editor oficial de mapas de Beat Saber en lugar del juego."
|
||||
},
|
||||
"tabs": {
|
||||
"maps": {
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
"placeholder": "Arguments supplémentaires ex: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "Ignorer Steam",
|
||||
"skipsteam-description": "Empêche Steam de s'ouvrir automatiquement avec Beat Saber, activez-le si vous utilisez un autre runtime VR comme WiVRn ou Monado avec lequel SteamVR pourrait interférer."
|
||||
"skipsteam-description": "Empêche Steam de s'ouvrir automatiquement avec Beat Saber, activez-le si vous utilisez un autre runtime VR comme WiVRn ou Monado avec lequel SteamVR pourrait interférer.",
|
||||
"map-editor": "Éditeur de map",
|
||||
"map-editor-description": "Lance l'éditeur officiel de map de Beat Saber au lieu du jeu."
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
"placeholder": "추가 인수 예: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "Steam 실행 건너뛰기",
|
||||
"skipsteam-description": "Beat Saber와 함께 Steam이 자동으로 열리는 것을 방지합니다. SteamVR이 간섭할 수 있는 WiVRn 또는 Monado와 같은 다른 VR 런타임을 사용하는 경우 활성화하세요."
|
||||
"skipsteam-description": "Beat Saber와 함께 Steam이 자동으로 열리는 것을 방지합니다. SteamVR이 간섭할 수 있는 WiVRn 또는 Monado와 같은 다른 VR 런타임을 사용하는 경우 활성화하세요.",
|
||||
"map-editor": "맵 편집기",
|
||||
"map-editor-description": "게임 대신 공식 Beat Saber 맵 편집기를 실행해."
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
"placeholder": "Параметры запуска, например: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "Пропустить Steam",
|
||||
"skipsteam-description": "Предотвращает автоматическое открытие Steam с Beat Saber, включите, если вы используете другую VR-среду, такую как WiVRn или Monado, с которой SteamVR может мешать."
|
||||
"skipsteam-description": "Предотвращает автоматическое открытие Steam с Beat Saber, включите, если вы используете другую VR-среду, такую как WiVRn или Monado, с которой SteamVR может мешать.",
|
||||
"map-editor": "Редактор карт",
|
||||
"map-editor-description": "Запусти официальный редактор карт Beat Saber вместо игры."
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
"placeholder": "額外啟動參數,例如: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "跳過 Steam",
|
||||
"skipsteam-description": "防止 Steam 與 Beat Saber 自動打開,如果您使用的是其他 VR 執行時,如 WiVRn 或 Monado,SteamVR 可能會干擾,請啟用此選項。"
|
||||
"skipsteam-description": "防止 Steam 與 Beat Saber 自動打開,如果您使用的是其他 VR 執行時,如 WiVRn 或 Monado,SteamVR 可能會干擾,請啟用此選項。",
|
||||
"map-editor": "地圖編輯器",
|
||||
"map-editor-description": "啟動官方的 Beat Saber 地圖編輯器,而不是遊戲。"
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
"placeholder": "额外启动参数,例如: --revert; --nowait"
|
||||
},
|
||||
"skipsteam": "跳过 Steam",
|
||||
"skipsteam-description": "防止 Steam 与 Beat Saber 自动打开,如果您使用的是其他 VR 运行时,如 WiVRn 或 Monado,SteamVR 可能会干扰,请启用此选项。"
|
||||
"skipsteam-description": "防止 Steam 与 Beat Saber 自动打开,如果您使用的是其他 VR 运行时,如 WiVRn 或 Monado,SteamVR 可能会干扰,请启用此选项。",
|
||||
"map-editor": "地图编辑器",
|
||||
"map-editor-description": "启动官方的 Beat Saber 地图编辑器,而不是游戏。"
|
||||
},
|
||||
"maps": {
|
||||
"search-bar": {
|
||||
|
||||
@@ -25,16 +25,20 @@ export abstract class AbstractLauncherService {
|
||||
if(!launchOptions.version.steam && !launchOptions.version.oculus){
|
||||
launchArgs.push("--no-yeet")
|
||||
}
|
||||
if (launchOptions.launchMods?.includes(LaunchMods.OCULUS)) {
|
||||
if(launchOptions.launchMods?.includes(LaunchMods.OCULUS)) {
|
||||
launchArgs.push("-vrmode");
|
||||
launchArgs.push("oculus");
|
||||
}
|
||||
if (launchOptions.launchMods?.includes(LaunchMods.FPFC)) {
|
||||
if(launchOptions.launchMods?.includes(LaunchMods.FPFC)) {
|
||||
launchArgs.push("fpfc");
|
||||
}
|
||||
if (launchOptions.launchMods?.includes(LaunchMods.DEBUG)) {
|
||||
if(launchOptions.launchMods?.includes(LaunchMods.DEBUG)) {
|
||||
launchArgs.push("--verbose");
|
||||
}
|
||||
if(launchOptions.launchMods?.includes(LaunchMods.EDITOR)) {
|
||||
launchArgs.push("editor");
|
||||
}
|
||||
|
||||
if (launchOptions.additionalArgs) {
|
||||
launchArgs.push(...launchOptions.additionalArgs);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { TaskIcon } from "./icons/task-icon.component";
|
||||
import { CopyIcon } from "./icons/copy-icon.component";
|
||||
import { SteamIcon } from "./icons/steam-icon.component";
|
||||
import { CSSProperties, memo } from "react";
|
||||
import EditIcon from "./icons/edit-icon.component";
|
||||
import { EditIcon } from "./icons/edit-icon.component";
|
||||
import { ExportIcon } from "./icons/export-icon.component";
|
||||
import PatreonIcon from "./icons/patreon-icon.component";
|
||||
import { SearchIcon } from "./icons/search-icon.component";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { CSSProperties } from "react";
|
||||
import { createSvgIcon } from "../svg-icon.type";
|
||||
|
||||
export default function EditIcon(props: { className?: string; style?: CSSProperties }) {
|
||||
export const EditIcon = createSvgIcon((props, ref) => {
|
||||
return (
|
||||
<svg className={props.className} style={props.style} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" height="40" width="40">
|
||||
<svg ref={ref} {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" height="40" width="40">
|
||||
<path fill="currentColor" d="M7.833 32.25h1.875L26.75 15.208l-1.875-1.875L7.833 30.375Zm24.959-19.042-5.959-5.916 1.917-1.917q.833-.833 2.042-.833 1.208 0 2.083.875l1.833 1.833q.875.833.854 2.021-.02 1.187-.854 2.021ZM6.542 35.125q-.667 0-1.125-.458-.459-.459-.459-1.125v-3.709q0-.333.104-.604.105-.271.355-.521L24.875 9.25l5.958 5.958-19.458 19.459q-.25.25-.542.354-.291.104-.583.104Zm19.25-20.833-.917-.959 1.875 1.875Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ export function LaunchModToogle({ onClick, active, text, icon: Icon, infoText }:
|
||||
const t = useTranslation();
|
||||
|
||||
return (
|
||||
<button className={`relative rounded-full cursor-pointer group active:scale-95 transition-transform ${!active && "shadow-md shadow-black"}`} onClick={() => onClick(!active)}>
|
||||
<button className={`shrink-0 relative rounded-full cursor-pointer group active:scale-95 transition-transform ${!active && "shadow-md shadow-black"}`} onClick={() => onClick(!active)}>
|
||||
<GlowEffect visible={active} className="absolute !rounded-full blur-[2px]" />
|
||||
<div className="w-full h-full px-6 flex gap-1.5 justify-center items-center bg-light-main-color-2 dark:bg-main-color-2 p-3 rounded-full text-gray-800 dark:text-white group-hover:bg-light-main-color-1 dark:group-hover:bg-main-color-1">
|
||||
{Icon && <Icon className="h-7 shrink-0 text-gray-800 dark:text-white" />}
|
||||
|
||||
+12
-10
@@ -37,7 +37,7 @@ export function LaunchOptionsPanel({ className, open, launchArgs, launchMods, on
|
||||
|
||||
export type LaunchModItemProps = {
|
||||
readonly id: LaunchMod;
|
||||
readonly Icon?: SvgIcon;
|
||||
readonly icon?: SvgIcon;
|
||||
readonly label: string;
|
||||
readonly description: string;
|
||||
readonly active: boolean;
|
||||
@@ -47,21 +47,23 @@ export type LaunchModItemProps = {
|
||||
readonly onPinChange?: (val: boolean) => void;
|
||||
}
|
||||
|
||||
export function LaunchModItem({ id, Icon, label, description, active, visible, pinned, onChange, onPinChange }: LaunchModItemProps) {
|
||||
export function LaunchModItem({ id, icon: Icon, label, description, active, visible, pinned, onChange, onPinChange }: LaunchModItemProps) {
|
||||
|
||||
const { text: t } = useTranslationV2();
|
||||
|
||||
return (
|
||||
<Tippy theme="default" placement="top" content={description}>
|
||||
<button id={id} className={cn("grow rounded-md bg-theme-1 relative flex justify-center items-center gap-1.5 h-10 py-1 px-3", visible === false && "hidden")} onClick={e => { e.preventDefault(); e.stopPropagation(); onChange?.(!active) }}>
|
||||
<BsmCheckbox className="h-4 aspect-square z-[1] relative" checked={active} onChange={onChange}/>
|
||||
{Icon && <Icon className="h-full w-fit py-0.5"/>}
|
||||
<button id={id} className={cn("grow rounded-md bg-theme-1 relative flex justify-center items-center h-10 py-1 px-3", visible === false && "hidden")} onClick={e => { e.preventDefault(); e.stopPropagation(); onChange?.(!active) }}>
|
||||
<BsmCheckbox className="h-4 aspect-square z-[1] relative mr-1.5" checked={active} onChange={onChange}/>
|
||||
{Icon && <Icon className="h-full w-fit py-0.5 mr-1.5"/>}
|
||||
<span className="font-bold">{label}</span>
|
||||
<Tippy theme="default" placement="right" content={pinned ? t("misc.unpin") : t("misc.pin")} hideOnClick>
|
||||
<button className="h-full py-2" onClick={e => { e.preventDefault(); e.stopPropagation(); onPinChange?.(!pinned) }}>
|
||||
{pinned ? <UnpinIcon className="size-full"/> : <PinIcon className="size-full"/>}
|
||||
</button>
|
||||
</Tippy>
|
||||
{onPinChange && (
|
||||
<Tippy theme="default" placement="right" content={pinned ? t("misc.unpin") : t("misc.pin")} hideOnClick>
|
||||
<button className="h-full py-2 px-1.5" onClick={e => { e.preventDefault(); e.stopPropagation(); onPinChange?.(!pinned) }}>
|
||||
{pinned ? <UnpinIcon className="size-full"/> : <PinIcon className="size-full"/>}
|
||||
</button>
|
||||
</Tippy>
|
||||
)}
|
||||
</button>
|
||||
</Tippy>
|
||||
);
|
||||
|
||||
@@ -25,6 +25,7 @@ import { OculusIcon } from "renderer/components/svgs/icons/oculus-icon.component
|
||||
import { DesktopIcon } from "renderer/components/svgs/icons/desktop-icon.component";
|
||||
import { TerminalIcon } from "renderer/components/svgs/icons/terminal-icon.component";
|
||||
import { DefaultConfigKey } from "renderer/config/default-configuration.config";
|
||||
import { EditIcon } from "renderer/components/svgs/icons/edit-icon.component";
|
||||
|
||||
type Props = { version: BSVersion };
|
||||
|
||||
@@ -65,7 +66,7 @@ export function LaunchSlide({ version }: Props) {
|
||||
setLaunchModItems(() => [
|
||||
{
|
||||
id: LaunchMods.OCULUS,
|
||||
Icon: OculusIcon,
|
||||
icon: OculusIcon,
|
||||
label: t("pages.version-viewer.launch-mods.oculus"),
|
||||
description: t("pages.version-viewer.launch-mods.oculus-description"),
|
||||
active: activeLaunchMods.includes(LaunchMods.OCULUS),
|
||||
@@ -76,7 +77,7 @@ export function LaunchSlide({ version }: Props) {
|
||||
},
|
||||
{
|
||||
id: LaunchMods.FPFC,
|
||||
Icon: DesktopIcon,
|
||||
icon: DesktopIcon,
|
||||
label: t("pages.version-viewer.launch-mods.desktop"),
|
||||
description: t("pages.version-viewer.launch-mods.desktop-description"),
|
||||
active: activeLaunchMods.includes(LaunchMods.FPFC),
|
||||
@@ -86,7 +87,7 @@ export function LaunchSlide({ version }: Props) {
|
||||
},
|
||||
{
|
||||
id: LaunchMods.DEBUG,
|
||||
Icon: TerminalIcon,
|
||||
icon: TerminalIcon,
|
||||
label: t("pages.version-viewer.launch-mods.debug"),
|
||||
description: t("pages.version-viewer.launch-mods.debug-description"),
|
||||
active: activeLaunchMods.includes(LaunchMods.DEBUG),
|
||||
@@ -102,6 +103,18 @@ export function LaunchSlide({ version }: Props) {
|
||||
pinned: pinnedLaunchMods.includes(LaunchMods.SKIP_STEAM),
|
||||
onChange: checked => checked ? setActiveLaunchMods(prev => [...prev, LaunchMods.SKIP_STEAM]) : setActiveLaunchMods(prev => prev.filter(mod => mod !== LaunchMods.SKIP_STEAM)),
|
||||
onPinChange: pinned => pinned ? setPinnedLaunchMods(prev => [...prev, LaunchMods.SKIP_STEAM]) : setPinnedLaunchMods(prev => prev.filter(mod => mod !== LaunchMods.SKIP_STEAM)),
|
||||
},
|
||||
{
|
||||
id: LaunchMods.EDITOR,
|
||||
icon: EditIcon,
|
||||
label: t("pages.version-viewer.launch-mods.map-editor"),
|
||||
description: t("pages.version-viewer.launch-mods.map-editor-description"),
|
||||
active: activeLaunchMods.includes(LaunchMods.EDITOR),
|
||||
pinned: pinnedLaunchMods.includes(LaunchMods.EDITOR),
|
||||
visible: !safeLt(version.BSVersion, "1.23.0"),
|
||||
onChange: checked => checked ? setActiveLaunchMods(prev => [...prev, LaunchMods.EDITOR]) : setActiveLaunchMods(prev => prev.filter(mod => mod !== LaunchMods.EDITOR)),
|
||||
onPinChange: pinned => pinned ? setPinnedLaunchMods(prev => [...prev, LaunchMods.EDITOR]) : setPinnedLaunchMods(prev => prev.filter(mod => mod !== LaunchMods.EDITOR)),
|
||||
|
||||
}
|
||||
]);
|
||||
}, [activeLaunchMods, pinnedLaunchMods, version]);
|
||||
@@ -123,8 +136,8 @@ export function LaunchSlide({ version }: Props) {
|
||||
}, [version]);
|
||||
|
||||
return (
|
||||
<div className="w-full shrink-0 items-center relative flex flex-col justify-start">
|
||||
<div className="flex flex-col gap-3 justify-center items-center mb-5">
|
||||
<div className="w-full shrink-0 items-center relative flex flex-col justify-start overflow-hidden">
|
||||
<div className="flex flex-col gap-3 justify-center items-center mb-4">
|
||||
<div className="h-24 flex justify-center items-center">
|
||||
<BsmImage className="relative object-cover h-28" image={BSLogo} />
|
||||
</div>
|
||||
@@ -139,12 +152,12 @@ export function LaunchSlide({ version }: Props) {
|
||||
)}
|
||||
</h1>
|
||||
</div>
|
||||
<div className="grid grid-flow-col gap-6">
|
||||
<div className="w-full flex justify-center items-center gap-4 flex-wrap scrollbar-default">
|
||||
{pinnedLaunchMods.map(id => launchModItems.find(mod => mod.id === id)).map(launchMod => {
|
||||
if(launchMod?.visible === false || !launchMod?.pinned) { return undefined; }
|
||||
return (
|
||||
<LaunchModToogle
|
||||
icon={launchMod.Icon}
|
||||
icon={launchMod.icon}
|
||||
infoText={launchMod.description}
|
||||
text={launchMod.label}
|
||||
active={launchMod.active}
|
||||
@@ -153,7 +166,7 @@ export function LaunchSlide({ version }: Props) {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="pt-4 w-2/3 flex flex-col items-center gap-3">
|
||||
<div className="mt-4 flex flex-col items-center justify-center gap-3">
|
||||
<div className="relative">
|
||||
<GlowEffect className="!rounded-full" visible={!!(activeLaunchMods?.length || additionalArgsString)}/>
|
||||
<BsmButton
|
||||
|
||||
@@ -5,6 +5,7 @@ export const LaunchMods = {
|
||||
FPFC: "fpfc",
|
||||
DEBUG: "debug",
|
||||
SKIP_STEAM: "skip_steam",
|
||||
EDITOR: "editor",
|
||||
} as const;
|
||||
|
||||
export type LaunchMod = typeof LaunchMods[keyof typeof LaunchMods];
|
||||
|
||||
Reference in New Issue
Block a user