@neurodyn/react-room-viewer 0.0.31 → 0.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -93,6 +93,17 @@ declare const resources: {
93
93
  readonly 'artwork-load-failed': "The image could not be loaded — its link is missing or incorrect in the widget settings.";
94
94
  readonly 'room-load-failed': "The room photo could not be loaded. Please try again.";
95
95
  };
96
+ readonly missingSurface: {
97
+ readonly floor: {
98
+ readonly title: "We couldn't find the floor";
99
+ readonly body: "Try a photo that shows the floor.";
100
+ };
101
+ readonly wall: {
102
+ readonly title: "We couldn't find a wall";
103
+ readonly body: "Try a photo that shows a wall.";
104
+ };
105
+ readonly uploadAnother: "Upload another photo";
106
+ };
96
107
  readonly wallPanel: {
97
108
  readonly loading: "Loading material";
98
109
  readonly panelActions: "Panel {{number}} actions";
@@ -233,6 +244,17 @@ declare const resources: {
233
244
  readonly 'artwork-load-failed': "Не удалось загрузить изображение — ссылка на него отсутствует или указана неверно в настройках виджета.";
234
245
  readonly 'room-load-failed': "Не удалось загрузить фото комнаты. Попробуйте ещё раз.";
235
246
  };
247
+ readonly missingSurface: {
248
+ readonly floor: {
249
+ readonly title: "Не получилось найти пол";
250
+ readonly body: "Попробуйте фото, на котором виден пол.";
251
+ };
252
+ readonly wall: {
253
+ readonly title: "Не получилось найти стену";
254
+ readonly body: "Попробуйте фото, на котором видна стена.";
255
+ };
256
+ readonly uploadAnother: "Загрузить другое фото";
257
+ };
236
258
  readonly wallPanel: {
237
259
  readonly loading: "Загрузка материала";
238
260
  readonly panelActions: "Действия с панелью {{number}}";
package/dist/index.js CHANGED
@@ -6725,6 +6725,17 @@ const ns1 = {
6725
6725
  'artwork-load-failed': 'The image could not be loaded — its link is missing or incorrect in the widget settings.',
6726
6726
  'room-load-failed': 'The room photo could not be loaded. Please try again.'
6727
6727
  },
6728
+ missingSurface: {
6729
+ floor: {
6730
+ title: 'We couldn\'t find the floor',
6731
+ body: 'Try a photo that shows the floor.'
6732
+ },
6733
+ wall: {
6734
+ title: 'We couldn\'t find a wall',
6735
+ body: 'Try a photo that shows a wall.'
6736
+ },
6737
+ uploadAnother: 'Upload another photo'
6738
+ },
6728
6739
  wallPanel: {
6729
6740
  loading: 'Loading material',
6730
6741
  panelActions: 'Panel {{number}} actions',
@@ -6864,6 +6875,17 @@ const ns1_ns1 = {
6864
6875
  'artwork-load-failed': 'Не удалось загрузить изображение — ссылка на него отсутствует или указана неверно в настройках виджета.',
6865
6876
  'room-load-failed': 'Не удалось загрузить фото комнаты. Попробуйте ещё раз.'
6866
6877
  },
6878
+ missingSurface: {
6879
+ floor: {
6880
+ title: 'Не получилось найти пол',
6881
+ body: 'Попробуйте фото, на котором виден пол.'
6882
+ },
6883
+ wall: {
6884
+ title: 'Не получилось найти стену',
6885
+ body: 'Попробуйте фото, на котором видна стена.'
6886
+ },
6887
+ uploadAnother: 'Загрузить другое фото'
6888
+ },
6867
6889
  wallPanel: {
6868
6890
  loading: 'Загрузка материала',
6869
6891
  panelActions: 'Действия с панелью {{number}}',
@@ -7841,6 +7863,7 @@ const RESOURCE_TYPE_PROFILES = {
7841
7863
  surfaces: [
7842
7864
  'wall'
7843
7865
  ],
7866
+ missingSurfaceMessage: 'wall',
7844
7867
  lighting: 'static-neutral-hdr',
7845
7868
  roomPresets: 'wall-room-presets',
7846
7869
  chrome: 'immersive-room',
@@ -7861,6 +7884,7 @@ const RESOURCE_TYPE_PROFILES = {
7861
7884
  surfaces: [
7862
7885
  'wall'
7863
7886
  ],
7887
+ missingSurfaceMessage: 'wall',
7864
7888
  lighting: 'static-neutral-hdr',
7865
7889
  roomPresets: 'wall-room-presets',
7866
7890
  chrome: 'framed-scene',
@@ -7878,6 +7902,7 @@ const RESOURCE_TYPE_PROFILES = {
7878
7902
  surfaces: [
7879
7903
  'floor'
7880
7904
  ],
7905
+ missingSurfaceMessage: 'floor',
7881
7906
  lighting: 'remote-neutral-hdr',
7882
7907
  roomPresets: 'floor-room-presets',
7883
7908
  chrome: 'immersive-room',
@@ -7895,6 +7920,7 @@ const RESOURCE_TYPE_PROFILES = {
7895
7920
  surfaces: [
7896
7921
  'floor'
7897
7922
  ],
7923
+ missingSurfaceMessage: 'floor',
7898
7924
  lighting: 'remote-neutral-hdr',
7899
7925
  roomPresets: 'floor-room-presets',
7900
7926
  chrome: 'immersive-room',
@@ -8166,28 +8192,6 @@ function DropDownArrow(props) {
8166
8192
  })
8167
8193
  });
8168
8194
  }
8169
- function EditorRotate(props) {
8170
- return /*#__PURE__*/ jsxs("svg", {
8171
- xmlns: "http://www.w3.org/2000/svg",
8172
- viewBox: "0 0 24 24",
8173
- fill: "none",
8174
- ...props,
8175
- children: [
8176
- /*#__PURE__*/ jsx("path", {
8177
- d: "M21.25 12C21.25 6.89137 17.1086 2.75 12 2.75C6.89137 2.75 2.75 6.89137 2.75 12C2.75 17.1086 6.89137 21.25 12 21.25C17.1086 21.25 21.25 17.1086 21.25 12ZM22.75 12C22.75 17.9371 17.9371 22.75 12 22.75C6.06294 22.75 1.25 17.9371 1.25 12C1.25 6.06294 6.06294 1.25 12 1.25C17.9371 1.25 22.75 6.06294 22.75 12Z",
8178
- fill: "currentColor"
8179
- }),
8180
- /*#__PURE__*/ jsx("path", {
8181
- d: "M2.51074 11.4512C4.93062 13.704 8.34578 14.76 11.8662 14.75C15.3868 14.74 18.9326 13.6626 21.5586 11.75L22.4414 12.9619C19.5314 15.0814 15.6692 16.2392 11.8701 16.25C8.07098 16.2607 4.25427 15.1229 1.48926 12.5488L2.51074 11.4512Z",
8182
- fill: "currentColor"
8183
- }),
8184
- /*#__PURE__*/ jsx("path", {
8185
- d: "M12.064 2.5332C9.97218 4.60314 8.74951 8.13693 8.74367 11.8135C8.7379 15.4824 9.94419 19.1271 12.4976 21.4443L11.4898 22.5557C8.53343 19.873 7.23749 15.7674 7.24367 11.8115C7.24989 7.86332 8.55333 3.89687 11.0093 1.4668L12.064 2.5332Z",
8186
- fill: "currentColor"
8187
- })
8188
- ]
8189
- });
8190
- }
8191
8195
  function EditorTrash(props) {
8192
8196
  return /*#__PURE__*/ jsx("svg", {
8193
8197
  xmlns: "http://www.w3.org/2000/svg",
@@ -8501,6 +8505,9 @@ function Spinner({ className, variant: type = 'default', size = 'default', state
8501
8505
  }
8502
8506
  }
8503
8507
  const fullscreenDialogContentClassName = 'inset-0 h-dvh min-w-full max-w-none translate-x-0 translate-y-0 rounded-none border-none bg-transparent p-0 shadow-none sm:p-0 sm:max-w-none';
8508
+ function isRoomLoadError(error) {
8509
+ return 'room-load-failed' === error || 'room-missing-surface' === error;
8510
+ }
8504
8511
  const RoomViewerMetadataContext = createContext(null);
8505
8512
  const RoomViewerSurfaceContext = createContext(null);
8506
8513
  const RoomViewerRoomsContext = createContext(null);
@@ -9797,15 +9804,28 @@ function getErrorMessageKey(variant) {
9797
9804
  if ('viewer-load-failed' === variant || 'artwork-load-failed' === variant || 'room-load-failed' === variant) return `loadError.${variant}`;
9798
9805
  return `accessError.${variant}`;
9799
9806
  }
9800
- function RoomViewerErrorState({ variant, showDialogCloseButton = false }) {
9807
+ function RoomViewerErrorState({ variant, missingSurfaceMessage, showDialogCloseButton = false }) {
9801
9808
  const { t } = useTranslation();
9809
+ const isMissingSurface = 'room-missing-surface' === variant;
9802
9810
  return /*#__PURE__*/ jsxs("div", {
9803
9811
  className: "flex size-full flex-col items-center justify-center gap-4 bg-radial from-background-containers to-background-base-2 p-4 text-center",
9804
9812
  children: [
9805
9813
  /*#__PURE__*/ jsx(Alert, {
9806
9814
  className: "size-8 text-icons-light"
9807
9815
  }),
9808
- /*#__PURE__*/ jsx("h2", {
9816
+ isMissingSurface ? /*#__PURE__*/ jsxs("div", {
9817
+ className: "grid gap-1",
9818
+ children: [
9819
+ /*#__PURE__*/ jsx("h2", {
9820
+ className: "typo-base-16 font-medium text-text-dark",
9821
+ children: t(`missingSurface.${missingSurfaceMessage}.title`)
9822
+ }),
9823
+ /*#__PURE__*/ jsx("p", {
9824
+ className: "typo-base-14 text-text-base",
9825
+ children: t(`missingSurface.${missingSurfaceMessage}.body`)
9826
+ })
9827
+ ]
9828
+ }) : /*#__PURE__*/ jsx("h2", {
9809
9829
  className: "typo-base-16 font-medium text-text-dark",
9810
9830
  children: t(getErrorMessageKey(variant))
9811
9831
  }),
@@ -11370,15 +11390,21 @@ function formatScenePlaneKinds(planes) {
11370
11390
  const distinctKinds = kinds.filter((kind, index)=>kinds.indexOf(kind) === index);
11371
11391
  return distinctKinds.length > 0 ? distinctKinds.join(', ') : 'none';
11372
11392
  }
11373
- function warnUnrenderableRoomScene({ failure, planes, resourceType }) {
11374
- warnOnce(`unrenderable-room-scene:${resourceType}:${failure}`, `Cannot place a "${resourceType}" Resource in this Room: ${failure}. Scene Plane Kinds: ${formatScenePlaneKinds(planes)}.`);
11375
- }
11376
11393
  function isRoomScenePlaneAllowedForResource(plane, surfaces) {
11377
11394
  return surfaces.includes(plane.kind);
11378
11395
  }
11379
11396
  function getAllowedRoomScenePlanes(scene, surfaces) {
11380
11397
  return scene.planes.filter((plane)=>isRoomScenePlaneAllowedForResource(plane, surfaces));
11381
11398
  }
11399
+ function hasMissingSurface(scene, surfaces) {
11400
+ return !scene.planes.some((plane)=>isRoomScenePlaneAllowedForResource(plane, surfaces));
11401
+ }
11402
+ function warnMissingSurface({ planes, source, surfaces }) {
11403
+ console.warn(`Missing Surface in ${source}: the Resource needs ${surfaces.join(' or ')}, the Scene has ${formatScenePlaneKinds(planes)}.`);
11404
+ }
11405
+ function warnUnrenderableRoomScene({ failure, planes, resourceType }) {
11406
+ warnOnce(`unrenderable-room-scene:${resourceType}:${failure}`, `Cannot place a "${resourceType}" Resource in this Room: ${failure}. Scene Plane Kinds: ${formatScenePlaneKinds(planes)}.`);
11407
+ }
11382
11408
  function createRoomScenePlaneGeometries(scene) {
11383
11409
  return new Map(scene.planes.map((plane)=>[
11384
11410
  plane.id,
@@ -13051,6 +13077,15 @@ const Room = /*#__PURE__*/ memo(()=>{
13051
13077
  ]);
13052
13078
  useEffect(()=>{
13053
13079
  if (!placementFailure) return;
13080
+ if ('no-allowed-surface' === placementFailure) {
13081
+ warnMissingSurface({
13082
+ planes: scene.planes,
13083
+ source: 'room-scene',
13084
+ surfaces
13085
+ });
13086
+ setLoadError('room-missing-surface');
13087
+ return;
13088
+ }
13054
13089
  warnUnrenderableRoomScene({
13055
13090
  failure: placementFailure,
13056
13091
  planes: scene.planes,
@@ -13061,6 +13096,7 @@ const Room = /*#__PURE__*/ memo(()=>{
13061
13096
  placementFailure,
13062
13097
  scene.planes,
13063
13098
  setLoadError,
13099
+ surfaces,
13064
13100
  type
13065
13101
  ]);
13066
13102
  return /*#__PURE__*/ jsxs(Fragment, {
@@ -14276,7 +14312,7 @@ function SceneGestureSlider({ gesture, min, max, 'aria-label': ariaLabel }) {
14276
14312
  });
14277
14313
  }
14278
14314
  function FramedSceneChrome({ showDialogCloseButton = false }) {
14279
- const { name } = useRoomViewerMetadata();
14315
+ const { name, type } = useRoomViewerMetadata();
14280
14316
  const { isViewerAccessPending, accessError, loadError, setLoadError, hasRooms } = useRoomViewerResource();
14281
14317
  const { setContainerRef, sceneLoad, isRoomScenePending } = useRoomViewerSceneState();
14282
14318
  const { dialogPortalContainer, viewerSurface, viewerDialogOpen, onViewerDialogOpenChange } = useRoomViewerSurface();
@@ -14295,6 +14331,7 @@ function FramedSceneChrome({ showDialogCloseButton = false }) {
14295
14331
  className: "relative size-full overflow-hidden bg-radial from-background-containers to-background-base-2 text-foreground",
14296
14332
  children: /*#__PURE__*/ jsx(RoomViewerErrorState, {
14297
14333
  variant: activeError,
14334
+ missingSurfaceMessage: resolveResourceProfile(type).missingSurfaceMessage,
14298
14335
  showDialogCloseButton: showDialogCloseButton
14299
14336
  })
14300
14337
  }) : /*#__PURE__*/ jsxs("div", {
@@ -14404,15 +14441,20 @@ function useOpeningIntroduction(open, enabled, sceneKey) {
14404
14441
  finish
14405
14442
  };
14406
14443
  }
14444
+ function isMissingSurfaceVariant(variant) {
14445
+ return 'custom-interior-missing-surface' === variant || 'room-missing-surface' === variant;
14446
+ }
14407
14447
  function FloorErrorDialog_getErrorMessageKey(variant) {
14408
14448
  if ('custom-interior-processing' === variant) return 'floor.error.processingBody';
14409
14449
  if ('viewer-load-failed' === variant) return 'floor.error.loadBody';
14410
14450
  if ('artwork-load-failed' === variant || 'room-load-failed' === variant) return `loadError.${variant}`;
14411
14451
  return `accessError.${variant}`;
14412
14452
  }
14413
- function FloorErrorDialog({ variant, open, portalContainer, showDialogCloseButton = false, onOpenChange, onTryAgain, onCancel }) {
14453
+ function FloorErrorDialog({ variant, missingSurfaceMessage, open, portalContainer, showDialogCloseButton = false, onOpenChange, onTryAgain, onCancel }) {
14414
14454
  const { t } = useTranslation();
14415
- const message = variant ? t(FloorErrorDialog_getErrorMessageKey(variant)) : '';
14455
+ const isMissingSurface = isMissingSurfaceVariant(variant);
14456
+ const title = isMissingSurface ? t(`missingSurface.${missingSurfaceMessage}.title`) : t('floor.error.title');
14457
+ const message = isMissingSurface ? t(`missingSurface.${missingSurfaceMessage}.body`) : variant ? t(FloorErrorDialog_getErrorMessageKey(variant)) : '';
14416
14458
  return /*#__PURE__*/ jsx(Dialog, {
14417
14459
  open: open,
14418
14460
  onOpenChange: onOpenChange,
@@ -14428,7 +14470,7 @@ function FloorErrorDialog({ variant, open, portalContainer, showDialogCloseButto
14428
14470
  className: "grid gap-1",
14429
14471
  children: [
14430
14472
  /*#__PURE__*/ jsx(DialogTitle, {
14431
- children: t('floor.error.title')
14473
+ children: title
14432
14474
  }),
14433
14475
  /*#__PURE__*/ jsx(DialogDescription, {
14434
14476
  className: "typo-base-14 font-medium text-text-base",
@@ -14439,15 +14481,24 @@ function FloorErrorDialog({ variant, open, portalContainer, showDialogCloseButto
14439
14481
  /*#__PURE__*/ jsxs("div", {
14440
14482
  className: "grid gap-2",
14441
14483
  children: [
14442
- onTryAgain && /*#__PURE__*/ jsxs(Button, {
14484
+ onTryAgain && /*#__PURE__*/ jsx(Button, {
14443
14485
  variant: "contrast",
14444
14486
  onClick: onTryAgain,
14445
- children: [
14446
- /*#__PURE__*/ jsx(EditorRotate, {
14447
- "aria-hidden": "true"
14448
- }),
14449
- t('floor.error.tryAgain')
14450
- ]
14487
+ children: isMissingSurface ? /*#__PURE__*/ jsxs(Fragment, {
14488
+ children: [
14489
+ /*#__PURE__*/ jsx(Camera, {
14490
+ "aria-hidden": "true"
14491
+ }),
14492
+ t('missingSurface.uploadAnother')
14493
+ ]
14494
+ }) : /*#__PURE__*/ jsxs(Fragment, {
14495
+ children: [
14496
+ /*#__PURE__*/ jsx(Rotate, {
14497
+ "aria-hidden": "true"
14498
+ }),
14499
+ t('floor.error.tryAgain')
14500
+ ]
14501
+ })
14451
14502
  }),
14452
14503
  onCancel && /*#__PURE__*/ jsx(Button, {
14453
14504
  variant: "outline",
@@ -15921,13 +15972,27 @@ function isCustomInteriorIntakeActive(abortSignal, isActive) {
15921
15972
  function isImageFile(file) {
15922
15973
  return file.type.startsWith('image/');
15923
15974
  }
15924
- async function processCustomInteriorIntake({ abortSignal, apiOptions, commitCustomInteriorSelection, downloadDebugMask, file, isActive, isDebugMaskExportEnabled, onDebugMaskError, onPersistenceError, onProcessingComplete, predictRoomScene, saveCustomInterior, trackRuntimeCustomInterior, waitForProcessingCompletion }) {
15975
+ class CustomInteriorMissingSurfaceError extends Error {
15976
+ constructor(){
15977
+ super('Room Photo has a Missing Surface.');
15978
+ this.name = 'CustomInteriorMissingSurfaceError';
15979
+ }
15980
+ }
15981
+ async function processCustomInteriorIntake({ abortSignal, apiOptions, commitCustomInteriorSelection, downloadDebugMask, file, isActive, isDebugMaskExportEnabled, onDebugMaskError, onPersistenceError, onProcessingComplete, predictRoomScene, saveCustomInterior, surfaces, trackRuntimeCustomInterior, waitForProcessingCompletion }) {
15925
15982
  const scene = await predictRoomScene(file, {
15926
15983
  ...apiOptions,
15927
15984
  signal: abortSignal
15928
15985
  });
15929
15986
  if (!isCustomInteriorIntakeActive(abortSignal, isActive)) return null;
15930
15987
  if (isDebugMaskExportEnabled()) downloadDebugMask(scene, file.name).catch(onDebugMaskError);
15988
+ if (hasMissingSurface(scene, surfaces)) {
15989
+ warnMissingSurface({
15990
+ planes: scene.planes,
15991
+ source: 'room-photo-upload',
15992
+ surfaces
15993
+ });
15994
+ throw new CustomInteriorMissingSurfaceError();
15995
+ }
15931
15996
  const customRoom = trackRuntimeCustomInterior(file, scene);
15932
15997
  if (!isCustomInteriorIntakeActive(abortSignal, isActive) || !customRoom) return null;
15933
15998
  saveCustomInterior(file, scene).catch(onPersistenceError);
@@ -15981,7 +16046,7 @@ function useRuntimeCustomInteriorRegistry() {
15981
16046
  replaceRuntimeCustomInteriors
15982
16047
  ]);
15983
16048
  }
15984
- function useCustomInteriorCatalog({ listCustomInteriors }) {
16049
+ function useCustomInteriorCatalog({ listCustomInteriors, surfaces }) {
15985
16050
  const { appendRuntimeCustomInterior, customRooms, replaceRuntimeCustomInteriors } = useRuntimeCustomInteriorRegistry();
15986
16051
  const isMountedRef = useRef(true);
15987
16052
  useEffect(()=>{
@@ -15993,10 +16058,11 @@ function useCustomInteriorCatalog({ listCustomInteriors }) {
15993
16058
  const refreshCustomInteriors = useCallback(async ()=>{
15994
16059
  const storedInteriors = await listCustomInteriors();
15995
16060
  if (!isMountedRef.current) return;
15996
- replaceRuntimeCustomInteriors(storedInteriors);
16061
+ replaceRuntimeCustomInteriors(storedInteriors.filter((interior)=>!hasMissingSurface(interior.scene, surfaces)));
15997
16062
  }, [
15998
16063
  listCustomInteriors,
15999
- replaceRuntimeCustomInteriors
16064
+ replaceRuntimeCustomInteriors,
16065
+ surfaces
16000
16066
  ]);
16001
16067
  useEffect(()=>{
16002
16068
  refreshCustomInteriors();
@@ -16086,7 +16152,7 @@ function useProcessingDialogErrorHandoff({ fallbackMs, handleProcessingDialogClo
16086
16152
  isProcessingDialogClosingForError
16087
16153
  ]);
16088
16154
  }
16089
- function useCustomInteriorIntakeFlow({ apiOptions, floorFlow, commitCustomInteriorSelection, downloadDebugMask, isDebugMaskExportEnabled, onAccessError, onDebugMaskError, onPersistenceError, onProcessingError, predictRoomScene, saveCustomInterior, setIsRoomScenePending, trackRuntimeCustomInterior, waitForProcessingCompletion }) {
16155
+ function useCustomInteriorIntakeFlow({ apiOptions, floorFlow, commitCustomInteriorSelection, downloadDebugMask, isDebugMaskExportEnabled, onAccessError, onDebugMaskError, onPersistenceError, onProcessingError, predictRoomScene, saveCustomInterior, setIsRoomScenePending, surfaces, trackRuntimeCustomInterior, waitForProcessingCompletion }) {
16090
16156
  const [isInvalidFile, setIsInvalidFile] = useState(false);
16091
16157
  const [isCustomInteriorProcessingComplete, setIsCustomInteriorProcessingComplete] = useState(false);
16092
16158
  const [uploadError, setUploadError] = useState(null);
@@ -16144,6 +16210,7 @@ function useCustomInteriorIntakeFlow({ apiOptions, floorFlow, commitCustomInteri
16144
16210
  },
16145
16211
  predictRoomScene,
16146
16212
  saveCustomInterior,
16213
+ surfaces,
16147
16214
  trackRuntimeCustomInterior,
16148
16215
  waitForProcessingCompletion
16149
16216
  });
@@ -16155,13 +16222,14 @@ function useCustomInteriorIntakeFlow({ apiOptions, floorFlow, commitCustomInteri
16155
16222
  onAccessError(nextError);
16156
16223
  return;
16157
16224
  }
16158
- onProcessingError(error);
16225
+ const nextUploadError = error instanceof CustomInteriorMissingSurfaceError ? 'custom-interior-missing-surface' : 'custom-interior-processing';
16226
+ if ('custom-interior-processing' === nextUploadError) onProcessingError(error);
16159
16227
  if (isProcessingDialogOpenRef.current) {
16160
- setPendingUploadError('custom-interior-processing');
16228
+ setPendingUploadError(nextUploadError);
16161
16229
  setIsProcessingDialogClosingForError(true);
16162
16230
  return;
16163
16231
  }
16164
- setUploadError('custom-interior-processing');
16232
+ setUploadError(nextUploadError);
16165
16233
  } finally{
16166
16234
  if (pendingAbortControllerRef.current === abortController) {
16167
16235
  pendingAbortControllerRef.current = null;
@@ -16182,6 +16250,7 @@ function useCustomInteriorIntakeFlow({ apiOptions, floorFlow, commitCustomInteri
16182
16250
  resetUploadErrorPresentation,
16183
16251
  saveCustomInterior,
16184
16252
  setIsRoomScenePending,
16253
+ surfaces,
16185
16254
  trackRuntimeCustomInterior,
16186
16255
  waitForProcessingCompletion
16187
16256
  ]);
@@ -16349,7 +16418,7 @@ function useRoomViewerFloorFlow(viewerSurface) {
16349
16418
  } : void 0);
16350
16419
  const { automaticRoomId, clearInteriorSelection } = floorFlow;
16351
16420
  useEffect(()=>{
16352
- if (automaticRoomId && room.id === automaticRoomId && 'room-load-failed' === loadError) {
16421
+ if (automaticRoomId && room.id === automaticRoomId && isRoomLoadError(loadError)) {
16353
16422
  clearInteriorSelection();
16354
16423
  setLoadError(null);
16355
16424
  }
@@ -16396,8 +16465,10 @@ function handleProcessingError(error) {
16396
16465
  }
16397
16466
  function useFloorViewerFlowController({ activeError, apiKey, baseURL, clearActiveError, closeMaterialSelection, glbUrl, handleAccessError, hasDialogPortalContainer, hasRooms, isRoomScenePending, isViewerAccessPending, onViewerDialogOpenChange, resourceType, sceneLoad, source, sourceRooms, viewerDialogOpen, viewerSurface, widgetSession }) {
16398
16467
  const floorFlow = useRoomViewerFloorFlow(viewerSurface);
16468
+ const surfaces = resolveResourceSurfaces(resourceType);
16399
16469
  const { appendRuntimeCustomInterior, customRooms } = useCustomInteriorCatalog({
16400
- listCustomInteriors: custom_interiors_listCustomInteriors
16470
+ listCustomInteriors: custom_interiors_listCustomInteriors,
16471
+ surfaces
16401
16472
  });
16402
16473
  const sourceRoomIds = external_react_useMemo(()=>new Set(sourceRooms.map((room)=>room.id)), [
16403
16474
  sourceRooms
@@ -16439,6 +16510,7 @@ function useFloorViewerFlowController({ activeError, apiKey, baseURL, clearActiv
16439
16510
  onProcessingError: handleProcessingError,
16440
16511
  predictRoomScene: room_scene_api_predictRoomScene,
16441
16512
  saveCustomInterior: custom_interiors_saveCustomInterior,
16513
+ surfaces,
16442
16514
  trackRuntimeCustomInterior: appendRuntimeCustomInterior,
16443
16515
  waitForProcessingCompletion: waitForCustomInteriorProcessingCompletion
16444
16516
  });
@@ -16476,6 +16548,13 @@ function useFloorViewerFlowController({ activeError, apiKey, baseURL, clearActiv
16476
16548
  closeMaterialSelection,
16477
16549
  recoverFromActiveError
16478
16550
  ]);
16551
+ const handleMissingSurfaceUploadAnother = useCallback(()=>{
16552
+ clearActiveError();
16553
+ handleOpenInteriorSelection();
16554
+ }, [
16555
+ clearActiveError,
16556
+ handleOpenInteriorSelection
16557
+ ]);
16479
16558
  const handleInteriorSelectionOpenChange = useCallback((open)=>{
16480
16559
  if (open) return;
16481
16560
  if (hasUsableSceneSelection) return void handleDismissInteriorSelection();
@@ -16530,7 +16609,7 @@ function useFloorViewerFlowController({ activeError, apiKey, baseURL, clearActiv
16530
16609
  ...presentation.activeErrorDialog,
16531
16610
  onCancel: canRecoverFromActiveError ? handleRecoverableError : void 0,
16532
16611
  onOpenChange: handleActiveErrorOpenChange,
16533
- onTryAgain: canRecoverFromActiveError ? handleRecoverableError : void 0,
16612
+ onTryAgain: 'room-missing-surface' === activeError ? handleMissingSurfaceUploadAnother : canRecoverFromActiveError ? handleRecoverableError : void 0,
16534
16613
  variant: activeError ?? presentedActiveErrorRef.current
16535
16614
  },
16536
16615
  customRooms,
@@ -16566,6 +16645,7 @@ function resolveFloorCompanyName(selectedObject, fallback) {
16566
16645
  function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
16567
16646
  const { t } = useTranslation();
16568
16647
  const { name, type } = useRoomViewerMetadata();
16648
+ const { missingSurfaceMessage } = resolveResourceProfile(type);
16569
16649
  const { accessError, glbUrl, apiKey, baseURL, hasRooms, source, widgetSession, isViewerAccessPending, loadError, selectedObject, tinuuid } = useRoomViewerResource();
16570
16650
  const { clearActiveError, handleAccessError } = useRoomViewerErrorCommands();
16571
16651
  const { room, sourceRooms } = useRoomViewerRooms();
@@ -16937,6 +17017,7 @@ function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
16937
17017
  const floorErrorDialogs = /*#__PURE__*/ jsxs(Fragment, {
16938
17018
  children: [
16939
17019
  /*#__PURE__*/ jsx(FloorErrorDialog, {
17020
+ missingSurfaceMessage: missingSurfaceMessage,
16940
17021
  variant: floorController.activeErrorDialog.variant,
16941
17022
  open: floorController.activeErrorDialog.open,
16942
17023
  portalContainer: activeDialogPortalContainer,
@@ -16946,6 +17027,7 @@ function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
16946
17027
  onCancel: floorController.activeErrorDialog.onCancel
16947
17028
  }),
16948
17029
  /*#__PURE__*/ jsx(FloorErrorDialog, {
17030
+ missingSurfaceMessage: missingSurfaceMessage,
16949
17031
  variant: floorController.uploadErrorDialog.variant,
16950
17032
  open: floorController.uploadErrorDialog.open,
16951
17033
  portalContainer: activeDialogPortalContainer,
@@ -17261,7 +17343,7 @@ function RoomViewerProvider({ children, src, tinuuid: initialTinuuid, roomId: co
17261
17343
  if (initialRoomId) {
17262
17344
  setRoomId(initialRoomId);
17263
17345
  setSceneLoad((current)=>patchSceneLoadState(current, ROOM_CHANGE_SCENE_LOAD_RESET));
17264
- setLoadError((current)=>'room-load-failed' === current ? null : current);
17346
+ setLoadError((current)=>isRoomLoadError(current) ? null : current);
17265
17347
  }
17266
17348
  }
17267
17349
  const selectedRoom = rooms.find((currentRoom)=>currentRoom.id === roomId);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neurodyn/react-room-viewer",
3
3
  "type": "module",
4
- "version": "0.0.31",
4
+ "version": "0.0.33",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },