@thefittingroom/shop-ui 4.3.1 → 4.3.3

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.js CHANGED
@@ -20605,12 +20605,22 @@ class FittingRoomAPI {
20605
20605
  }
20606
20606
  console.debug("checking user for vto frames", colorwaySizeAssetSKU);
20607
20607
  const firestoreUser = data;
20608
- const frames2 = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20609
- if (!frames2?.length) {
20608
+ const colorwaySizeAssetEntry = firestoreUser.vto?.[this.BrandID]?.[colorwaySizeAssetSKU];
20609
+ if (!colorwaySizeAssetEntry) {
20610
+ console.debug("no vto entry for SKU, continue watching:", colorwaySizeAssetSKU);
20611
+ return false;
20612
+ }
20613
+ if (colorwaySizeAssetEntry.error) {
20614
+ console.error("VTO error found for SKU:", colorwaySizeAssetSKU, colorwaySizeAssetEntry.error);
20615
+ throw NoFramesFoundError;
20616
+ }
20617
+ console.debug("cololrwaySizeAssetEntry", colorwaySizeAssetEntry);
20618
+ const frames = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20619
+ if (!frames?.length) {
20610
20620
  throw NoFramesFoundError;
20611
20621
  }
20612
- console.debug("testing first frame for SKU:", colorwaySizeAssetSKU, frames2[0]);
20613
- const tested = await testImage(frames2[0]);
20622
+ console.debug("testing first frame for SKU:", colorwaySizeAssetSKU, frames[0]);
20623
+ const tested = await testImage(frames[0]);
20614
20624
  if (!tested) {
20615
20625
  console.error("image test failed for SKU:", colorwaySizeAssetSKU);
20616
20626
  throw NoFramesFoundError;
@@ -20641,12 +20651,12 @@ class FittingRoomAPI {
20641
20651
  console.error(`Error watching for try-on frames for SKU: ${colorwaySizeAssetSKU}`, error);
20642
20652
  throw error;
20643
20653
  }
20644
- const frames2 = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20645
- if (!frames2) {
20654
+ const frames = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20655
+ if (!frames) {
20646
20656
  console.error(`Frames not found on final user object for SKU: ${colorwaySizeAssetSKU}`, firestoreUser);
20647
20657
  throw NoFramesFoundError;
20648
20658
  }
20649
- return frames2;
20659
+ return frames;
20650
20660
  }
20651
20661
  async GetCachedOrRequestUserColorwaySizeAssetFrames(firestoreUserController, colorwaySizeAssetSKU, skipCache) {
20652
20662
  console.debug("GetCachedOrRequestUserColorwaySizeAssetFrames", colorwaySizeAssetSKU, "skipCache:", skipCache);
@@ -20683,7 +20693,6 @@ class FittingRoomAPI {
20683
20693
  framesPromise = this.watchForTryOnFrames(firestoreUserController, colorwaySizeAssetSKU, true);
20684
20694
  }
20685
20695
  this.vtoFramesPromiseCache.set(colorwaySizeAssetSKU, framesPromise);
20686
- console.debug("retrieved frames", frames);
20687
20696
  return await framesPromise;
20688
20697
  }
20689
20698
  }
@@ -21338,10 +21347,10 @@ class TFRModal {
21338
21347
  }
21339
21348
  toPasswordReset() {
21340
21349
  }
21341
- onTryOn(frames2) {
21350
+ onTryOn(frames) {
21342
21351
  this.manager.open(
21343
21352
  TryOnModal({
21344
- frames: frames2,
21353
+ frames,
21345
21354
  onClose: () => this.close(),
21346
21355
  onNavBack: () => this.navBack()
21347
21356
  })
@@ -21479,6 +21488,17 @@ class SizeRecComponent {
21479
21488
  this.tfrTryOnButton.classList.remove("loading");
21480
21489
  }
21481
21490
  }
21491
+ ShowSizeRecommendationError(message) {
21492
+ console.debug("ShowSizeRecommendationError", message);
21493
+ this.tfrSizeRecommendationError.innerHTML = message;
21494
+ this.tfrSizeRecommendationError.classList.remove("hide");
21495
+ this.tfrSizeRecommendationsContainer.classList.add("hide");
21496
+ }
21497
+ HideSizeRecommendationError() {
21498
+ console.debug("HideSizeRecommendationError");
21499
+ this.tfrSizeRecommendationError.classList.add("hide");
21500
+ this.tfrSizeRecommendationsContainer.classList.remove("hide");
21501
+ }
21482
21502
  SetStyleMeasurementLocations(garmentMeasurementLocations) {
21483
21503
  if (!garmentMeasurementLocations || !garmentMeasurementLocations.length) {
21484
21504
  this.tfrSizeRecTitle.classList.add("hide");
@@ -21502,6 +21522,9 @@ class SizeRecComponent {
21502
21522
  showTryOnButton() {
21503
21523
  this.tfrTryOnButton.classList.remove("hide");
21504
21524
  }
21525
+ hideTryOnButton() {
21526
+ this.tfrTryOnButton.classList.add("hide");
21527
+ }
21505
21528
  disableTryOnButton(message) {
21506
21529
  this.tfrTryOnButton.disabled = true;
21507
21530
  this.tfrTryOnButton.title = message;
@@ -21515,6 +21538,7 @@ class SizeRecComponent {
21515
21538
  init(sizeRecMainDiv) {
21516
21539
  if (!sizeRecMainDiv) throw new Error("Size rec main div not found");
21517
21540
  this.sizeRecMainDiv = sizeRecMainDiv;
21541
+ this.sizeRecMainDiv.classList.add("hide");
21518
21542
  this.render(sizeRecMainDiv);
21519
21543
  this.setElements(sizeRecMainDiv);
21520
21544
  this.bindEvents();
@@ -21610,7 +21634,8 @@ class SizeRecComponent {
21610
21634
  }
21611
21635
  renderSizeRec(sizeMeasurementLocationFits) {
21612
21636
  const selectedSizeIndex = sizeMeasurementLocationFits.findIndex((size) => size.isRecommended);
21613
- const selectedSizeLabel = sizeMeasurementLocationFits[selectedSizeIndex].label;
21637
+ const selectedSize = sizeMeasurementLocationFits[selectedSizeIndex];
21638
+ const selectedSizeLabel = selectedSize.label || selectedSize.size_value?.name || selectedSize.id;
21614
21639
  this.tfrSizeRecSize.innerHTML = ` ${selectedSizeLabel}`;
21615
21640
  this.availableSizes = sizeMeasurementLocationFits;
21616
21641
  this.redraw = (index) => this.renderSizeRecTable(sizeMeasurementLocationFits, index);
@@ -21623,7 +21648,7 @@ class SizeRecComponent {
21623
21648
  }
21624
21649
  renderSizeRecSelect(sizeMeasurementLocationFits, index) {
21625
21650
  const html = sizeMeasurementLocationFits.map(
21626
- (size, i) => `<div class="tfr-size-rec-select-button ${i === index ? "active" : ""}" data-index="${i}">${size.label}</div>`
21651
+ (size, i) => `<div class="tfr-size-rec-select-button ${i === index ? "active" : ""}" data-index="${i}">${size.label || size.size_value?.name || size.id}</div>`
21627
21652
  ).join("");
21628
21653
  this.tfrSizeRecSelect.innerHTML = html;
21629
21654
  }
@@ -21700,7 +21725,7 @@ class SizeRecComponent {
21700
21725
  }
21701
21726
  render(sizeRecMainDiv) {
21702
21727
  const body = `<div id="tfr-size-recommendations">
21703
- <div id="tfr-size-rec-loading">
21728
+ <div id="tfr-size-rec-loading" class="hide">
21704
21729
  <div class="lds-ellipsis">
21705
21730
  <div></div>
21706
21731
  <div></div>
@@ -21792,7 +21817,7 @@ class SizeRecommendationController {
21792
21817
  );
21793
21818
  }
21794
21819
  setLoggedOutStyleMeasurementLocations(garmentMeasurementLocations = []) {
21795
- if (garmentMeasurementLocations.length == 0) {
21820
+ if (garmentMeasurementLocations.length === 0) {
21796
21821
  throw new Error("filteredLocations passed to setGarmentLocations is 0");
21797
21822
  }
21798
21823
  console.debug("filledLocations", garmentMeasurementLocations);
@@ -21807,8 +21832,16 @@ class SizeRecommendationController {
21807
21832
  async GetSizeRecommendationByStyleID(styleId) {
21808
21833
  console.debug("start size recommendation", styleId);
21809
21834
  try {
21835
+ this.Show();
21810
21836
  this.SetSizeRecommendationLoading(true);
21811
- const sizeFitRecommendation = await this.fittingRoomAPI.GetRecommendedSizes(styleId);
21837
+ this.sizeFitRecommendationPromise = this.fittingRoomAPI.GetRecommendedSizes(styleId);
21838
+ const sizeFitRecommendation = await this.sizeFitRecommendationPromise;
21839
+ if (!sizeFitRecommendation?.recommended_size) {
21840
+ this.sizeRecComponent.ShowLoggedIn();
21841
+ this.sizeRecComponent.Show();
21842
+ this.sizeRecComponent.ShowSizeRecommendationError("No sizes were recommended.");
21843
+ return;
21844
+ }
21812
21845
  const sizeMeasurementLocationFits = sizeFitRecommendation.available_sizes.map((size) => {
21813
21846
  const sizeMeasurementLocationFit = {
21814
21847
  isRecommended: size.id === sizeFitRecommendation.recommended_size.id,
@@ -21828,6 +21861,7 @@ class SizeRecommendationController {
21828
21861
  }).sort((a, b) => (a.size_value?.id || 0) - (b.size_value?.id || 0));
21829
21862
  this.sizeRecComponent.ShowLoggedIn();
21830
21863
  this.sizeRecComponent.Show();
21864
+ this.sizeRecComponent.HideSizeRecommendationError();
21831
21865
  this.sizeRecComponent.SetRecommendedSize(sizeMeasurementLocationFits);
21832
21866
  } catch (e) {
21833
21867
  console.error("error in get size recommendation", e);
@@ -21867,6 +21901,9 @@ class SizeRecommendationController {
21867
21901
  console.debug("SetVTOLoading", isLoading);
21868
21902
  this.sizeRecComponent.SetVTOLoading(isLoading);
21869
21903
  }
21904
+ CurrentSizeRecommendation() {
21905
+ return this.sizeFitRecommendationPromise;
21906
+ }
21870
21907
  setCssVariables(sizeRecMainDiv, cssVariables) {
21871
21908
  const toKebabCase = (str) => str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
21872
21909
  for (const [key, value] of Object.entries(cssVariables)) {
@@ -21915,21 +21952,21 @@ class VTOController {
21915
21952
  this.sliderElement = null;
21916
21953
  this.isShown = false;
21917
21954
  }
21918
- onNewFramesReady(frames2) {
21919
- console.debug("onNewFramesReady", frames2);
21955
+ onNewFramesReady(frames) {
21956
+ console.debug("onNewFramesReady", frames);
21920
21957
  if (!this.isShown) {
21921
21958
  this.show();
21922
21959
  }
21923
- if (Array.isArray(frames2) && frames2.length > 0) {
21924
- const boundedValue = Math.min(this.currentSliderValue, frames2.length - 1);
21925
- const e = this.slider.Load(frames2, boundedValue);
21960
+ if (Array.isArray(frames) && frames.length > 0) {
21961
+ const boundedValue = Math.min(this.currentSliderValue, frames.length - 1);
21962
+ const e = this.slider.Load(frames, boundedValue);
21926
21963
  if (e instanceof Error) {
21927
21964
  console.error(e);
21928
21965
  return;
21929
21966
  }
21930
- if (this.sliderElement && this.currentSliderValue < frames2.length) {
21967
+ if (this.sliderElement && this.currentSliderValue < frames.length) {
21931
21968
  this.sliderElement.value = this.currentSliderValue.toString();
21932
- this.tryOnImage.src = frames2[this.currentSliderValue];
21969
+ this.tryOnImage.src = frames[this.currentSliderValue];
21933
21970
  }
21934
21971
  }
21935
21972
  }
@@ -22014,7 +22051,10 @@ class FittingRoomController {
22014
22051
  }
22015
22052
  this.styleMeasurementLocations = this.styleToGarmentMeasurementLocations(this.style);
22016
22053
  const authUser = await authUserPromise;
22017
- this.unsubFirestoreUserStateChange = this.firebaseAuthUserController.ListenForAuthStateChange(true, this.authStateChangeCallback.bind(this));
22054
+ this.unsubFirestoreUserStateChange = this.firebaseAuthUserController.ListenForAuthStateChange(
22055
+ true,
22056
+ this.authStateChangeCallback.bind(this)
22057
+ );
22018
22058
  if (!authUser) {
22019
22059
  throw UserNotLoggedInError;
22020
22060
  }
@@ -22039,14 +22079,25 @@ class FittingRoomController {
22039
22079
  }
22040
22080
  }
22041
22081
  async SetColorwaySizeAssetBySKU(activeSku, skipCache = false) {
22082
+ if (!this.style?.is_vto) {
22083
+ console.warn("skipping SetColorwaySizeAssetBySKU due to disabled vto");
22084
+ return;
22085
+ }
22042
22086
  if (this.cacheColorwaySizeAssetsPromise) {
22043
22087
  await this.cacheColorwaySizeAssetsPromise;
22044
22088
  }
22045
- console.debug("SetColorwaySizeAssetBySKU", activeSku, skipCache);
22046
- if (!this.style?.is_vto) {
22047
- console.warn("skipping SetColorwaySizeAssetBySKU due to disabled vto");
22089
+ const currentSizeRec = this.SizeRecommendationController.CurrentSizeRecommendation();
22090
+ if (!currentSizeRec) {
22091
+ console.warn("skipping SetColorwaySizeAssetBySKU due to no size recommendation promise");
22048
22092
  return;
22049
22093
  }
22094
+ const sizeFitRecommendation = await currentSizeRec;
22095
+ console.debug("SetColorwaySizeAssetBySKU: SizeFitRecommendation", sizeFitRecommendation);
22096
+ if (!sizeFitRecommendation?.recommended_size?.id) {
22097
+ console.warn("skipping SetColorwaySizeAssetBySKU due to no size recommendation");
22098
+ return;
22099
+ }
22100
+ console.debug("SetColorwaySizeAssetBySKU", activeSku, skipCache);
22050
22101
  try {
22051
22102
  this.selectedColorwaySizeAsset = await this.API.GetCachedColorwaySizeAssetFromSku(activeSku, skipCache);
22052
22103
  } catch (e) {
@@ -22180,7 +22231,7 @@ class FittingRoomController {
22180
22231
  case AvatarStatusPending:
22181
22232
  if (this.hooks?.onLoading) this.hooks.onLoading();
22182
22233
  console.log("calling DisableTryOnButton - avatar not ready");
22183
- this.SizeRecommendationController.HideTryOnButton("Your avatar is not ready yet");
22234
+ this.SizeRecommendationController.DisableTryOnButton("Your avatar is not ready yet");
22184
22235
  break;
22185
22236
  case AvatarStatusCreated:
22186
22237
  if (this.hooks?.onLoadingComplete) this.hooks.onLoadingComplete();
@@ -22189,7 +22240,7 @@ class FittingRoomController {
22189
22240
  break;
22190
22241
  default:
22191
22242
  console.log("calling DisableTryOnButton - fitting room unavailable");
22192
- this.SizeRecommendationController.HideTryOnButton("The Fitting Room is currently unavailable.");
22243
+ this.SizeRecommendationController.DisableTryOnButton("The Fitting Room is currently unavailable.");
22193
22244
  throw new Error("no avatar status");
22194
22245
  }
22195
22246
  }
@@ -20609,12 +20609,22 @@ This typically indicates that your device does not have a healthy Internet conne
20609
20609
  }
20610
20610
  console.debug("checking user for vto frames", colorwaySizeAssetSKU);
20611
20611
  const firestoreUser = data;
20612
- const frames2 = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20613
- if (!frames2?.length) {
20612
+ const colorwaySizeAssetEntry = firestoreUser.vto?.[this.BrandID]?.[colorwaySizeAssetSKU];
20613
+ if (!colorwaySizeAssetEntry) {
20614
+ console.debug("no vto entry for SKU, continue watching:", colorwaySizeAssetSKU);
20615
+ return false;
20616
+ }
20617
+ if (colorwaySizeAssetEntry.error) {
20618
+ console.error("VTO error found for SKU:", colorwaySizeAssetSKU, colorwaySizeAssetEntry.error);
20619
+ throw NoFramesFoundError;
20620
+ }
20621
+ console.debug("cololrwaySizeAssetEntry", colorwaySizeAssetEntry);
20622
+ const frames = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20623
+ if (!frames?.length) {
20614
20624
  throw NoFramesFoundError;
20615
20625
  }
20616
- console.debug("testing first frame for SKU:", colorwaySizeAssetSKU, frames2[0]);
20617
- const tested = await testImage(frames2[0]);
20626
+ console.debug("testing first frame for SKU:", colorwaySizeAssetSKU, frames[0]);
20627
+ const tested = await testImage(frames[0]);
20618
20628
  if (!tested) {
20619
20629
  console.error("image test failed for SKU:", colorwaySizeAssetSKU);
20620
20630
  throw NoFramesFoundError;
@@ -20645,12 +20655,12 @@ This typically indicates that your device does not have a healthy Internet conne
20645
20655
  console.error(`Error watching for try-on frames for SKU: ${colorwaySizeAssetSKU}`, error);
20646
20656
  throw error;
20647
20657
  }
20648
- const frames2 = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20649
- if (!frames2) {
20658
+ const frames = this.getVTOFramesFromUser(firestoreUser, colorwaySizeAssetSKU);
20659
+ if (!frames) {
20650
20660
  console.error(`Frames not found on final user object for SKU: ${colorwaySizeAssetSKU}`, firestoreUser);
20651
20661
  throw NoFramesFoundError;
20652
20662
  }
20653
- return frames2;
20663
+ return frames;
20654
20664
  }
20655
20665
  async GetCachedOrRequestUserColorwaySizeAssetFrames(firestoreUserController, colorwaySizeAssetSKU, skipCache) {
20656
20666
  console.debug("GetCachedOrRequestUserColorwaySizeAssetFrames", colorwaySizeAssetSKU, "skipCache:", skipCache);
@@ -20687,7 +20697,6 @@ This typically indicates that your device does not have a healthy Internet conne
20687
20697
  framesPromise = this.watchForTryOnFrames(firestoreUserController, colorwaySizeAssetSKU, true);
20688
20698
  }
20689
20699
  this.vtoFramesPromiseCache.set(colorwaySizeAssetSKU, framesPromise);
20690
- console.debug("retrieved frames", frames);
20691
20700
  return await framesPromise;
20692
20701
  }
20693
20702
  }
@@ -21342,10 +21351,10 @@ This typically indicates that your device does not have a healthy Internet conne
21342
21351
  }
21343
21352
  toPasswordReset() {
21344
21353
  }
21345
- onTryOn(frames2) {
21354
+ onTryOn(frames) {
21346
21355
  this.manager.open(
21347
21356
  TryOnModal({
21348
- frames: frames2,
21357
+ frames,
21349
21358
  onClose: () => this.close(),
21350
21359
  onNavBack: () => this.navBack()
21351
21360
  })
@@ -21483,6 +21492,17 @@ This typically indicates that your device does not have a healthy Internet conne
21483
21492
  this.tfrTryOnButton.classList.remove("loading");
21484
21493
  }
21485
21494
  }
21495
+ ShowSizeRecommendationError(message) {
21496
+ console.debug("ShowSizeRecommendationError", message);
21497
+ this.tfrSizeRecommendationError.innerHTML = message;
21498
+ this.tfrSizeRecommendationError.classList.remove("hide");
21499
+ this.tfrSizeRecommendationsContainer.classList.add("hide");
21500
+ }
21501
+ HideSizeRecommendationError() {
21502
+ console.debug("HideSizeRecommendationError");
21503
+ this.tfrSizeRecommendationError.classList.add("hide");
21504
+ this.tfrSizeRecommendationsContainer.classList.remove("hide");
21505
+ }
21486
21506
  SetStyleMeasurementLocations(garmentMeasurementLocations) {
21487
21507
  if (!garmentMeasurementLocations || !garmentMeasurementLocations.length) {
21488
21508
  this.tfrSizeRecTitle.classList.add("hide");
@@ -21506,6 +21526,9 @@ This typically indicates that your device does not have a healthy Internet conne
21506
21526
  showTryOnButton() {
21507
21527
  this.tfrTryOnButton.classList.remove("hide");
21508
21528
  }
21529
+ hideTryOnButton() {
21530
+ this.tfrTryOnButton.classList.add("hide");
21531
+ }
21509
21532
  disableTryOnButton(message) {
21510
21533
  this.tfrTryOnButton.disabled = true;
21511
21534
  this.tfrTryOnButton.title = message;
@@ -21519,6 +21542,7 @@ This typically indicates that your device does not have a healthy Internet conne
21519
21542
  init(sizeRecMainDiv) {
21520
21543
  if (!sizeRecMainDiv) throw new Error("Size rec main div not found");
21521
21544
  this.sizeRecMainDiv = sizeRecMainDiv;
21545
+ this.sizeRecMainDiv.classList.add("hide");
21522
21546
  this.render(sizeRecMainDiv);
21523
21547
  this.setElements(sizeRecMainDiv);
21524
21548
  this.bindEvents();
@@ -21614,7 +21638,8 @@ This typically indicates that your device does not have a healthy Internet conne
21614
21638
  }
21615
21639
  renderSizeRec(sizeMeasurementLocationFits) {
21616
21640
  const selectedSizeIndex = sizeMeasurementLocationFits.findIndex((size) => size.isRecommended);
21617
- const selectedSizeLabel = sizeMeasurementLocationFits[selectedSizeIndex].label;
21641
+ const selectedSize = sizeMeasurementLocationFits[selectedSizeIndex];
21642
+ const selectedSizeLabel = selectedSize.label || selectedSize.size_value?.name || selectedSize.id;
21618
21643
  this.tfrSizeRecSize.innerHTML = `&nbsp;${selectedSizeLabel}`;
21619
21644
  this.availableSizes = sizeMeasurementLocationFits;
21620
21645
  this.redraw = (index) => this.renderSizeRecTable(sizeMeasurementLocationFits, index);
@@ -21627,7 +21652,7 @@ This typically indicates that your device does not have a healthy Internet conne
21627
21652
  }
21628
21653
  renderSizeRecSelect(sizeMeasurementLocationFits, index) {
21629
21654
  const html = sizeMeasurementLocationFits.map(
21630
- (size, i) => `<div class="tfr-size-rec-select-button ${i === index ? "active" : ""}" data-index="${i}">${size.label}</div>`
21655
+ (size, i) => `<div class="tfr-size-rec-select-button ${i === index ? "active" : ""}" data-index="${i}">${size.label || size.size_value?.name || size.id}</div>`
21631
21656
  ).join("");
21632
21657
  this.tfrSizeRecSelect.innerHTML = html;
21633
21658
  }
@@ -21704,7 +21729,7 @@ This typically indicates that your device does not have a healthy Internet conne
21704
21729
  }
21705
21730
  render(sizeRecMainDiv) {
21706
21731
  const body = `<div id="tfr-size-recommendations">
21707
- <div id="tfr-size-rec-loading">
21732
+ <div id="tfr-size-rec-loading" class="hide">
21708
21733
  <div class="lds-ellipsis">
21709
21734
  <div></div>
21710
21735
  <div></div>
@@ -21796,7 +21821,7 @@ This typically indicates that your device does not have a healthy Internet conne
21796
21821
  );
21797
21822
  }
21798
21823
  setLoggedOutStyleMeasurementLocations(garmentMeasurementLocations = []) {
21799
- if (garmentMeasurementLocations.length == 0) {
21824
+ if (garmentMeasurementLocations.length === 0) {
21800
21825
  throw new Error("filteredLocations passed to setGarmentLocations is 0");
21801
21826
  }
21802
21827
  console.debug("filledLocations", garmentMeasurementLocations);
@@ -21811,8 +21836,16 @@ This typically indicates that your device does not have a healthy Internet conne
21811
21836
  async GetSizeRecommendationByStyleID(styleId) {
21812
21837
  console.debug("start size recommendation", styleId);
21813
21838
  try {
21839
+ this.Show();
21814
21840
  this.SetSizeRecommendationLoading(true);
21815
- const sizeFitRecommendation = await this.fittingRoomAPI.GetRecommendedSizes(styleId);
21841
+ this.sizeFitRecommendationPromise = this.fittingRoomAPI.GetRecommendedSizes(styleId);
21842
+ const sizeFitRecommendation = await this.sizeFitRecommendationPromise;
21843
+ if (!sizeFitRecommendation?.recommended_size) {
21844
+ this.sizeRecComponent.ShowLoggedIn();
21845
+ this.sizeRecComponent.Show();
21846
+ this.sizeRecComponent.ShowSizeRecommendationError("No sizes were recommended.");
21847
+ return;
21848
+ }
21816
21849
  const sizeMeasurementLocationFits = sizeFitRecommendation.available_sizes.map((size) => {
21817
21850
  const sizeMeasurementLocationFit = {
21818
21851
  isRecommended: size.id === sizeFitRecommendation.recommended_size.id,
@@ -21832,6 +21865,7 @@ This typically indicates that your device does not have a healthy Internet conne
21832
21865
  }).sort((a, b) => (a.size_value?.id || 0) - (b.size_value?.id || 0));
21833
21866
  this.sizeRecComponent.ShowLoggedIn();
21834
21867
  this.sizeRecComponent.Show();
21868
+ this.sizeRecComponent.HideSizeRecommendationError();
21835
21869
  this.sizeRecComponent.SetRecommendedSize(sizeMeasurementLocationFits);
21836
21870
  } catch (e) {
21837
21871
  console.error("error in get size recommendation", e);
@@ -21871,6 +21905,9 @@ This typically indicates that your device does not have a healthy Internet conne
21871
21905
  console.debug("SetVTOLoading", isLoading);
21872
21906
  this.sizeRecComponent.SetVTOLoading(isLoading);
21873
21907
  }
21908
+ CurrentSizeRecommendation() {
21909
+ return this.sizeFitRecommendationPromise;
21910
+ }
21874
21911
  setCssVariables(sizeRecMainDiv, cssVariables) {
21875
21912
  const toKebabCase = (str) => str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
21876
21913
  for (const [key, value] of Object.entries(cssVariables)) {
@@ -21919,21 +21956,21 @@ This typically indicates that your device does not have a healthy Internet conne
21919
21956
  this.sliderElement = null;
21920
21957
  this.isShown = false;
21921
21958
  }
21922
- onNewFramesReady(frames2) {
21923
- console.debug("onNewFramesReady", frames2);
21959
+ onNewFramesReady(frames) {
21960
+ console.debug("onNewFramesReady", frames);
21924
21961
  if (!this.isShown) {
21925
21962
  this.show();
21926
21963
  }
21927
- if (Array.isArray(frames2) && frames2.length > 0) {
21928
- const boundedValue = Math.min(this.currentSliderValue, frames2.length - 1);
21929
- const e = this.slider.Load(frames2, boundedValue);
21964
+ if (Array.isArray(frames) && frames.length > 0) {
21965
+ const boundedValue = Math.min(this.currentSliderValue, frames.length - 1);
21966
+ const e = this.slider.Load(frames, boundedValue);
21930
21967
  if (e instanceof Error) {
21931
21968
  console.error(e);
21932
21969
  return;
21933
21970
  }
21934
- if (this.sliderElement && this.currentSliderValue < frames2.length) {
21971
+ if (this.sliderElement && this.currentSliderValue < frames.length) {
21935
21972
  this.sliderElement.value = this.currentSliderValue.toString();
21936
- this.tryOnImage.src = frames2[this.currentSliderValue];
21973
+ this.tryOnImage.src = frames[this.currentSliderValue];
21937
21974
  }
21938
21975
  }
21939
21976
  }
@@ -22018,7 +22055,10 @@ This typically indicates that your device does not have a healthy Internet conne
22018
22055
  }
22019
22056
  this.styleMeasurementLocations = this.styleToGarmentMeasurementLocations(this.style);
22020
22057
  const authUser = await authUserPromise;
22021
- this.unsubFirestoreUserStateChange = this.firebaseAuthUserController.ListenForAuthStateChange(true, this.authStateChangeCallback.bind(this));
22058
+ this.unsubFirestoreUserStateChange = this.firebaseAuthUserController.ListenForAuthStateChange(
22059
+ true,
22060
+ this.authStateChangeCallback.bind(this)
22061
+ );
22022
22062
  if (!authUser) {
22023
22063
  throw UserNotLoggedInError;
22024
22064
  }
@@ -22043,14 +22083,25 @@ This typically indicates that your device does not have a healthy Internet conne
22043
22083
  }
22044
22084
  }
22045
22085
  async SetColorwaySizeAssetBySKU(activeSku, skipCache = false) {
22086
+ if (!this.style?.is_vto) {
22087
+ console.warn("skipping SetColorwaySizeAssetBySKU due to disabled vto");
22088
+ return;
22089
+ }
22046
22090
  if (this.cacheColorwaySizeAssetsPromise) {
22047
22091
  await this.cacheColorwaySizeAssetsPromise;
22048
22092
  }
22049
- console.debug("SetColorwaySizeAssetBySKU", activeSku, skipCache);
22050
- if (!this.style?.is_vto) {
22051
- console.warn("skipping SetColorwaySizeAssetBySKU due to disabled vto");
22093
+ const currentSizeRec = this.SizeRecommendationController.CurrentSizeRecommendation();
22094
+ if (!currentSizeRec) {
22095
+ console.warn("skipping SetColorwaySizeAssetBySKU due to no size recommendation promise");
22052
22096
  return;
22053
22097
  }
22098
+ const sizeFitRecommendation = await currentSizeRec;
22099
+ console.debug("SetColorwaySizeAssetBySKU: SizeFitRecommendation", sizeFitRecommendation);
22100
+ if (!sizeFitRecommendation?.recommended_size?.id) {
22101
+ console.warn("skipping SetColorwaySizeAssetBySKU due to no size recommendation");
22102
+ return;
22103
+ }
22104
+ console.debug("SetColorwaySizeAssetBySKU", activeSku, skipCache);
22054
22105
  try {
22055
22106
  this.selectedColorwaySizeAsset = await this.API.GetCachedColorwaySizeAssetFromSku(activeSku, skipCache);
22056
22107
  } catch (e) {
@@ -22184,7 +22235,7 @@ This typically indicates that your device does not have a healthy Internet conne
22184
22235
  case AvatarStatusPending:
22185
22236
  if (this.hooks?.onLoading) this.hooks.onLoading();
22186
22237
  console.log("calling DisableTryOnButton - avatar not ready");
22187
- this.SizeRecommendationController.HideTryOnButton("Your avatar is not ready yet");
22238
+ this.SizeRecommendationController.DisableTryOnButton("Your avatar is not ready yet");
22188
22239
  break;
22189
22240
  case AvatarStatusCreated:
22190
22241
  if (this.hooks?.onLoadingComplete) this.hooks.onLoadingComplete();
@@ -22193,7 +22244,7 @@ This typically indicates that your device does not have a healthy Internet conne
22193
22244
  break;
22194
22245
  default:
22195
22246
  console.log("calling DisableTryOnButton - fitting room unavailable");
22196
- this.SizeRecommendationController.HideTryOnButton("The Fitting Room is currently unavailable.");
22247
+ this.SizeRecommendationController.DisableTryOnButton("The Fitting Room is currently unavailable.");
22197
22248
  throw new Error("no avatar status");
22198
22249
  }
22199
22250
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thefittingroom/shop-ui",
3
- "version": "4.3.1",
3
+ "version": "4.3.3",
4
4
  "description": "the fitting room UI library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",