diff --git a/src/app/editor/[id]/page.tsx b/src/app/editor/[id]/page.tsx index c22cdec..3b564bd 100644 --- a/src/app/editor/[id]/page.tsx +++ b/src/app/editor/[id]/page.tsx @@ -1885,6 +1885,7 @@ function normalizeReplaysForCompare(input: BattleReplay[] | null | undefined) { return list .filter((replay) => replay && typeof replay.geometry_id === "string" && replay.geometry_id.trim().length > 0) .map((replay) => ({ + id: typeof replay.id === "string" ? replay.id : replay.geometry_id, geometry_id: replay.geometry_id, target_geometry_ids: normalizeReplayTargetGeometryIdsForCompare( replay.target_geometry_ids, diff --git a/src/uhm/doc/commit_snapshot.ts b/src/uhm/doc/commit_snapshot.ts index 82f867d..bcf5d92 100644 --- a/src/uhm/doc/commit_snapshot.ts +++ b/src/uhm/doc/commit_snapshot.ts @@ -203,6 +203,7 @@ export type ReplayStage = { }; export type BattleReplay = { + id: string; geometry_id: string; target_geometry_ids: string[]; detail: ReplayStage[]; diff --git a/src/uhm/doc/editor_state_replay.md b/src/uhm/doc/editor_state_replay.md index 549f8bb..5a02742 100644 --- a/src/uhm/doc/editor_state_replay.md +++ b/src/uhm/doc/editor_state_replay.md @@ -30,6 +30,7 @@ Replay mode hiện tại có 2 lớp state: ```ts type BattleReplay = { + id: string; geometry_id: string; target_geometry_ids: string[]; detail: ReplayStage[]; @@ -41,6 +42,9 @@ type BattleReplay = { - `geometry_id` - MAIN geo của replay - cũng là key để tìm replay tương ứng +- `id` + - hiện luôn bằng `geometry_id` + - thêm để schema replay có id riêng rõ ràng hơn - `target_geometry_ids` - toàn bộ geo được đưa vào replay - phần tử đầu nên luôn là MAIN geo @@ -66,6 +70,7 @@ Replay seed mới có dạng: ```ts { + id: triggerId, geometry_id: triggerId, target_geometry_ids: [...], detail: [] diff --git a/src/uhm/doc/export_json_replay.md b/src/uhm/doc/export_json_replay.md index 63add7a..44528d2 100644 --- a/src/uhm/doc/export_json_replay.md +++ b/src/uhm/doc/export_json_replay.md @@ -57,6 +57,7 @@ type ReplayExportPayload = { ```ts type BattleReplay = { + id: string; geometry_id: string; target_geometry_ids: string[]; detail: ReplayStage[]; @@ -67,6 +68,8 @@ type BattleReplay = { - `geometry_id` - MAIN geo của replay +- `id` + - hiện luôn bằng `geometry_id` - `target_geometry_ids` - toàn bộ geo thuộc replay - phần tử đầu nên luôn là MAIN geo @@ -124,6 +127,7 @@ type ReplayStep = { "exported_at": "2026-05-17T12:34:56.000Z", "geometry_id": "019e13ab-4823-76c5-afde-2391c0cf311d", "current_replay": { + "id": "019e13ab-4823-76c5-afde-2391c0cf311d", "geometry_id": "019e13ab-4823-76c5-afde-2391c0cf311d", "target_geometry_ids": [ "019e13ab-4823-76c5-afde-2391c0cf311d", @@ -176,6 +180,7 @@ type ReplayStep = { "snapshot_fragment": { "replays": [ { + "id": "019e13ab-4823-76c5-afde-2391c0cf311d", "geometry_id": "019e13ab-4823-76c5-afde-2391c0cf311d", "target_geometry_ids": [ "019e13ab-4823-76c5-afde-2391c0cf311d", diff --git a/src/uhm/lib/editor/snapshot/editorSnapshot.ts b/src/uhm/lib/editor/snapshot/editorSnapshot.ts index 19a2480..29f1f3f 100644 --- a/src/uhm/lib/editor/snapshot/editorSnapshot.ts +++ b/src/uhm/lib/editor/snapshot/editorSnapshot.ts @@ -705,6 +705,7 @@ export function toApiEditorSnapshot(snapshot: EditorSnapshot): EditorSnapshot { cloned.replays = cloned.replays.map((replay) => { const geometryId = typeof replay?.geometry_id === "string" ? replay.geometry_id : ""; return { + id: geometryId, geometry_id: geometryId, target_geometry_ids: normalizeReplayTargetGeometryIds(replay as unknown, geometryId), detail: Array.isArray(replay?.detail) ? replay.detail : [], @@ -721,8 +722,14 @@ function normalizeReplaySnapshots(value: unknown): BattleReplay[] | undefined { } function normalizeReplaySnapshot(replay: BattleReplay): BattleReplay { - const geometryId = typeof replay?.geometry_id === "string" ? replay.geometry_id : ""; + const geometryId = + typeof replay?.geometry_id === "string" && replay.geometry_id.trim().length > 0 + ? replay.geometry_id + : typeof (replay as unknown as { id?: unknown })?.id === "string" + ? (replay as unknown as { id: string }).id + : ""; return { + id: geometryId, geometry_id: geometryId, target_geometry_ids: normalizeReplayTargetGeometryIds(replay, geometryId), detail: Array.isArray(replay.detail) diff --git a/src/uhm/lib/editor/state/useEditorState.ts b/src/uhm/lib/editor/state/useEditorState.ts index 368c734..2e2a784 100644 --- a/src/uhm/lib/editor/state/useEditorState.ts +++ b/src/uhm/lib/editor/state/useEditorState.ts @@ -716,6 +716,7 @@ function createReplaySessionSeed( selectedIds: (string | number)[] ): BattleReplay { return { + id: geometryId, geometry_id: geometryId, target_geometry_ids: buildReplaySeedTargetIds( sourceDraft.features.find((feature) => String(feature.properties.id) === geometryId), @@ -733,6 +734,7 @@ function normalizeReplaySessionSeed( selectedIds: (string | number)[] ): BattleReplay { const nextReplay = deepClone(replay); + nextReplay.id = geometryId; const triggerFeature = sourceDraft.features.find((feature) => String(feature.properties.id) === geometryId); const seedTargetIds = buildReplaySeedTargetIds(triggerFeature, geometryId, selectedIds); nextReplay.target_geometry_ids = normalizeReplayTargetGeometryIds( diff --git a/src/uhm/types/projects.ts b/src/uhm/types/projects.ts index a1376c0..72b8a8e 100644 --- a/src/uhm/types/projects.ts +++ b/src/uhm/types/projects.ts @@ -154,6 +154,7 @@ export type ReplayStage = { }; export type BattleReplay = { + id: string; // mirror của geometry_id để đồng bộ schema chung geometry_id: string; // geometry mà khi nhấn vào là có thể replay target_geometry_ids: string[]; // tập geometry được đưa vào replay, phần tử đầu nên là MAIN geo detail: ReplayStage[];