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