[chore] added a beat saber version outdated warning in the version view

This commit is contained in:
MathieuG-P
2024-11-24 21:26:47 +01:00
parent 229a149f00
commit 7b658de727
17 changed files with 170 additions and 13 deletions
@@ -18,7 +18,7 @@ export const BSVersionOutdatedModal: ModalComponent<void, { outdated: BSVersion,
const handleContinue = () => {
if (remember) {
config.set("not-show-bs-version-outdated", true);
config.set("not-show-bs-version-outdated-modal", true);
}
resolver({ exitCode: ModalExitCode.COMPLETED });
@@ -66,9 +66,10 @@ import { CleanIcon } from "./icons/clean-icon.component";
import { BrowseIcon } from "./icons/browse-icon.component";
import { AddFileIcon } from "./icons/add-file-icon.component";
import { CancelIcon } from "./icons/cancel-icon.component";
import { WarningIcon } from "./icons/warning-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" | "cancel" | "fr-FR-flag" | "es-ES-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");
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" | "cancel" | "warning" | "fr-FR-flag" | "es-ES-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");
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
@@ -281,6 +282,10 @@ export const BsmIcon = memo(({ className, icon, style }: { className?: string; i
return <CancelIcon className={className} style={style} />;
}
if(icon === "warning"){
return <WarningIcon className={className} style={style} />;
}
return <TrashIcon className={className} style={style} />;
@@ -0,0 +1,9 @@
import { createSvgIcon } from "../svg-icon.type";
export const WarningIcon = createSvgIcon((props, ref) => {
return (
<svg ref={ref} {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor">
<path d="M80-78q-15 0-27-8t-19-19q-7-11-7.5-25t7.5-28l400-689q8-14 20-20t26-6q14 0 26 6t20 20l400 689q8 14 7.5 28t-7.5 25q-7 11-19 19t-27 8H80Zm401-135q22 0 37.5-15.5T534-266q0-22-15.5-37.5T481-319q-22 0-37.5 15.5T428-266q0 22 15.5 37.5T481-213Zm0-143q22 0 37.5-15.5T534-409v-98q0-22-15.5-37.5T481-560q-22 0-37.5 15.5T428-507v98q0 22 15.5 37.5T481-356Z"/>
</svg>
);
})
@@ -1,7 +1,7 @@
import { ChangeEvent, useEffect, useState } from "react";
import { ChangeEvent, useEffect, useMemo, useState } from "react";
import { BsmButton } from "renderer/components/shared/bsm-button.component";
import { useObservable } from "renderer/hooks/use-observable.hook";
import { useTranslation } from "renderer/hooks/use-translation.hook";
import { useTranslationV2 } from "renderer/hooks/use-translation.hook";
import { BSLauncherService, LaunchMods } from "renderer/services/bs-launcher.service";
import { ConfigurationService } from "renderer/services/configuration.service";
import { BSVersion } from "shared/bs-version.interface";
@@ -15,15 +15,20 @@ import { BsDownloaderService } from "renderer/services/bs-version-download/bs-do
import equal from "fast-deep-equal";
import { GlowEffect } from "renderer/components/shared/glow-effect.component";
import { cn } from "renderer/helpers/css-class.helpers";
import { BSVersionManagerService } from "renderer/services/bs-version-manager.service";
import { safeLt } from "shared/helpers/semver.helpers";
import { WarningIcon } from "renderer/components/svgs/icons/warning-icon.component";
import Tippy from "@tippyjs/react";
type Props = { version: BSVersion };
export function LaunchSlide({ version }: Props) {
const t = useTranslation();
const { text: t, element: te } = useTranslationV2();
const configService = useService(ConfigurationService);
const bsLauncherService = useService(BSLauncherService);
const bsDownloader = useService(BsDownloaderService);
const versions = useService(BSVersionManagerService);
const [oculusMode, setOculusMode] = useState(!!configService.get<boolean>(LaunchMods.OCULUS_MOD));
const [desktopMode, setDesktopMode] = useState(!!configService.get<boolean>(LaunchMods.DESKTOP_MOD));
@@ -71,11 +76,24 @@ export function LaunchSlide({ version }: Props) {
return lastValueFrom(launch$).catch(() => {});
};
const isOutdated = useMemo(() => {
return safeLt(version?.BSVersion, versions.getRecommendedVersion()?.BSVersion);
}, [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">
<BsmImage className="relative object-cover h-28" image={BSLogo} />
<h1 className="relative text-4xl font-bold italic -top-3">{version.name ? `${version.BSVersion} - ${version.name}` : version.BSVersion}</h1>
<h1 className="relative text-4xl font-bold italic -top-3">
{version.name ? `${version.BSVersion} - ${version.name}` : version.BSVersion}
{isOutdated && (
<Tippy theme="default" content={te("pages.version-viewer.launch-mods.outdated-tippy", { recommendedVersion: <b>{versions.getRecommendedVersion().BSVersion}</b> })}>
<span className="absolute bg-theme-1 size-7 rounded-full p-1.5 flex justify-center items-center -right-2 top-2 translate-x-full translate-y-px cursor-help">
<WarningIcon className="text-warning-400 animate-pulse"/>
</span>
</Tippy>
)}
</h1>
</div>
<div className="grid grid-flow-col gap-6">
{!(version.oculus || version.metadata?.store === BsStore.OCULUS) && <LaunchModToogle infoText="pages.version-viewer.launch-mods.oculus-description" icon="oculus" onClick={() => setMode(LaunchMods.OCULUS_MOD, !oculusMode)} active={oculusMode} text="pages.version-viewer.launch-mods.oculus" />}
@@ -111,3 +129,5 @@ export function LaunchSlide({ version }: Props) {
</div>
);
}
@@ -15,8 +15,7 @@ import { logRenderError } from "renderer";
import { ModalExitCode, ModalService } from "renderer/services/modale.service";
import { BSVersionOutdatedModal } from "renderer/components/modal/modal-types/bs-version-outdated-modal.component";
import { ConfigurationService } from "renderer/services/configuration.service";
import { coerce, lt, valid } from "semver";
import { tryit } from "shared/helpers/error.helpers";
import { safeLt } from "shared/helpers/semver.helpers";
export const AvailableVersionsContext = createContext<{ selectedVersion: BSVersion; setSelectedVersion: (version: BSVersion) => void }>(null);
@@ -34,12 +33,10 @@ export function AvailableVersionsList() {
const t = useTranslation();
const startDownload = async (version: BSVersion) => {
const showOutdated = !config.get("not-show-bs-version-outdated");
const recommendedVersion = showOutdated ? versionManager.availableVersions$.value.find(v => v.recommended) : undefined;
const showOutdated = !config.get("not-show-bs-version-outdated-modal");
const recommendedVersion = versionManager.getRecommendedVersion();
const isVersionOutdated = recommendedVersion?.BSVersion ? (
tryit(() => lt(valid(coerce(version.BSVersion)), valid(coerce(recommendedVersion.BSVersion)))).result ?? false
) : false;
const isVersionOutdated = safeLt(version.BSVersion, recommendedVersion?.BSVersion);
if (showOutdated && isVersionOutdated) {
@@ -21,6 +21,9 @@ import { CreateLaunchShortcutModal } from "renderer/components/modal/modal-types
import { lastValueFrom } from "rxjs";
import { NotificationService } from "renderer/services/notification.service";
import { BsDownloaderService } from "renderer/services/bs-version-download/bs-downloader.service";
import { useOnUpdate } from "renderer/hooks/use-on-update.hook";
import { safeLt } from "shared/helpers/semver.helpers";
import { ConfigurationService } from "renderer/services/configuration.service";
export function VersionViewer() {
@@ -31,11 +34,41 @@ export function VersionViewer() {
const ipcService = useService(IpcService);
const bsLauncher = useService(BSLauncherService);
const notification = useService(NotificationService);
const config = useService(ConfigurationService);
const { state } = useLocation() as { state: BSVersion };
const navigate = useNavigate();
const [currentTabIndex, setCurrentTabIndex] = useState(0);
useOnUpdate(() => {
checkIsVersionOutaded();
}, [state]);
const checkIsVersionOutaded = async () => {
if(config.get("not-show-bs-version-outdated-notification")){
return;
}
const recommended = bsVersionManagerService.getRecommendedVersion();
const isOutdated = safeLt(state.BSVersion, recommended?.BSVersion);
if(!isOutdated){
return;
}
const res = await notification.notifyWarning({ title: "notifications.bs-version-oudated.title", desc: "notifications.bs-version-oudated.msg", duration: 9000, actions: [
{ id: "0", title: "notifications.bs-version-oudated.actions.do-not-remind" },
{ id: "1", title: "notifications.bs-version-oudated.actions.ok", cancel: true }
] });
if(res === "0"){
config.set("not-show-bs-version-outdated-notification", true);
}
}
const navigateToVersion = (version?: BSVersion) => {
if (!version) {
return navigate("/available-versions");
@@ -211,4 +211,8 @@ export class BSVersionManagerService {
version
]))).values());
}
public getRecommendedVersion(): BSVersion | undefined {
return (this.availableVersions$.value ?? []).find(v => v.recommended);
}
}
+8
View File
@@ -0,0 +1,8 @@
import { coerce, lt, valid } from "semver";
import { tryit } from "./error.helpers";
export function safeLt(a: string, b: string): boolean {
const { result } = tryit(() => lt(valid(coerce(a)), valid(coerce(b))));
return result ?? false;
}