diff --git a/nise-replay-viewer/src/interface/App.tsx b/nise-replay-viewer/src/interface/App.tsx index bf96af4..3467b78 100644 --- a/nise-replay-viewer/src/interface/App.tsx +++ b/nise-replay-viewer/src/interface/App.tsx @@ -5,6 +5,7 @@ import {Helper} from "./composites/helper"; import {useEffect} from "react"; import {OsuRenderer} from "@/osu/OsuRenderer"; import {Stats} from "@/interface/composites/stats"; +import {LoadingDialog} from "@/interface/composites/loading-dialog"; export function App() { @@ -38,6 +39,7 @@ export function App() { <> + diff --git a/nise-replay-viewer/src/interface/components/ui/dialog.tsx b/nise-replay-viewer/src/interface/components/ui/dialog.tsx index c23630e..7898db1 100644 --- a/nise-replay-viewer/src/interface/components/ui/dialog.tsx +++ b/nise-replay-viewer/src/interface/components/ui/dialog.tsx @@ -28,28 +28,31 @@ const DialogOverlay = React.forwardRef< DialogOverlay.displayName = DialogPrimitive.Overlay.displayName const DialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - {children} - - - Close - - - + React.ElementRef, + React.ComponentPropsWithoutRef & { hideCloseButton?: boolean } // Add hideCloseButton prop +>(({ className, children, hideCloseButton, ...props }, ref) => ( + + + + {children} + {!hideCloseButton && ( // Conditionally render based on hideCloseButton + + + Close + + )} + + )) -DialogContent.displayName = DialogPrimitive.Content.displayName +DialogContent.displayName = DialogPrimitive.Content.displayName; + const DialogHeader = ({ className, diff --git a/nise-replay-viewer/src/interface/composites/loading-dialog.tsx b/nise-replay-viewer/src/interface/composites/loading-dialog.tsx new file mode 100644 index 0000000..95901a8 --- /dev/null +++ b/nise-replay-viewer/src/interface/composites/loading-dialog.tsx @@ -0,0 +1,27 @@ +import { Dialog, DialogContent } from "@/interface/components/ui/dialog"; +import { state } from "@/utils"; + +export function LoadingDialog() { + const { beatmap, replay} = state(); + + if (beatmap && replay) { + return; + } + + return ( + + +
+

+ Loading replay... +

+
+

Your replay is being loaded

+
+
+
+
+ ); +} diff --git a/nise-replay-viewer/src/osu/Drawer.ts b/nise-replay-viewer/src/osu/Drawer.ts index ca45bbf..f6cc2f4 100644 --- a/nise-replay-viewer/src/osu/Drawer.ts +++ b/nise-replay-viewer/src/osu/Drawer.ts @@ -38,10 +38,18 @@ export class Drawer { } static async loadDefaultImages() { - for (const imageName of Object.keys(Drawer.images)) { - Drawer.images[imageName as keyof typeof Drawer.images] = - await loadImageAsync(`/${imageName}.png`); - } + const imageLoadPromises = Object.keys(Drawer.images).map(imageName => + loadImageAsync(`/${imageName}.png`).then( + image => { + Drawer.images[imageName as keyof typeof Drawer.images] = image; + }, + error => { + console.error(`Failed to load image ${imageName}:`, error); + } + ) + ); + + return Promise.allSettled(imageLoadPromises) } static setImages(images: typeof this.images) { @@ -97,7 +105,7 @@ export class Drawer { // Drawer.p.strokeWeight(2); // Drawer.p.line(barX + barWidth / 2, barY - 5, barX + barWidth / 2, barY + barHeight + 5); - Drawer.p.pop(); + // Drawer.p.pop(); } //@ts-ignore diff --git a/nise-replay-viewer/src/osu/OsuRenderer.ts b/nise-replay-viewer/src/osu/OsuRenderer.ts index d2cc835..93b70d9 100644 --- a/nise-replay-viewer/src/osu/OsuRenderer.ts +++ b/nise-replay-viewer/src/osu/OsuRenderer.ts @@ -12,7 +12,7 @@ import { } from "osu-standard-stable"; import {Drawer} from "./Drawer"; import {Vec2} from "@osujs/math"; -import {clamp, getBeatmap, getReplay} from "@/utils"; +import {clamp, getBeatmap, getReplay, state} from "@/utils"; import EventEmitter from "eventemitter3"; import {toast} from "sonner"; import p5 from "p5"; @@ -303,6 +303,11 @@ export class OsuRenderer { const i_beatmap = await getBeatmap(beatmap, i_replay); OsuRenderer.setOptions(i_beatmap, i_replay, judgements); + state.setState({ + beatmap: i_beatmap, + replay: i_replay, + mods: i_replay.info.mods?.all, + }); this.event.emit(OsuRendererEvents.LOAD); } diff --git a/nise-replay-viewer/src/renderer.ts b/nise-replay-viewer/src/renderer.ts index fa10295..57bb562 100644 --- a/nise-replay-viewer/src/renderer.ts +++ b/nise-replay-viewer/src/renderer.ts @@ -13,7 +13,7 @@ export class Renderer { Renderer.registerEvents(); Drawer.setP(p); - await Drawer.loadDefaultImages().then( + Drawer.loadDefaultImages().then( () => { Renderer.areImagesLoaded = true; OsuRenderer.setPlaying(true); diff --git a/nise-replay-viewer/src/style.css b/nise-replay-viewer/src/style.css index ab702c4..a9057da 100644 --- a/nise-replay-viewer/src/style.css +++ b/nise-replay-viewer/src/style.css @@ -3,7 +3,7 @@ font-style: normal; font-display: swap; font-weight: 400; - src: url('https://replay.nise.moe/ia-quattro-400-normal.woff2') format('woff2'); + src: url('/ia-quattro-400-normal.woff2') format('woff2'); } @font-face { @@ -11,7 +11,7 @@ font-style: normal; font-display: swap; font-weight: 700; - src: url('https://replay.nise.moe/ia-quattro-700-normal.woff2') format('woff2'); + src: url('/ia-quattro-700-normal.woff2') format('woff2'); } #app { diff --git a/nise-replay-viewer/src/utils.ts b/nise-replay-viewer/src/utils.ts index 21ef2a8..f473870 100644 --- a/nise-replay-viewer/src/utils.ts +++ b/nise-replay-viewer/src/utils.ts @@ -3,7 +3,7 @@ import { ScoreDecoder } from "../osu-parsers"; import { StandardRuleset, StandardBeatmap } from "osu-standard-stable"; import { IMod, Score } from "osu-classes"; -import p5, { Image } from "p5"; +import p5 from "p5"; import { create } from "zustand"; const ruleset = new StandardRuleset(); @@ -27,11 +27,17 @@ export async function getBeatmap(mapText: string, scoreBase: Score) { return ruleset.applyToBeatmap(map); } -export async function loadImageAsync(image: string): Promise { - return new Promise((res) => { - p.loadImage(image, (img) => { - res(img); - }); +export async function loadImageAsync(image: string): Promise { + return new Promise((resolve, reject) => { + p.loadImage( + image, + (img) => { + resolve(img); + }, + (err) => { + reject(err); + } + ); }); }