refactor(lab): объединить RAV004 в единый Rerun replay
This commit is contained in:
@@ -36,7 +36,6 @@ import {
|
||||
createRecordedAutoplayGate,
|
||||
createRecordedInitialSeekGate,
|
||||
createRecordedOpenWatchdog,
|
||||
shouldReapplyRecordedBlueprint,
|
||||
} from "../core/observation/recordedRerunLifecycle";
|
||||
import type {
|
||||
RecordedPerceptionLayers,
|
||||
@@ -72,7 +71,6 @@ export {
|
||||
recordedPlaybackRangeWhenReady,
|
||||
recordedPointColorKey,
|
||||
rerunPresentationStatus,
|
||||
shouldReapplyRecordedBlueprint,
|
||||
type RecordedPlaybackBufferState,
|
||||
} from "../core/observation/recordedRerunLifecycle";
|
||||
export {
|
||||
@@ -167,6 +165,7 @@ interface RecordedRerunIdentity {
|
||||
}
|
||||
|
||||
const RECORDED_RRD_PATH = /^\/api\/v1\/observation-sessions\/[A-Za-z0-9][A-Za-z0-9._:-]{0,127}\/recording\.rrd$/;
|
||||
const LAB_RECORDED_REPLAY_PATH = /^\/api\/v1\/laboratory\/vegetation-shadow\/lab-v1-vegetation-shadow-[a-f0-9]{64}\/canonical-replay\.rrd$/;
|
||||
const RECORDED_BLUEPRINT_PATH = /^\/api\/v1\/observation-sessions\/[A-Za-z0-9][A-Za-z0-9._:-]{0,127}\/blueprint\.rrd$/;
|
||||
const RECORDED_PERCEPTION_PATH = /^\/api\/v1\/observation-sessions\/[A-Za-z0-9][A-Za-z0-9._:-]{0,127}\/perception\.rrd$/;
|
||||
const LAB_RECORDED_PERCEPTION_PATH = /^\/api\/v1\/laboratory\/vegetation-shadow\/lab-v1-vegetation-shadow-[a-f0-9]{64}\/canonical-overlay\.rrd$/;
|
||||
@@ -231,7 +230,8 @@ export function resolveRecordedViewerSourceUrl(
|
||||
const expectedViewerSourceUrl = `${descriptor.sourceUrl}?generation=${descriptor.sha256}`;
|
||||
const endpoint = new URL(descriptor.viewerSourceUrl, `${base.origin}/`);
|
||||
if (
|
||||
!RECORDED_RRD_PATH.test(descriptor.sourceUrl) ||
|
||||
!(RECORDED_RRD_PATH.test(descriptor.sourceUrl)
|
||||
|| LAB_RECORDED_REPLAY_PATH.test(descriptor.sourceUrl)) ||
|
||||
descriptor.viewerSourceUrl !== expectedViewerSourceUrl ||
|
||||
endpoint.origin !== base.origin ||
|
||||
endpoint.pathname !== descriptor.sourceUrl ||
|
||||
@@ -252,10 +252,23 @@ export function rerunViewerInitialSource(
|
||||
return resolvedSourceUrl;
|
||||
}
|
||||
|
||||
export function resolveRecordedBlueprintUrl(sourceUrl: string, origin: string): string | null {
|
||||
export function resolveRecordedBlueprintUrl(
|
||||
sourceUrl: string,
|
||||
origin: string,
|
||||
explicitSourceUrl?: string,
|
||||
): string | null {
|
||||
const normalized = sourceUrl.trim();
|
||||
if (!RECORDED_RRD_PATH.test(normalized)) return null;
|
||||
const base = new URL(origin);
|
||||
if (explicitSourceUrl !== undefined) {
|
||||
const explicit = explicitSourceUrl.trim();
|
||||
if (
|
||||
!LAB_RECORDED_REPLAY_PATH.test(normalized)
|
||||
|| !RECORDED_BLUEPRINT_PATH.test(explicit)
|
||||
) return null;
|
||||
const endpoint = new URL(explicit, `${base.origin}/`);
|
||||
return endpoint.origin === base.origin ? endpoint.href : null;
|
||||
}
|
||||
if (!RECORDED_RRD_PATH.test(normalized)) return null;
|
||||
const endpoint = new URL(
|
||||
normalized.replace(/\/recording\.rrd$/, "/blueprint.rrd"),
|
||||
`${base.origin}/`,
|
||||
@@ -690,6 +703,7 @@ export function RerunViewport({
|
||||
segmentation: false,
|
||||
cuboids3d: false,
|
||||
};
|
||||
const recordedBlueprintSourceUrl = recordedProfile?.blueprintSourceUrl;
|
||||
const recordedPerceptionSourceUrl = recordedProfile?.perceptionSourceUrl;
|
||||
const recordedSemanticLayer = recordedProfile?.semanticLayer;
|
||||
const recordedUnifiedPerception = recordedProfile?.unifiedPerception ?? false;
|
||||
@@ -727,7 +741,11 @@ export function RerunViewport({
|
||||
const [blueprintChannelRevision, setBlueprintChannelRevision] = useState(0);
|
||||
const [perceptionChannelRevision, setPerceptionChannelRevision] = useState(0);
|
||||
const recordedBlueprintUrl = sourceUrl
|
||||
? resolveRecordedBlueprintUrl(sourceUrl, window.location.origin)
|
||||
? resolveRecordedBlueprintUrl(
|
||||
sourceUrl,
|
||||
window.location.origin,
|
||||
recordedBlueprintSourceUrl,
|
||||
)
|
||||
: null;
|
||||
const recordedPerceptionUrl = recordedPerceptionSourceUrl
|
||||
? resolveRerunSourceUrl(recordedPerceptionSourceUrl, window.location.origin)
|
||||
@@ -773,7 +791,8 @@ export function RerunViewport({
|
||||
return;
|
||||
}
|
||||
|
||||
const isRecordedSource = RECORDED_RRD_PATH.test(normalizedSource);
|
||||
const isRecordedSource = RECORDED_RRD_PATH.test(normalizedSource)
|
||||
|| LAB_RECORDED_REPLAY_PATH.test(normalizedSource);
|
||||
let resolvedSource: string;
|
||||
try {
|
||||
if (isRecordedSource) {
|
||||
@@ -1151,23 +1170,7 @@ export function RerunViewport({
|
||||
disposed ||
|
||||
(isRecordedSource && event.application_id !== "nodedc_mission_core_recorded")
|
||||
) return;
|
||||
if (recordingOpened) {
|
||||
const identity = recordedIdentityRef.current;
|
||||
if (shouldReapplyRecordedBlueprint(
|
||||
recordingOpened,
|
||||
isRecordedSource,
|
||||
recordedBlueprintUrl !== null,
|
||||
identity,
|
||||
event,
|
||||
)) {
|
||||
// A LAB sidecar is a second upstream receiver for the same
|
||||
// recording store. Rerun re-opens that store only after the
|
||||
// sidecar has been decoded, so reapply the canonical blueprint
|
||||
// at this exact boundary instead of racing it during download.
|
||||
setBlueprintChannelRevision((revision) => revision + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (recordingOpened) return;
|
||||
recordingOpened = true;
|
||||
if (!isRecordedSource) {
|
||||
// Store discovery only establishes a candidate. Admission is
|
||||
|
||||
@@ -242,7 +242,7 @@ export function CanonicalRecordedLabReplay<
|
||||
minPrimarySize={splitView ? 24 : 0}
|
||||
minSecondarySize={splitView ? 24 : 0}
|
||||
resizable={splitView}
|
||||
separatorLabel="Изменить размер VIDEO/CAMERA и 3D/PLAN"
|
||||
separatorLabel="Изменить размер видео/камеры и 3D/плана"
|
||||
/>
|
||||
{mediaMode === "none" && spatialMode === "none" ? (
|
||||
<div className="l3-visual-audit__state" role="status">
|
||||
|
||||
Reference in New Issue
Block a user