@preference-sl/pref-viewer 2.10.0-beta.22 → 2.10.0-beta.24

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +140 -64
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preference-sl/pref-viewer",
3
- "version": "2.10.0-beta.22",
3
+ "version": "2.10.0-beta.24",
4
4
  "description": "Web Component to preview GLTF models with Babylon.js",
5
5
  "author": "Alex Moreno Palacio <amoreno@preference.es>",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -61,7 +61,7 @@ class PrefViewer extends HTMLElement {
61
61
  visible: false,
62
62
  size: null,
63
63
  timeStamp: null,
64
- changed: false,
64
+ changed: { pending: false, success: false },
65
65
  },
66
66
  environment: {
67
67
  name: "environment",
@@ -71,7 +71,7 @@ class PrefViewer extends HTMLElement {
71
71
  visible: false,
72
72
  size: null,
73
73
  timeStamp: null,
74
- changed: false,
74
+ changed: { pending: false, success: false },
75
75
  },
76
76
  materials: {
77
77
  name: "materials",
@@ -81,35 +81,35 @@ class PrefViewer extends HTMLElement {
81
81
  visible: false,
82
82
  size: null,
83
83
  timeStamp: null,
84
- changed: false,
84
+ changed: { pending: false, success: false },
85
85
  },
86
86
  },
87
87
  options: {
88
88
  camera: {
89
89
  value: null,
90
90
  locked: true,
91
- changed: false,
91
+ changed: { pending: false, success: false },
92
92
  },
93
93
  materials: {
94
94
  innerWall: {
95
95
  value: null,
96
96
  prefix: "innerWall",
97
- changed: false,
97
+ changed: { pending: false, success: false },
98
98
  },
99
99
  outerWall: {
100
100
  value: null,
101
101
  prefix: "outerWall",
102
- changed: false,
102
+ changed: { pending: false, success: false },
103
103
  },
104
104
  innerFloor: {
105
105
  value: null,
106
106
  prefix: "innerFloor",
107
- changed: false,
107
+ changed: { pending: false, success: false },
108
108
  },
109
109
  outerFloor: {
110
110
  value: null,
111
111
  prefix: "outerFloor",
112
- changed: false,
112
+ changed: { pending: false, success: false },
113
113
  },
114
114
  },
115
115
  },
@@ -261,24 +261,24 @@ class PrefViewer extends HTMLElement {
261
261
  this.loading = false;
262
262
 
263
263
  const toLoadDetail = {
264
- container_model: !!this.#data.containers.model.changed,
265
- container_environment: !!this.#data.containers.environment.changed,
266
- container_materials: !!this.#data.containers.materials.changed,
267
- options_camera: !!this.#data.options.camera.changed,
268
- options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed,
269
- options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
270
- options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed,
271
- options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed,
264
+ container_model: !!this.#data.containers.model.changed.pending,
265
+ container_environment: !!this.#data.containers.environment.changed.pending,
266
+ container_materials: !!this.#data.containers.materials.changed.pending,
267
+ options_camera: !!this.#data.options.camera.changed.pending,
268
+ options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed.pending,
269
+ options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed.pending,
270
+ options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.pending,
271
+ options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.pending,
272
272
  };
273
273
  const loadedDetail = {
274
- container_model: !!this.#data.containers.model.changed?.success,
275
- container_environment: !!this.#data.containers.environment.changed?.success,
276
- container_materials: !!this.#data.containers.materials.changed?.success,
277
- options_camera: !!this.#data.options.camera.changed?.success,
278
- options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed?.success,
279
- options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed?.success,
280
- options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed?.success,
281
- options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed?.success,
274
+ container_model: !!this.#data.containers.model.changed.success,
275
+ container_environment: !!this.#data.containers.environment.changed.success,
276
+ container_materials: !!this.#data.containers.materials.changed.success,
277
+ options_camera: !!this.#data.options.camera.changed.success,
278
+ options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed.success,
279
+ options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed.success,
280
+ options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.success,
281
+ options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.success,
282
282
  };
283
283
 
284
284
  const detail = {
@@ -315,16 +315,16 @@ class PrefViewer extends HTMLElement {
315
315
  #setStatusOptionsLoaded() {
316
316
  console.log("PrefViewer: #setStatusOptionsLoaded()");
317
317
  const toLoadDetail = {
318
- innerWallMaterial: !!this.#data.options.materials.innerWall.changed,
319
- outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
320
- innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed,
321
- outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed,
318
+ innerWallMaterial: !!this.#data.options.materials.innerWall.changed.pending,
319
+ outerWallMaterial: !!this.#data.options.materials.outerWall.changed.pending,
320
+ innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.pending,
321
+ outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.pending,
322
322
  };
323
323
  const loadedDetail = {
324
- innerWallMaterial: !!this.#data.options.materials.innerWall.changed?.success,
325
- outerWallMaterial: !!this.#data.options.materials.outerWall.changed?.success,
326
- innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed?.success,
327
- outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed?.success,
324
+ innerWallMaterial: !!this.#data.options.materials.innerWall.changed.success,
325
+ outerWallMaterial: !!this.#data.options.materials.outerWall.changed.success,
326
+ innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.success,
327
+ outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.success,
328
328
  };
329
329
 
330
330
  const detail = {
@@ -350,7 +350,13 @@ class PrefViewer extends HTMLElement {
350
350
  }
351
351
  const changed = options.camera !== this.#data.options.camera.value;
352
352
  console.log("PrefViewer: #checkCameraChanged()", { incoming: options.camera, previous: this.#data.options.camera.value, changed });
353
- this.#data.options.camera.changed = changed ? { oldValue: this.#data.options.camera.value, oldLocked: this.#data.options.camera.locked, success: false } : false;
353
+ this.#data.options.camera.changed = {
354
+ ...this.#data.options.camera.changed,
355
+ pending: changed,
356
+ success: false,
357
+ oldValue: changed ? this.#data.options.camera.value : this.#data.options.camera.changed.oldValue,
358
+ oldLocked: changed ? this.#data.options.camera.locked : this.#data.options.camera.changed.oldLocked,
359
+ };
354
360
  if (changed) this.#data.options.camera.value = options.camera;
355
361
 
356
362
  return changed;
@@ -363,11 +369,19 @@ class PrefViewer extends HTMLElement {
363
369
  let someChanged = false;
364
370
  Object.keys(this.#data.options.materials).forEach((material) => {
365
371
  const key = `${material}Material`;
366
- const materialChanged = options[key] && options[key] !== this.#data.options.materials[material].value ? true : false;
367
- console.log("PrefViewer: #checkMaterialsChanged()", { key, incoming: options[key], previous: this.#data.options.materials[material].value, materialChanged });
368
- this.#data.options.materials[material].changed = materialChanged ? { oldValue: this.#data.options.materials[material].value, success: false } : false;
369
- this.#data.options.materials[material].value = materialChanged ? options[key] : this.#data.options.materials[material].value;
370
- someChanged = someChanged || this.#data.options.materials[material].changed;
372
+ const materialState = this.#data.options.materials[material];
373
+ const prev = materialState.value;
374
+ const incoming = options[key];
375
+ const materialChanged = !!incoming && incoming !== prev;
376
+ console.log("PrefViewer: #checkMaterialsChanged()", { key, incoming, previous: prev, materialChanged });
377
+ materialState.changed = {
378
+ ...materialState.changed,
379
+ pending: materialChanged,
380
+ success: false,
381
+ oldValue: materialChanged ? prev : materialState.changed.oldValue,
382
+ };
383
+ materialState.value = materialChanged ? incoming : prev;
384
+ someChanged = someChanged || materialChanged;
371
385
  });
372
386
  return someChanged;
373
387
  }
@@ -377,13 +391,18 @@ class PrefViewer extends HTMLElement {
377
391
  container.timeStamp = container.changed.timeStamp;
378
392
  container.size = container.changed.size;
379
393
  container.changed.success = true;
394
+ container.changed.pending = false;
380
395
  }
381
396
 
382
397
  #resetChangedFlags() {
383
398
  console.log("PrefViewer: #resetChangedFlags()");
384
- Object.values(this.#data.containers).forEach((container) => (container.changed = false));
385
- Object.values(this.#data.options.materials).forEach((material) => (material.changed = false));
386
- this.#data.options.camera.changed = false;
399
+ const reset = (node) => {
400
+ node.changed.success = false;
401
+ node.changed.pending = false;
402
+ };
403
+ Object.values(this.#data.containers).forEach(reset);
404
+ Object.values(this.#data.options.materials).forEach(reset);
405
+ reset(this.#data.options.camera);
387
406
  }
388
407
 
389
408
  // Babylon.js
@@ -638,17 +657,23 @@ class PrefViewer extends HTMLElement {
638
657
  return false;
639
658
  }
640
659
 
641
- const material = this.#data.containers.materials.assetContainer?.materials.find((mat) => mat.name === optionMaterial.value) || null;
660
+ const material = this.#data.containers.materials.assetContainer?.materials
661
+ .find((mat) => mat.name === optionMaterial.value) || null;
662
+
642
663
  if (!material) {
643
664
  console.warn("PrefViewer: material not found", optionMaterial.value);
644
665
  return false;
645
666
  }
646
667
 
668
+ const hadExplicitChange = !!optionMaterial.changed.pending;
669
+
647
670
  const containers = [];
648
- if (this.#data.containers.model.assetContainer && (this.#data.containers.model.changed || this.#data.containers.materials.changed || optionMaterial.changed)) {
671
+ if (this.#data.containers.model.assetContainer &&
672
+ (this.#data.containers.model.changed.pending || this.#data.containers.materials.changed.pending || optionMaterial.changed.pending)) {
649
673
  containers.push(this.#data.containers.model.assetContainer);
650
674
  }
651
- if (this.#data.containers.environment.assetContainer && (this.#data.containers.environment.changed || this.#data.containers.materials.changed || optionMaterial.changed)) {
675
+ if (this.#data.containers.environment.assetContainer &&
676
+ (this.#data.containers.environment.changed.pending || this.#data.containers.materials.changed.pending || optionMaterial.changed.pending)) {
652
677
  containers.push(this.#data.containers.environment.assetContainer);
653
678
  }
654
679
  if (containers.length === 0) {
@@ -666,11 +691,15 @@ class PrefViewer extends HTMLElement {
666
691
  })
667
692
  );
668
693
 
669
- console.log("PrefViewer: material assignment result", { prefix: optionMaterial.prefix, material: optionMaterial.value, someSetted });
694
+ console.log("PrefViewer: material assignment result", {
695
+ prefix: optionMaterial.prefix, material: optionMaterial.value, someSetted
696
+ });
670
697
 
671
698
  if (someSetted) {
672
699
  optionMaterial.changed.success = true;
673
- } else {
700
+ optionMaterial.changed.pending = false;
701
+ } else if (hadExplicitChange) {
702
+ // Solo revertimos si el usuario pidió el cambio y falló
674
703
  optionMaterial.value = optionMaterial.changed.oldValue;
675
704
  }
676
705
 
@@ -695,29 +724,58 @@ class PrefViewer extends HTMLElement {
695
724
  modelChanged: this.#data.containers.model.changed,
696
725
  envChanged: this.#data.containers.environment.changed
697
726
  });
698
- if (!this.#data.options.camera.value || (!this.#data.options.camera.changed && !this.#data.containers.model.changed && !this.#data.containers.environment.changed)) {
727
+
728
+ const camState = this.#data.options.camera;
729
+
730
+ if (!camState.value && !camState.changed.pending && !this.#data.containers.model.changed.pending && !this.#data.containers.environment.changed.pending) {
699
731
  return false;
700
732
  }
701
733
 
702
- let camera = this.#data.containers.model.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.value) || this.#data.containers.environment.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.value) || null;
734
+ const hadExplicitChange = !!camState.changed.pending;
735
+
736
+ let camera =
737
+ this.#data.containers.model.assetContainer?.cameras.find(c => c.name === camState.value) ||
738
+ this.#data.containers.environment.assetContainer?.cameras.find(c => c.name === camState.value) ||
739
+ null;
740
+
703
741
  if (!camera) {
704
- if (this.#data.options.camera.changed?.oldValue && this.#data.options.camera.changed?.oldValue !== this.#data.options.camera.value) {
705
- camera = this.#data.containers.model.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.changed.oldValue) || this.#data.containers.environment.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.changed.oldValue) || null;
706
- }
707
- if (camera) {
708
- camera.metadata = { locked: this.#data.options.camera.changed.oldLocked };
709
- this.#data.options.camera.value = this.#data.options.camera.changed.oldValue;
710
- this.#data.options.camera.locked = this.#data.options.camera.changed.oldLocked;
742
+ // Si falló la cámara solicitada y hubo cambio explícito, intentamos volver a la anterior
743
+ if (hadExplicitChange && camState.changed.oldValue && camState.changed.oldValue !== camState.value) {
744
+ camera =
745
+ this.#data.containers.model.assetContainer?.cameras.find(c => c.name === camState.changed.oldValue) ||
746
+ this.#data.containers.environment.assetContainer?.cameras.find(c => c.name === camState.changed.oldValue) ||
747
+ null;
748
+
749
+ if (camera) {
750
+ camera.metadata = { locked: camState.changed.oldLocked };
751
+ camState.value = camState.changed.oldValue;
752
+ camState.locked = camState.changed.oldLocked;
753
+ camState.changed.success = false;
754
+ camState.changed.pending = false;
755
+ } else {
756
+ // Fallback a la cámara por defecto del componente
757
+ camera = this.#camera;
758
+ camState.value = null;
759
+ camState.locked = this.#camera.metadata.locked;
760
+ camState.changed.success = false;
761
+ camState.changed.pending = false;
762
+ }
711
763
  } else {
764
+ // No hubo cambio explícito: usa fallback sin tocar changed
712
765
  camera = this.#camera;
713
- this.#data.options.camera.value = null;
714
- this.#data.options.camera.locked = this.#camera.metadata.locked;
766
+ camState.value = null;
767
+ camState.locked = this.#camera.metadata.locked;
715
768
  }
716
- this.#data.options.camera.changed.success = false;
717
769
  } else {
718
- camera.metadata = { locked: this.#data.options.camera.locked };
770
+ camera.metadata = { locked: camState.locked };
771
+ // Marca success si hubo cambio explícito
772
+ if (hadExplicitChange) {
773
+ camState.changed.success = true;
774
+ camState.changed.pending = false;
775
+ }
719
776
  }
720
- if (!this.#data.options.camera.locked && this.#data.options.camera.value !== null) {
777
+
778
+ if (!camState.locked && camState.value !== null) {
721
779
  camera.attachControl(this.#canvas, true);
722
780
  }
723
781
  this.#scene.activeCamera = camera;
@@ -796,7 +854,13 @@ class PrefViewer extends HTMLElement {
796
854
  console.log("PrefViewer: DB entry unchanged, skipping", container.name);
797
855
  return false;
798
856
  } else {
799
- container.changed = { timeStamp: object.timeStamp, size: object.size, success: false };
857
+ container.changed = {
858
+ ...container.changed,
859
+ pending: true,
860
+ success: false,
861
+ timeStamp: object.timeStamp,
862
+ size: object.size,
863
+ };
800
864
  console.log("PrefViewer: DB entry changed", container.changed);
801
865
  }
802
866
  }
@@ -813,12 +877,18 @@ class PrefViewer extends HTMLElement {
813
877
  file = new File([blob], `${container.name}${extension}`, {
814
878
  type: blob.type,
815
879
  });
816
- if (!container.changed) {
880
+ if (!container.changed.pending) {
817
881
  if (container.timeStamp === null && container.size === size) {
818
882
  console.log("PrefViewer: same base64 size and null timestamp, skipping", container.name);
819
883
  return false;
820
884
  } else {
821
- container.changed = { timeStamp: null, size: size, success: false };
885
+ container.changed = {
886
+ ...container.changed,
887
+ pending: true,
888
+ success: false,
889
+ timeStamp: null,
890
+ size: size,
891
+ };
822
892
  }
823
893
  }
824
894
  console.log("PrefViewer: prepared File from base64", { name: file.name, size: file.size, type: file.type });
@@ -830,7 +900,13 @@ class PrefViewer extends HTMLElement {
830
900
  console.log("PrefViewer: remote file unchanged, skipping", container.name);
831
901
  return false;
832
902
  } else {
833
- container.changed = { timeStamp: fileTimeStamp, size: fileSize, success: false };
903
+ container.changed = {
904
+ ...container.changed,
905
+ pending: true,
906
+ success: false,
907
+ timeStamp: fileTimeStamp,
908
+ size: fileSize,
909
+ };
834
910
  console.log("PrefViewer: remote file changed", container.changed);
835
911
  }
836
912
  }