@inappstory/slide-api 0.0.22 → 0.0.23

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.cjs CHANGED
@@ -575,8 +575,8 @@ const getWinWidth = function (env) {
575
575
  const getWinHeight = function (env) {
576
576
  return env.innerHeight || env.document.documentElement.clientHeight || env.document.body.clientHeight;
577
577
  };
578
- const sendStatisticEventToApp = function (sdkApi, name, data, devPayload) {
579
- sdkApi.sendStatisticEvent(name, data, devPayload);
578
+ const sendStatisticEventToApp = function (sdkApi, name, data, devPayload, options) {
579
+ sdkApi.sendStatisticEvent(name, data, devPayload, options?.forceEnableStatisticV2 ?? false);
580
580
  };
581
581
  const getValueOrException = function (value, message) {
582
582
  if (value == null) {
@@ -672,6 +672,37 @@ const Clipboard = (function (window, document, navigator) {
672
672
  copy,
673
673
  };
674
674
  })(window, document, navigator);
675
+ function FilterNumber(x) {
676
+ return typeof x === "number";
677
+ }
678
+ function determineLocale() {
679
+ // All modern browsers support this. Should match what's used by localeCompare() etc.
680
+ const intl = window.Intl;
681
+ if (intl !== undefined) {
682
+ return intl.NumberFormat().resolvedOptions().locale;
683
+ }
684
+ // Fall back to ranked choice locales, which are configured in the browser but aren't necessarily
685
+ // what's used in functions like localeCompare().
686
+ const languages = navigator.languages;
687
+ if (languages !== undefined && languages.length > 0) {
688
+ return languages[0];
689
+ }
690
+ // Old standard.
691
+ return navigator.language ?? "en-US";
692
+ }
693
+ function isScreenSupportsTouch(env) {
694
+ let supportsTouch = false;
695
+ if ("ontouchstart" in env) {
696
+ supportsTouch = true;
697
+ }
698
+ else if (env.navigator.msPointerEnabled) {
699
+ supportsTouch = true;
700
+ }
701
+ else if ("ontouchstart" in env.document.documentElement) {
702
+ supportsTouch = true;
703
+ }
704
+ return supportsTouch;
705
+ }
675
706
 
676
707
  var supportAnimate = document.documentElement.animate !== undefined;
677
708
  supportAnimate = false; // tmp off
@@ -1069,8 +1100,8 @@ class EsModuleSdkApi {
1069
1100
  showNextSlide(duration) {
1070
1101
  this.sdkBinding().showNextSlide(duration);
1071
1102
  }
1072
- sendStatisticEvent(name, data, devPayload) {
1073
- this.sdkBinding().sendStatisticEvent(name, data, devPayload);
1103
+ sendStatisticEvent(name, data, devPayload, forceEnableStatisticV2) {
1104
+ this.sdkBinding().sendStatisticEvent(name, data, devPayload, forceEnableStatisticV2);
1074
1105
  }
1075
1106
  getCardLocalData() {
1076
1107
  return this.sdkBinding().getCardLocalData();
@@ -1171,6 +1202,14 @@ class EsModuleSdkApi {
1171
1202
  getCardFonts() {
1172
1203
  return this.sdkBinding().getCardFonts();
1173
1204
  }
1205
+ disableVerticalSwipeGesture() {
1206
+ this.sdkBinding().disableVerticalSwipeGesture();
1207
+ }
1208
+ enableVerticalSwipeGesture() {
1209
+ this.sdkBinding().enableVerticalSwipeGesture();
1210
+ }
1211
+ disableBackpress() { }
1212
+ enableBackpress() { }
1174
1213
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`() => SDKInterface`]; }
1175
1214
  }
1176
1215
 
@@ -1425,11 +1464,11 @@ class WidgetBase {
1425
1464
  }
1426
1465
  return data;
1427
1466
  }
1428
- static sendStatisticEventToApp(name, data, devPayload) {
1429
- sendStatisticEventToApp(this.widgetsService.sdkApi, name, data, devPayload);
1467
+ static sendStatisticEventToApp(name, data, devPayload, options) {
1468
+ sendStatisticEventToApp(this.widgetsService.sdkApi, name, data, devPayload, options);
1430
1469
  }
1431
- sendStatisticEventToApp(name, data, devPayload) {
1432
- this.constructor.sendStatisticEventToApp(name, data, devPayload);
1470
+ sendStatisticEventToApp(name, data, devPayload, options) {
1471
+ this.constructor.sendStatisticEventToApp(name, data, devPayload, options);
1433
1472
  }
1434
1473
  startDisabledTimeline() {
1435
1474
  this.sdkApi.startDisabledTimeline(this.cardId, this.slideIndex);
@@ -2041,7 +2080,9 @@ class WidgetDateCountdown extends WidgetBase {
2041
2080
  this._showLayer(this.layers, 0);
2042
2081
  }
2043
2082
  else {
2044
- this._showLayer(this.layers, 1);
2083
+ if (this.layers[1] != null) {
2084
+ this._showLayer(this.layers, 1);
2085
+ }
2045
2086
  }
2046
2087
  }
2047
2088
  onPause() {
@@ -2124,7 +2165,9 @@ class WidgetDateCountdown extends WidgetBase {
2124
2165
  }
2125
2166
  else {
2126
2167
  this.pendingUpdate = false;
2127
- this._showLayer(this.layers, 1);
2168
+ if (this.layers[1] != null) {
2169
+ this._showLayer(this.layers, 1);
2170
+ }
2128
2171
  }
2129
2172
  if (this.pendingUpdate) {
2130
2173
  this.env.requestAnimationFrame(() => this.updateTimer());
@@ -3084,6 +3127,7 @@ class WidgetQuest extends WidgetBase {
3084
3127
  isWidget;
3085
3128
  slideCount;
3086
3129
  nonFinalSlide;
3130
+ slideDisabledNavigation;
3087
3131
  finalSlide;
3088
3132
  constructor(element, options) {
3089
3133
  const isWidget = !hasClass(element, "narrative-slide");
@@ -3096,6 +3140,7 @@ class WidgetQuest extends WidgetBase {
3096
3140
  this.finalSlide = !this.isWidget && !this.nonFinalSlide;
3097
3141
  this.label = this.element.querySelector(".label-view .label");
3098
3142
  this.variants = slice.call(this.element.querySelectorAll(".variants-box .variant-view"));
3143
+ this.slideDisabledNavigation = Boolean(getTagDataAsNumber(this.slide, "disableNavigation") ?? 0);
3099
3144
  this.selectedAnswer = undefined;
3100
3145
  }
3101
3146
  /**
@@ -3240,6 +3285,10 @@ class WidgetQuest extends WidgetBase {
3240
3285
  const directionForward = event.direction === "forward";
3241
3286
  event.direction === "backward";
3242
3287
  if (this.isWidget) {
3288
+ // like in web-sdk - simple block tap navigation at all
3289
+ if (this.slideDisabledNavigation) {
3290
+ return;
3291
+ }
3243
3292
  if (directionForward) {
3244
3293
  return;
3245
3294
  }
@@ -3263,6 +3312,10 @@ class WidgetQuest extends WidgetBase {
3263
3312
  }
3264
3313
  }
3265
3314
  else {
3315
+ // like in web-sdk - simple block tap navigation at all
3316
+ if (this.slideDisabledNavigation) {
3317
+ return;
3318
+ }
3266
3319
  // slides without quest form
3267
3320
  // simple slide case
3268
3321
  if (this.nonFinalSlide || event.slideIndex < this.firstSlideWithQuestIndex()) {
@@ -4221,10 +4274,10 @@ class WidgetRangeSlider extends WidgetBase {
4221
4274
  if (!this.maxHandlePos) {
4222
4275
  this.update(true, false);
4223
4276
  }
4224
- document.addEventListener("touchmove", this.handleMove);
4225
- document.addEventListener("touchend", this.handleEnd);
4226
- document.addEventListener("mousemove", this.handleMove);
4227
- document.addEventListener("mouseup", this.handleEnd);
4277
+ this.env.document.addEventListener("touchmove", this.handleMove);
4278
+ this.env.document.addEventListener("touchend", this.handleEnd);
4279
+ this.env.document.addEventListener("mousemove", this.handleMove);
4280
+ this.env.document.addEventListener("mouseup", this.handleEnd);
4228
4281
  // add active class because Firefox is ignoring
4229
4282
  // the handle:active pseudo selector because of `e.preventDefault();`
4230
4283
  this.range.classList.add(this.options.activeClass);
@@ -4249,10 +4302,10 @@ class WidgetRangeSlider extends WidgetBase {
4249
4302
  this.isClickCapturedBySlider = false;
4250
4303
  });
4251
4304
  // e.preventDefault();
4252
- document.removeEventListener("touchmove", this.handleMove);
4253
- document.removeEventListener("touchend", this.handleEnd);
4254
- document.removeEventListener("mousemove", this.handleMove);
4255
- document.removeEventListener("mouseup", this.handleEnd);
4305
+ this.env.document.removeEventListener("touchmove", this.handleMove);
4306
+ this.env.document.removeEventListener("touchend", this.handleEnd);
4307
+ this.env.document.removeEventListener("mousemove", this.handleMove);
4308
+ this.env.document.removeEventListener("mouseup", this.handleEnd);
4256
4309
  this.range.classList.remove(this.options.activeClass);
4257
4310
  this.element.classList.add("input-done");
4258
4311
  if (!this.hasSubmitButton) {
@@ -15282,6 +15335,1045 @@ class WidgetBarcode extends WidgetBase {
15282
15335
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`]; }
15283
15336
  }
15284
15337
 
15338
+ class Formatter {
15339
+ intlSupport = false;
15340
+ defaultTimeFormat = "medium";
15341
+ defaultDatetimeFormat = "medium";
15342
+ defaultDateFormat = "medium";
15343
+ decimalSeparator = ".";
15344
+ thousandSeparator = "&thinsp;";
15345
+ spaceSeparator = "&thinsp;";
15346
+ static Second = 1000;
15347
+ static Minute = 60 * Formatter.Second;
15348
+ static Hour = 60 * Formatter.Minute;
15349
+ static Day = 24 * Formatter.Hour;
15350
+ datetimeFormatOptions = {
15351
+ short: {
15352
+ year: "numeric",
15353
+ month: "2-digit",
15354
+ day: "2-digit",
15355
+ hour: "2-digit",
15356
+ minute: "2-digit",
15357
+ },
15358
+ medium: {
15359
+ year: "numeric",
15360
+ month: "2-digit",
15361
+ day: "2-digit",
15362
+ hour: "2-digit",
15363
+ minute: "2-digit",
15364
+ second: "2-digit",
15365
+ },
15366
+ long: {
15367
+ year: "numeric",
15368
+ month: "long",
15369
+ day: "2-digit",
15370
+ hour: "2-digit",
15371
+ minute: "2-digit",
15372
+ second: "2-digit",
15373
+ timeZoneName: "short",
15374
+ },
15375
+ full: {
15376
+ weekday: "long",
15377
+ year: "numeric",
15378
+ month: "long",
15379
+ day: "2-digit",
15380
+ hour: "2-digit",
15381
+ minute: "2-digit",
15382
+ second: "2-digit",
15383
+ timeZoneName: "long",
15384
+ },
15385
+ };
15386
+ dateFormatOptions = {
15387
+ short: {
15388
+ year: "2-digit",
15389
+ month: "2-digit",
15390
+ day: "2-digit",
15391
+ },
15392
+ medium: {
15393
+ year: "numeric",
15394
+ month: "2-digit",
15395
+ day: "2-digit",
15396
+ },
15397
+ long: {
15398
+ year: "numeric",
15399
+ month: "long",
15400
+ day: "2-digit",
15401
+ },
15402
+ full: {
15403
+ weekday: "long",
15404
+ year: "numeric",
15405
+ month: "long",
15406
+ day: "2-digit",
15407
+ },
15408
+ };
15409
+ timeFormatOptions = {
15410
+ short: {
15411
+ hour: "2-digit",
15412
+ minute: "2-digit",
15413
+ },
15414
+ medium: {
15415
+ hour: "2-digit",
15416
+ minute: "2-digit",
15417
+ second: "2-digit",
15418
+ },
15419
+ long: {
15420
+ hour: "2-digit",
15421
+ minute: "2-digit",
15422
+ second: "2-digit",
15423
+ timeZoneName: "short",
15424
+ },
15425
+ full: {
15426
+ hour: "2-digit",
15427
+ minute: "2-digit",
15428
+ second: "2-digit",
15429
+ timeZoneName: "long",
15430
+ },
15431
+ };
15432
+ context;
15433
+ constructor(context) {
15434
+ this.intlSupport = typeof Intl === "object" && Intl !== null;
15435
+ this.context = context;
15436
+ }
15437
+ asDate(value, format = undefined, options = {}) {
15438
+ if (!format) {
15439
+ format = this.defaultDateFormat;
15440
+ }
15441
+ return this.formatDateTimeValue(value, format, "date", options);
15442
+ }
15443
+ asTime(value, format = undefined, options = {}) {
15444
+ if (!format) {
15445
+ format = this.defaultTimeFormat;
15446
+ }
15447
+ return this.formatDateTimeValue(value, format, "time", options);
15448
+ }
15449
+ asDatetime(value, format = undefined, options = {}) {
15450
+ if (!format) {
15451
+ format = this.defaultTimeFormat;
15452
+ }
15453
+ return this.formatDateTimeValue(value, format, "datetime", options);
15454
+ }
15455
+ formatDateTimeValue(value, format = undefined, type = undefined, options = {}) {
15456
+ const normalizedValue = Formatter.normalizeDatetimeValue(value);
15457
+ if (normalizedValue === null) {
15458
+ return "";
15459
+ }
15460
+ if (this.intlSupport) {
15461
+ let formatterOptions = {};
15462
+ if (type === "date") {
15463
+ if (typeof format === "undefined") {
15464
+ format = this.defaultDateFormat;
15465
+ }
15466
+ if (typeof format === "object") {
15467
+ formatterOptions = format;
15468
+ }
15469
+ else {
15470
+ if (format in this.dateFormatOptions) {
15471
+ formatterOptions = this.dateFormatOptions[format];
15472
+ }
15473
+ else {
15474
+ return this.momentFallback(normalizedValue, format, options);
15475
+ }
15476
+ }
15477
+ }
15478
+ else if (type === "time") {
15479
+ if (typeof format === "undefined") {
15480
+ format = this.defaultTimeFormat;
15481
+ }
15482
+ if (typeof format === "object") {
15483
+ formatterOptions = format;
15484
+ }
15485
+ else {
15486
+ if (format in this.timeFormatOptions) {
15487
+ formatterOptions = this.timeFormatOptions[format];
15488
+ }
15489
+ else {
15490
+ return this.momentFallback(normalizedValue, format, options);
15491
+ }
15492
+ }
15493
+ }
15494
+ else if (type === "datetime") {
15495
+ if (typeof format === "undefined") {
15496
+ format = this.defaultDatetimeFormat;
15497
+ }
15498
+ if (typeof format === "object") {
15499
+ formatterOptions = format;
15500
+ }
15501
+ else {
15502
+ if (format in this.datetimeFormatOptions) {
15503
+ formatterOptions = this.datetimeFormatOptions[format];
15504
+ }
15505
+ else {
15506
+ return this.momentFallback(normalizedValue, format, options);
15507
+ }
15508
+ }
15509
+ }
15510
+ if (options.timezone) {
15511
+ formatterOptions.timeZone = options.timezone;
15512
+ }
15513
+ Intl.DateTimeFormat(this.locale, formatterOptions).format(normalizedValue);
15514
+ return Intl.DateTimeFormat(this.locale, formatterOptions).format(normalizedValue);
15515
+ }
15516
+ return "";
15517
+ }
15518
+ momentFallback(value, format, options = {}) {
15519
+ return value.toLocaleString(this.locale);
15520
+ // return this.context.$moment(value).format(format);
15521
+ }
15522
+ asInteger(value) {
15523
+ if (value === undefined || value === null) {
15524
+ return this.nullDisplay;
15525
+ }
15526
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15527
+ if (this.intlSupport) {
15528
+ return Intl.NumberFormat(this.locale, {
15529
+ maximumFractionDigits: 0,
15530
+ useGrouping: true,
15531
+ }).format(normalizedValue);
15532
+ }
15533
+ return Formatter.numberFormat(normalizedValue, 0, this.decimalSeparator, this.thousandSeparator);
15534
+ }
15535
+ asDecimal(value, decimals = 2) {
15536
+ if (value == null) {
15537
+ return this.nullDisplay;
15538
+ }
15539
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15540
+ if (this.intlSupport) {
15541
+ return Intl.NumberFormat(this.locale, {
15542
+ maximumFractionDigits: decimals,
15543
+ minimumFractionDigits: decimals,
15544
+ useGrouping: true,
15545
+ }).format(normalizedValue);
15546
+ }
15547
+ return Formatter.numberFormat(normalizedValue, decimals, this.decimalSeparator, this.thousandSeparator);
15548
+ }
15549
+ asDecimalMax(value, decimals = 2) {
15550
+ if (value === undefined || value === null) {
15551
+ return this.nullDisplay;
15552
+ }
15553
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15554
+ if (this.intlSupport) {
15555
+ return Intl.NumberFormat(this.locale, {
15556
+ maximumFractionDigits: decimals,
15557
+ minimumFractionDigits: 0,
15558
+ useGrouping: true,
15559
+ }).format(normalizedValue);
15560
+ }
15561
+ return Formatter.numberFormat(normalizedValue, decimals, this.decimalSeparator, this.thousandSeparator);
15562
+ }
15563
+ asPercent(value, decimals = 0) {
15564
+ if (value === undefined || value === null) {
15565
+ return this.nullDisplay;
15566
+ }
15567
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15568
+ if (this.intlSupport) {
15569
+ return Intl.NumberFormat(this.locale, {
15570
+ style: "percent",
15571
+ maximumFractionDigits: decimals,
15572
+ minimumFractionDigits: decimals,
15573
+ }).format(normalizedValue);
15574
+ }
15575
+ return Formatter.numberFormat(normalizedValue * 100, decimals, this.decimalSeparator, this.thousandSeparator);
15576
+ }
15577
+ asPercentMax(value, decimals = 0) {
15578
+ if (value === undefined || value === null) {
15579
+ return this.nullDisplay;
15580
+ }
15581
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15582
+ if (this.intlSupport) {
15583
+ return Intl.NumberFormat(this.locale, {
15584
+ style: "percent",
15585
+ maximumFractionDigits: decimals,
15586
+ minimumFractionDigits: 0,
15587
+ }).format(normalizedValue);
15588
+ }
15589
+ return Formatter.numberFormat(normalizedValue * 100, decimals, this.decimalSeparator, this.thousandSeparator);
15590
+ }
15591
+ asRelativeTime(value, referenceTime = undefined) {
15592
+ if (value === undefined || value === null) {
15593
+ return this.nullDisplay;
15594
+ }
15595
+ const normalizedValue = Formatter.normalizeDatetimeValue(value);
15596
+ if (normalizedValue == null) {
15597
+ return this.nullDisplay;
15598
+ }
15599
+ if (referenceTime === undefined || referenceTime === null) {
15600
+ referenceTime = new Date();
15601
+ }
15602
+ else {
15603
+ referenceTime = Formatter.normalizeDatetimeValue(value);
15604
+ }
15605
+ const dt = referenceTime.getTime() - normalizedValue.getTime();
15606
+ const absDt = Math.abs(dt);
15607
+ const invert = dt < 0;
15608
+ if (absDt < Formatter.Second) {
15609
+ return this.context.i18n?.t("format.relativeTime.justNow").toString() ?? "";
15610
+ }
15611
+ const seconds = absDt / 1000;
15612
+ let interval = seconds / 31536000;
15613
+ if (interval > 1) {
15614
+ return this.context.i18n?.tc("format.relativeTime.year" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15615
+ }
15616
+ interval = seconds / 2592000;
15617
+ if (interval > 1) {
15618
+ return this.context.i18n?.tc("format.relativeTime.month" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15619
+ }
15620
+ interval = seconds / 86400;
15621
+ if (interval > 1) {
15622
+ return this.context.i18n?.tc("format.relativeTime.day" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15623
+ }
15624
+ interval = seconds / 3600;
15625
+ if (interval > 1) {
15626
+ return this.context.i18n?.tc("format.relativeTime.hour" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15627
+ }
15628
+ interval = seconds / 60;
15629
+ if (interval > 1) {
15630
+ return this.context.i18n?.tc("format.relativeTime.minute" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15631
+ }
15632
+ return this.context.i18n?.tc("format.relativeTime.second" + (invert ? "In" : "Ago"), Math.floor(seconds)).toString() ?? "";
15633
+ }
15634
+ asDuration(value) {
15635
+ if (value === undefined || value === null) {
15636
+ return "00:00";
15637
+ }
15638
+ const normalizedValue = Formatter.normalizeDatetimeValue(value);
15639
+ if (normalizedValue === undefined || normalizedValue === null) {
15640
+ return "00:00";
15641
+ }
15642
+ const hours = Math.floor(value / 3600);
15643
+ const minutes = Math.floor((value / 60) % 60);
15644
+ const seconds = value % 60;
15645
+ if (hours > 0) {
15646
+ return `${hours}:${minutes < 10 ? 0 : ""}${minutes}:${seconds < 10 ? 0 : ""}${seconds}`;
15647
+ }
15648
+ else {
15649
+ return `${minutes < 10 ? 0 : ""}${minutes}:${seconds < 10 ? 0 : ""}${seconds}`;
15650
+ }
15651
+ }
15652
+ asCurrency(value, currency = undefined) {
15653
+ if (value === undefined || value === null) {
15654
+ return this.nullDisplay;
15655
+ }
15656
+ if (currency === undefined || currency === null) {
15657
+ currency = "USD";
15658
+ }
15659
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15660
+ if (normalizedValue == null) {
15661
+ return this.nullDisplay;
15662
+ }
15663
+ let decimals = 2;
15664
+ if (Number.isInteger(normalizedValue)) {
15665
+ decimals = 0;
15666
+ }
15667
+ if (currency === "RUR" || currency === "RUB") {
15668
+ return `${this.asDecimal(normalizedValue, decimals)}${this.spaceSeparator}₽`;
15669
+ }
15670
+ if (this.intlSupport) {
15671
+ try {
15672
+ return Intl.NumberFormat(this.locale, {
15673
+ style: "currency",
15674
+ currency,
15675
+ currencyDisplay: "symbol",
15676
+ maximumFractionDigits: decimals,
15677
+ minimumFractionDigits: decimals,
15678
+ }).format(normalizedValue);
15679
+ }
15680
+ catch (e) {
15681
+ console.error(e);
15682
+ return String(normalizedValue);
15683
+ }
15684
+ }
15685
+ return currency + "&thinsp;" + this.asDecimal(normalizedValue, 2);
15686
+ }
15687
+ asShortSizeCasual(value, dp = 1) {
15688
+ if (value === undefined || value === null) {
15689
+ return this.nullDisplay;
15690
+ }
15691
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15692
+ if (normalizedValue === undefined || normalizedValue === null) {
15693
+ return this.nullDisplay;
15694
+ }
15695
+ const thresh = 1024;
15696
+ if (Math.abs(value) < thresh) {
15697
+ return value + " B";
15698
+ }
15699
+ const units = ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
15700
+ let u = -1;
15701
+ const r = 10 ** dp;
15702
+ do {
15703
+ value /= thresh;
15704
+ ++u;
15705
+ } while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);
15706
+ return value.toFixed(dp) + " " + units[u];
15707
+ }
15708
+ asShortSize(value, si = false, dp = 1) {
15709
+ if (value === undefined || value === null) {
15710
+ return this.nullDisplay;
15711
+ }
15712
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15713
+ if (normalizedValue === undefined || normalizedValue === null) {
15714
+ return this.nullDisplay;
15715
+ }
15716
+ const thresh = si ? 1000 : 1024;
15717
+ if (Math.abs(value) < thresh) {
15718
+ return value + " B";
15719
+ }
15720
+ const units = si ? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] : ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
15721
+ let u = -1;
15722
+ const r = 10 ** dp;
15723
+ do {
15724
+ value /= thresh;
15725
+ ++u;
15726
+ } while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);
15727
+ return value.toFixed(dp) + " " + units[u];
15728
+ }
15729
+ static numberFormat(value, decimals = 0, decimalSeparator = ".", thousandsSeparator) {
15730
+ const sign = value < 0 ? "-" : "";
15731
+ const sNumber = Math.abs(parseInt((+value || 0).toFixed(decimals))) + "";
15732
+ const len = sNumber.length;
15733
+ const tchunk = len > 3 ? len % 3 : 0;
15734
+ const chFirst = tchunk ? sNumber.substr(0, tchunk) + thousandsSeparator : "";
15735
+ const chRest = sNumber.substr(tchunk).replace(/(\d\d\d)(?=\d)/g, "$1" + thousandsSeparator);
15736
+ const chLast = decimals ? decimalSeparator + (Math.abs(value) - parseFloat(sNumber)).toFixed(decimals).slice(2) : "";
15737
+ return sign + chFirst + chRest + chLast;
15738
+ }
15739
+ get nullDisplay() {
15740
+ return "";
15741
+ // if (this.context && this.context.i18n) {
15742
+ // return this.context.i18n.t("notSet").toString();
15743
+ // }
15744
+ //
15745
+ // return "not set";
15746
+ }
15747
+ static normalizeDatetimeValue(value) {
15748
+ const type = typeof value;
15749
+ if (type === "object" && value instanceof Date) {
15750
+ return value;
15751
+ }
15752
+ else if (type === "number") {
15753
+ return new Date(value);
15754
+ }
15755
+ else if (type === "string") {
15756
+ if (isNaN(value)) {
15757
+ return new Date(parseInt(value));
15758
+ }
15759
+ else {
15760
+ const d = Date.parse(value);
15761
+ if (isNaN(d)) {
15762
+ return null;
15763
+ }
15764
+ return new Date(d);
15765
+ }
15766
+ }
15767
+ return null;
15768
+ }
15769
+ static normalizeNumericValue(value) {
15770
+ const type = typeof value;
15771
+ if ((type === "object" && value === null) || type === "undefined") {
15772
+ return 0;
15773
+ }
15774
+ else if (type === "number") {
15775
+ return value;
15776
+ }
15777
+ return parseFloat(value);
15778
+ }
15779
+ get locale() {
15780
+ return this.context.determineLocale();
15781
+ }
15782
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`{\n determineLocale: () => string;\n i18n: { t: (key: string) => string; tc: (key: string, value: string | number) => string } | undefined;\n }`]; }
15783
+ }
15784
+ const formatter = new Formatter({ determineLocale, i18n: undefined });
15785
+
15786
+ class SwipeGestureDetector {
15787
+ env;
15788
+ isScreenSupportsTouch;
15789
+ canContinueHandleDown;
15790
+ onStart;
15791
+ onUpdate;
15792
+ onEnd;
15793
+ constructor(env, isScreenSupportsTouch, canContinueHandleDown, onStart, onUpdate, onEnd) {
15794
+ this.env = env;
15795
+ this.isScreenSupportsTouch = isScreenSupportsTouch;
15796
+ this.canContinueHandleDown = canContinueHandleDown;
15797
+ this.onStart = onStart;
15798
+ this.onUpdate = onUpdate;
15799
+ this.onEnd = onEnd;
15800
+ // Store context
15801
+ this.handleDown = this.handleDown.bind(this);
15802
+ this.handleMove = this.handleMove.bind(this);
15803
+ this.handleEnd = this.handleEnd.bind(this);
15804
+ this.supportsTouch = false;
15805
+ if (this.isScreenSupportsTouch) {
15806
+ this.env.document.addEventListener("touchstart", this.handleDown, false);
15807
+ }
15808
+ else {
15809
+ this.env.document.addEventListener("mousedown", this.handleDown, false);
15810
+ }
15811
+ }
15812
+ startPageCoordinate = [0, 0];
15813
+ limit = Math.tan(((45 * 1.5) / 180) * Math.PI);
15814
+ pageWidth = window.innerWidth || document.body.clientWidth;
15815
+ threshold = Math.max(1, Math.floor(0.01 * this.pageWidth));
15816
+ supportsTouch = false;
15817
+ handleDown(e) {
15818
+ if (!this.canContinueHandleDown(e)) {
15819
+ return;
15820
+ }
15821
+ this.startPageCoordinate = this.getPageCoordinate(e);
15822
+ if (this.isScreenSupportsTouch) {
15823
+ this.env.document.addEventListener("touchmove", this.handleMove, false);
15824
+ this.env.document.addEventListener("touchend", this.handleEnd, false);
15825
+ }
15826
+ else {
15827
+ this.env.document.addEventListener("mousemove", this.handleMove, false);
15828
+ this.env.document.addEventListener("mouseup", this.handleEnd, false);
15829
+ }
15830
+ this.onStart(e);
15831
+ }
15832
+ handleMove(e) {
15833
+ // console.log("handleMove", { startPageCoordinate: this.startPageCoordinate})
15834
+ // this.currentPageCoordinate = this.getPageCoordinate(e);
15835
+ this.onUpdate(e);
15836
+ }
15837
+ handleEnd(e) {
15838
+ if (this.isScreenSupportsTouch) {
15839
+ this.env.document.removeEventListener("touchmove", this.handleMove);
15840
+ this.env.document.removeEventListener("touchend", this.handleEnd);
15841
+ }
15842
+ else {
15843
+ this.env.document.removeEventListener("mousemove", this.handleMove);
15844
+ this.env.document.removeEventListener("mouseup", this.handleEnd);
15845
+ }
15846
+ const currentPageCoordinate = this.getPageCoordinate(e);
15847
+ let gesture = 0 /* SwipeGesture.undefined */;
15848
+ const x = currentPageCoordinate[0] - this.startPageCoordinate[0];
15849
+ const y = currentPageCoordinate[1] - this.startPageCoordinate[1];
15850
+ // console.log("handleEnd", {currentPageCoordinate, startPageCoordinate: this.startPageCoordinate})
15851
+ let xy = Math.abs(x / y);
15852
+ let yx = Math.abs(y / x);
15853
+ if (Math.abs(x) > this.threshold || Math.abs(y) > this.threshold) {
15854
+ if (yx <= this.limit) {
15855
+ if (x < 0) {
15856
+ gesture = 4 /* SwipeGesture.SwipeLeft */;
15857
+ // @ts-ignore
15858
+ // _log(JSON.stringify({t: "SwipeLeft", yx, x, threshold: this.threshold}), true);
15859
+ }
15860
+ else {
15861
+ // @ts-ignore
15862
+ // _log(JSON.stringify({t: "SwipeRight", yx, x, threshold: this.threshold}), true);
15863
+ gesture = 5 /* SwipeGesture.SwipeRight */;
15864
+ }
15865
+ }
15866
+ if (xy <= this.limit) {
15867
+ if (y < 0) {
15868
+ // @ts-ignore
15869
+ // _log(JSON.stringify({t: "SwipeUp", xy, y, threshold: this.threshold}), true);
15870
+ gesture = 2 /* SwipeGesture.SwipeUp */;
15871
+ }
15872
+ else {
15873
+ // @ts-ignore
15874
+ // _log(JSON.stringify({t: "SwipeDown", xy, y, threshold: this.threshold}), true);
15875
+ gesture = 3 /* SwipeGesture.SwipeDown */;
15876
+ }
15877
+ }
15878
+ }
15879
+ else {
15880
+ // @ts-ignore
15881
+ // _log(JSON.stringify({t: "Tap", x, y, threshold: this.threshold}), true);
15882
+ gesture = 1 /* SwipeGesture.Tap */;
15883
+ }
15884
+ this.onEnd(e, gesture);
15885
+ }
15886
+ destroy() {
15887
+ if (this.isScreenSupportsTouch) {
15888
+ this.env.document.removeEventListener("touchstart", this.handleDown);
15889
+ }
15890
+ else {
15891
+ this.env.document.removeEventListener("mousedown", this.handleDown);
15892
+ }
15893
+ }
15894
+ getPageCoordinate(e) {
15895
+ let x = 0;
15896
+ let y = 0;
15897
+ if (e["clientX"] != null && e["clientY"] != null) {
15898
+ x = e["clientX"];
15899
+ y = e["clientY"];
15900
+ }
15901
+ else if (e.touches &&
15902
+ e.touches[0] &&
15903
+ e.touches[0]["clientX"] != null &&
15904
+ e.touches[0]["clientY"] != null) {
15905
+ x = e.touches[0]["clientX"];
15906
+ y = e.touches[0]["clientY"];
15907
+ }
15908
+ else if (e.changedTouches &&
15909
+ e.changedTouches[0] &&
15910
+ e.changedTouches[0]["clientX"] != null &&
15911
+ e.changedTouches[0]["clientY"] != null) {
15912
+ x = e.changedTouches[0]["clientX"];
15913
+ y = e.changedTouches[0]["clientY"];
15914
+ }
15915
+ // @ts-ignore
15916
+ else if (e.currentPoint && e.currentPoint["x"] != null && e.currentPoint["y"] != null) {
15917
+ // @ts-ignore
15918
+ x = e.currentPoint["x"];
15919
+ // @ts-ignore
15920
+ y = e.currentPoint["y"];
15921
+ }
15922
+ return [x, y];
15923
+ }
15924
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`Window`, `boolean`, `(e: MouseEvent | TouchEvent) => boolean`, `(e: MouseEvent | TouchEvent) => void`, `(e: MouseEvent | TouchEvent) => void`, `(e: MouseEvent | TouchEvent, gesture: SwipeGesture) => void`]; }
15925
+ }
15926
+
15927
+ /**
15928
+ * adult: null
15929
+ * availability: 1
15930
+ * coverUrl: "https://cdn.test.inappstory.com/np/file/cf/wb/wc/vcaji5clqon3nkwdwle3cjz63x.jpg?k=KgAAAAAAAAACAQ"
15931
+ * currency: "RUR"
15932
+ * description: "Непромокаемый комбинезон - дождевик детский Муссон"
15933
+ * id: 204
15934
+ * name: "Непромокаемый комбинезон - дождевик детский \"Муссон\""
15935
+ * offerId: "10125"
15936
+ * oldPrice: null
15937
+ * price: "2690.0000"
15938
+ * url: "http://www.songnomik.ru/products/detskaya-odezhda-optom-dlya-novorozhdennyh/detskie-kombinezony-optom/2166483.html"
15939
+ */
15940
+ class WidgetProducts extends WidgetBase {
15941
+ static DEFAULTS = {
15942
+ slide: null,
15943
+ activateAfterCreate: false,
15944
+ create: false,
15945
+ localData: {},
15946
+ };
15947
+ static widgetClassName = "narrative-element-products";
15948
+ captionView;
15949
+ linkTarget = [];
15950
+ msgNetworkError;
15951
+ msgServiceError;
15952
+ swipeGestureDetector = null;
15953
+ isClickCapturedByWidget = false;
15954
+ isScreenSupportsTouch = false;
15955
+ constructor(element, options) {
15956
+ super(element, options);
15957
+ this.captionView = this.element.querySelector(".narrative-element-text-lines");
15958
+ const linkTarget = decodeURIComponent(getTagData(element, "linkTarget") ?? "[]");
15959
+ try {
15960
+ let parsed = JSON.parse(linkTarget);
15961
+ if (Array.isArray(parsed)) {
15962
+ this.linkTarget = parsed.filter(FilterNumber);
15963
+ }
15964
+ }
15965
+ catch (e) {
15966
+ console.error(e);
15967
+ }
15968
+ this.isScreenSupportsTouch = isScreenSupportsTouch(this.env);
15969
+ this.msgNetworkError = getTagData(this.element, "msgNetworkError");
15970
+ this.msgServiceError = getTagData(this.element, "msgServiceError");
15971
+ }
15972
+ /**
15973
+ * Start or restart widget
15974
+ * @param localData
15975
+ */
15976
+ onRefreshUserData(localData) {
15977
+ super.onRefreshUserData(localData);
15978
+ }
15979
+ onStart() {
15980
+ super.onStart();
15981
+ // reinit for case when we returned to slide from other slide and onStop destroyed SwipeGestureDetector
15982
+ this.initSwipeGestureDetector();
15983
+ }
15984
+ isTransparentElement() {
15985
+ if (this.element) {
15986
+ try {
15987
+ const color = window.getComputedStyle(this.element).color;
15988
+ if (color === "transparent" || color === "rgba(0, 0, 0, 0)" || color === "rgba(0,0,0,0)") {
15989
+ return true;
15990
+ }
15991
+ }
15992
+ catch (err) {
15993
+ console.error(err);
15994
+ }
15995
+ }
15996
+ return false;
15997
+ }
15998
+ _statEventWidgetClick() {
15999
+ try {
16000
+ const captionViewText = this.captionView?.textContent ?? "";
16001
+ this.sendStatisticEventToApp("w-products-click", {
16002
+ ...this.statisticEventBaseFieldsShortForm,
16003
+ wi: this.elementId,
16004
+ wl: captionViewText,
16005
+ wv: this.linkTarget,
16006
+ }, {
16007
+ ...this.statisticEventBaseFieldsShortForm,
16008
+ widget_id: this.elementId,
16009
+ widget_label: captionViewText,
16010
+ widget_value: this.linkTarget,
16011
+ }, {
16012
+ forceEnableStatisticV2: true,
16013
+ });
16014
+ }
16015
+ catch (error) {
16016
+ console.error(error);
16017
+ }
16018
+ }
16019
+ _statEventWidgetOpen(offers) {
16020
+ try {
16021
+ const captionViewText = this.captionView?.textContent ?? "";
16022
+ this.sendStatisticEventToApp("w-products-open", {
16023
+ ...this.statisticEventBaseFieldsShortForm,
16024
+ wi: this.elementId,
16025
+ wl: captionViewText,
16026
+ wv: this.linkTarget,
16027
+ wit: offers.map(item => item.offerId),
16028
+ }, {
16029
+ ...this.statisticEventBaseFieldsShortForm,
16030
+ widget_id: this.elementId,
16031
+ widget_label: captionViewText,
16032
+ widget_value: this.linkTarget,
16033
+ widget_items: offers.map(item => item.offerId),
16034
+ }, {
16035
+ forceEnableStatisticV2: true,
16036
+ });
16037
+ }
16038
+ catch (error) {
16039
+ console.error(error);
16040
+ }
16041
+ }
16042
+ _statEventWidgetCardClick(offer) {
16043
+ try {
16044
+ const captionViewText = this.captionView?.textContent ?? "";
16045
+ this.sendStatisticEventToApp("w-products-card-click", {
16046
+ ...this.statisticEventBaseFieldsShortForm,
16047
+ wi: this.elementId,
16048
+ wl: captionViewText,
16049
+ wv: offer.offerId,
16050
+ wvi: offer.id,
16051
+ }, {
16052
+ ...this.statisticEventBaseFieldsShortForm,
16053
+ widget_id: this.elementId,
16054
+ widget_label: captionViewText,
16055
+ widget_value: offer.offerId,
16056
+ widget_value_id: offer.id,
16057
+ }, {
16058
+ forceEnableStatisticV2: true,
16059
+ });
16060
+ }
16061
+ catch (error) {
16062
+ console.error(error);
16063
+ }
16064
+ }
16065
+ async fetchProducts() {
16066
+ const fetchAndCacheMedia = async () => {
16067
+ if (!this.linkTarget.length) {
16068
+ return { message: this.msgServiceError ?? "", models: [] };
16069
+ }
16070
+ const path = `product/offer?id=${this.linkTarget.join(",")}`;
16071
+ const headers = {
16072
+ accept: "application/json",
16073
+ "Content-Type": "application/json",
16074
+ };
16075
+ const profileKey = "fetch-products";
16076
+ try {
16077
+ const response = await this.sdkApi.sendApiRequest(path, "GET", null, headers, null, profileKey);
16078
+ // console.log({response});
16079
+ const status = response.status;
16080
+ if (status === 200 || status === 201) {
16081
+ if (response.data && Array.isArray(response.data) && response.data.length > 0) {
16082
+ try {
16083
+ await this.cacheOffersMediaResources(response.data);
16084
+ }
16085
+ catch (error) {
16086
+ console.error(error);
16087
+ }
16088
+ return { message: "", models: response.data };
16089
+ }
16090
+ else {
16091
+ return { message: this.msgServiceError ?? "", models: [] };
16092
+ }
16093
+ }
16094
+ else if (status === 12163 || status === 12002) {
16095
+ return { message: this.msgNetworkError ?? "", models: [] };
16096
+ }
16097
+ else {
16098
+ return { message: this.msgServiceError ?? "", models: [] };
16099
+ }
16100
+ }
16101
+ catch (error) {
16102
+ console.error(error);
16103
+ return { message: this.msgServiceError ?? "", models: [] };
16104
+ }
16105
+ };
16106
+ return Promise.all([
16107
+ fetchAndCacheMedia(),
16108
+ new Promise(t => {
16109
+ return setTimeout(t, 200);
16110
+ }),
16111
+ ]).then(([result]) => result);
16112
+ }
16113
+ cacheOffersMediaResources(offers) {
16114
+ const cacheItem = (offer) => {
16115
+ return new Promise(resolve => {
16116
+ if (offer.coverUrl != null) {
16117
+ this.env
16118
+ .fetch(offer.coverUrl)
16119
+ .then(response => {
16120
+ if (response != null && response.ok) {
16121
+ response
16122
+ .blob()
16123
+ .then(blob => {
16124
+ offer.coverUrl = URL.createObjectURL(blob);
16125
+ resolve();
16126
+ })
16127
+ .catch(resolve);
16128
+ }
16129
+ else {
16130
+ resolve();
16131
+ }
16132
+ })
16133
+ .catch(resolve);
16134
+ }
16135
+ else {
16136
+ resolve();
16137
+ }
16138
+ });
16139
+ };
16140
+ const promises = offers.map(cacheItem);
16141
+ return Promise.all(promises);
16142
+ }
16143
+ revokeOffersMediaResources(offers) {
16144
+ offers.forEach(offer => {
16145
+ if (offer.coverUrl != null) {
16146
+ // todo check if coverUrl really is object URL
16147
+ URL.revokeObjectURL(offer.coverUrl);
16148
+ }
16149
+ });
16150
+ }
16151
+ initSwipeGestureDetector() {
16152
+ if (this.isOpen) {
16153
+ this.swipeGestureDetector = new SwipeGestureDetector(this.env, this.isScreenSupportsTouch, () => true, e => {
16154
+ // this.isClickCapturedByWidget = true;
16155
+ return;
16156
+ }, e => {
16157
+ return;
16158
+ }, (e, gesture) => {
16159
+ if (gesture === 3 /* SwipeGesture.SwipeDown */) {
16160
+ this.closeProductsView();
16161
+ }
16162
+ // this.env.requestAnimationFrame(() => {
16163
+ // this.isClickCapturedByWidget = false;
16164
+ // });
16165
+ });
16166
+ }
16167
+ }
16168
+ productsView = null;
16169
+ isOpen = false;
16170
+ currentModels = [];
16171
+ async openProductsView() {
16172
+ if (this.isOpen) {
16173
+ return;
16174
+ }
16175
+ this._statEventWidgetClick();
16176
+ if (!this.disableTimer) {
16177
+ this.sdkApi.pauseUI();
16178
+ }
16179
+ if (!this.isTransparentElement()) {
16180
+ this.element.classList.add("loader");
16181
+ }
16182
+ // const start = window.performance.now();
16183
+ const result = await this.fetchProducts();
16184
+ // @ts-ignore
16185
+ // _log(`fetched for ${window.performance.now() - start}ms`, true);
16186
+ // console.log({result})
16187
+ if (result.models.length > 0) {
16188
+ this.currentModels = result.models;
16189
+ this.productsView = this.createProductsView(this.currentModels, this.closeProductsView.bind(this));
16190
+ this.productsView.classList.add("ias-products-container-view--visible");
16191
+ this.slide.appendChild(this.productsView);
16192
+ this.element.classList.add("hidden");
16193
+ this.isOpen = true;
16194
+ // prevent next slide navigation gesture
16195
+ this.isClickCapturedByWidget = true;
16196
+ this.sdkApi.disableVerticalSwipeGesture();
16197
+ this.sdkApi.disableBackpress();
16198
+ this._statEventWidgetOpen(this.currentModels);
16199
+ this.initSwipeGestureDetector();
16200
+ }
16201
+ else {
16202
+ if (result.message) {
16203
+ this.sdkApi.showToast(result.message);
16204
+ }
16205
+ }
16206
+ this.element.classList.remove("loader");
16207
+ }
16208
+ closeProductsView() {
16209
+ if (!this.isOpen) {
16210
+ return;
16211
+ }
16212
+ this.productsView?.classList.add("ias-products-container-view--hidden");
16213
+ this.element.classList.remove("hidden");
16214
+ this.isClickCapturedByWidget = false;
16215
+ if (this.swipeGestureDetector != null) {
16216
+ this.swipeGestureDetector.destroy();
16217
+ }
16218
+ this.sdkApi.enableVerticalSwipeGesture();
16219
+ this.sdkApi.enableBackpress();
16220
+ const onClosed = () => {
16221
+ this.productsView?.removeEventListener("animationend", onClosed);
16222
+ this.productsView?.parentElement?.removeChild(this.productsView);
16223
+ this.revokeOffersMediaResources(this.currentModels);
16224
+ if (!this.disableTimer) {
16225
+ this.sdkApi.resumeUI();
16226
+ }
16227
+ this.isOpen = false;
16228
+ this.currentModels = [];
16229
+ };
16230
+ this.productsView?.addEventListener("animationend", onClosed);
16231
+ }
16232
+ createCardView(offer) {
16233
+ const figure = document.createElement("div");
16234
+ figure.classList.add("ias-products-card-figure");
16235
+ if (offer.coverUrl) {
16236
+ // todo preload coverImage by fetch, save to offer.coverUrl via createUrl (add revoke)
16237
+ // if cannot fetch - skip caching
16238
+ const image = document.createElement("img");
16239
+ image.classList.add("ias-products-card-figure-image");
16240
+ image.alt = offer.name ?? "";
16241
+ image.src = offer.coverUrl;
16242
+ figure.appendChild(image);
16243
+ }
16244
+ // const subTitle = document.createElement("div");
16245
+ // subTitle.classList.add("ias-products-card-subtitle");
16246
+ // subTitle.innerText = offer.description ?? "";
16247
+ const title = document.createElement("div");
16248
+ title.classList.add("ias-products-card-title");
16249
+ title.innerText = offer.name ?? "";
16250
+ let price = null;
16251
+ if (offer.price) {
16252
+ price = document.createElement("div");
16253
+ price.classList.add("ias-products-card-price");
16254
+ price.innerHTML = formatter.asCurrency(offer.price, offer.currency);
16255
+ }
16256
+ let oldPrice = null;
16257
+ if (offer.oldPrice) {
16258
+ oldPrice = document.createElement("div");
16259
+ oldPrice.classList.add("ias-products-card-old-price");
16260
+ oldPrice.innerHTML = formatter.asCurrency(offer.oldPrice, offer.currency);
16261
+ }
16262
+ const prices = document.createElement("div");
16263
+ prices.classList.add("ias-products-card-prices");
16264
+ if (price) {
16265
+ prices.appendChild(price);
16266
+ }
16267
+ if (oldPrice) {
16268
+ prices.appendChild(oldPrice);
16269
+ }
16270
+ const card = document.createElement("div");
16271
+ card.classList.add("ias-products-card");
16272
+ card.onclick = () => {
16273
+ this._statEventWidgetCardClick(offer);
16274
+ if (offer.url) {
16275
+ this.sdkApi.openUrl(offer.url);
16276
+ }
16277
+ };
16278
+ card.appendChild(figure);
16279
+ // card.appendChild(subTitle);
16280
+ card.appendChild(prices);
16281
+ card.appendChild(title);
16282
+ return card;
16283
+ }
16284
+ createScrollView(offers) {
16285
+ const scrollView = document.createElement("div");
16286
+ scrollView.classList.add("ias-products-scroll-view");
16287
+ offers.forEach(offer => scrollView.appendChild(this.createCardView(offer)));
16288
+ return scrollView;
16289
+ }
16290
+ createProductsView(offers, onClose) {
16291
+ const containerView = document.createElement("div");
16292
+ containerView.classList.add("ias-products-container-view");
16293
+ const backdropView = document.createElement("div");
16294
+ backdropView.classList.add("ias-products-container-backdrop-view");
16295
+ backdropView.onclick = e => {
16296
+ e.preventDefault();
16297
+ e.stopPropagation();
16298
+ onClose();
16299
+ };
16300
+ const backgroundView = document.createElement("div");
16301
+ backgroundView.classList.add("ias-products-container-background-view");
16302
+ const scrollView = this.createScrollView(offers);
16303
+ const closeButton = document.createElement("div");
16304
+ closeButton.classList.add("ias-products-container-close-button");
16305
+ // fill=${ProductsWidgetOptionsDefault.productsList.closeBackgroundColor}
16306
+ closeButton.innerHTML = `<svg width="32" height="12.5" viewBox="0 0 64 25" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M56.293 1.23375C58.054 -0.41125 60.846 -0.41125 62.607 1.23375C64.464 2.96775 64.464 5.85675 62.607 7.59075L35.157 23.2288C33.396 24.8738 30.604 24.8738 28.843 23.2288L1.393 7.59075C0.494002 6.75175 0 5.62775 0 4.41275C0 3.19775 0.494002 2.07375 1.393 1.23475C3.154 -0.410251 5.946 -0.410251 7.707 1.23475L32 13.9237L56.293 1.23375Z" fill="currentColor" /></svg>`;
16307
+ closeButton.onclick = e => {
16308
+ e.preventDefault();
16309
+ e.stopPropagation();
16310
+ onClose();
16311
+ };
16312
+ backgroundView.appendChild(scrollView);
16313
+ backgroundView.appendChild(closeButton);
16314
+ containerView.appendChild(backdropView);
16315
+ containerView.appendChild(backgroundView);
16316
+ return containerView;
16317
+ }
16318
+ getIsClickCapturedByWidget() {
16319
+ return this.isClickCapturedByWidget;
16320
+ }
16321
+ destroy() {
16322
+ if (this.swipeGestureDetector != null) {
16323
+ this.swipeGestureDetector.destroy();
16324
+ this.swipeGestureDetector = null;
16325
+ }
16326
+ }
16327
+ onStop() {
16328
+ super.onStop();
16329
+ this.destroy();
16330
+ }
16331
+ static api = {
16332
+ widgetClassName: WidgetProducts.widgetClassName,
16333
+ onRefreshUserData: WidgetProducts.onRefreshUserData,
16334
+ init: function (element, localData) {
16335
+ WidgetProducts.initWidget(element, localData, (element, options) => new WidgetProducts(element, options));
16336
+ },
16337
+ onStart: function (element) {
16338
+ WidgetProducts.getInstance(element)?.onStart();
16339
+ },
16340
+ onStop: function (element) {
16341
+ WidgetProducts.getInstance(element)?.onStop();
16342
+ },
16343
+ click: function (element) {
16344
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16345
+ if (widgetElement) {
16346
+ const widget = WidgetProducts.getInstance(widgetElement);
16347
+ if (widget) {
16348
+ widget.openProductsView();
16349
+ }
16350
+ }
16351
+ return false;
16352
+ },
16353
+ isClickCapturedByWidget: function (element) {
16354
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16355
+ if (widgetElement) {
16356
+ const widget = WidgetProducts.getInstance(widgetElement);
16357
+ if (widget) {
16358
+ return widget.getIsClickCapturedByWidget();
16359
+ }
16360
+ }
16361
+ return false;
16362
+ },
16363
+ onHandleBackpress: function (element) {
16364
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16365
+ if (widgetElement) {
16366
+ const widget = WidgetProducts.getInstance(widgetElement);
16367
+ if (widget) {
16368
+ widget.closeProductsView();
16369
+ }
16370
+ }
16371
+ return false;
16372
+ },
16373
+ };
16374
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`]; }
16375
+ }
16376
+
15285
16377
  let sdkInterface;
15286
16378
  const getSlideApi = (_sdkInterface) => {
15287
16379
  sdkInterface = _sdkInterface;
@@ -15302,6 +16394,7 @@ const getSlideApi = (_sdkInterface) => {
15302
16394
  WidgetTest: WidgetTest.api,
15303
16395
  WidgetVote: WidgetVote.api,
15304
16396
  WidgetBarcode: WidgetBarcode.api,
16397
+ WidgetProducts: WidgetProducts.api,
15305
16398
  };
15306
16399
  };
15307
16400