feat: Add support for Studio single-room dumps in RoomZipImportController and update ImportRoom UI

This commit is contained in:
Alexa
2026-06-25 15:25:58 +03:00
parent 44fc9047e0
commit 9d33b1f4d6
2 changed files with 18 additions and 0 deletions
@@ -140,6 +140,14 @@ public class RoomZipImportController(
{
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
// RecNet serializes large snowflake-style IDs (SubRoomId, save IDs)
// as JSON strings to avoid JS 2^53 precision loss, while smaller/older
// IDs stay as raw numbers — and a single SubRooms[] array can mix both
// forms (Showdown's export is numeric for entries 0-17, then string
// from "SD_Archive_120822_Catalyst" on). Allow numeric properties to
// read from either token so the import doesn't crash on the first
// string-encoded ID.
NumberHandling = JsonNumberHandling.AllowReadingFromString,
};
// ── RoomDetails.json DTOs ──────────────────────────────────────────
@@ -95,6 +95,9 @@ interface PreviewRoom {
/// release window — see CLIENT_BUILD_CUTOFF.
latestModifiedAt: string | null;
postBuildCutoff: boolean;
/// True when this room came from a Studio single-room dump (room.json +
/// SubRooms/<scene>/ saves) rather than a standard RoomDetails.json export.
isStudio: boolean;
}
interface PreviewSubroom {
@@ -545,6 +548,11 @@ export function ImportRoom() {
<span className="font-medium text-ink-50">{r.name}</span>
</label>
<span className="text-xs text-ink-500 font-mono">{r.folder.split('/').pop()}</span>
{r.isStudio && (
<span className="badge-online" title="Imported from a RR Studio single-room dump (room.json + SubRooms/<scene>/ saves).">
Studio
</span>
)}
{!r.hasImage && <span className="badge-junior">no image</span>}
{r.postBuildCutoff && (
<span
@@ -1088,6 +1096,7 @@ async function parseZipPreview(file: File, onProgress?: (percent: number) => voi
promoImageCount,
latestModifiedAt,
postBuildCutoff,
isStudio: false,
});
bump();
}
@@ -1213,6 +1222,7 @@ async function parseZipPreview(file: File, onProgress?: (percent: number) => voi
promoImageCount,
latestModifiedAt,
postBuildCutoff,
isStudio: true,
});
bump();
}