@inappstory/slide-api 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -211,6 +211,29 @@ class WidgetsService {
211
211
 
212
212
  container.registerSingleton(undefined, { identifier: `WidgetsService`, implementation: WidgetsService });
213
213
 
214
+ class LayoutService {
215
+ _env;
216
+ _sdkApi;
217
+ _layoutApi;
218
+ constructor(_env, _sdkApi, _layoutApi) {
219
+ this._env = _env;
220
+ this._sdkApi = _sdkApi;
221
+ this._layoutApi = _layoutApi;
222
+ }
223
+ get env() {
224
+ return this._env;
225
+ }
226
+ get sdkApi() {
227
+ return this._sdkApi;
228
+ }
229
+ get layoutApi() {
230
+ return this._layoutApi;
231
+ }
232
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`Window`, `SDKApi`, `ILayoutApi`]; }
233
+ }
234
+
235
+ container.registerSingleton(undefined, { identifier: `LayoutService`, implementation: LayoutService });
236
+
214
237
  // import '../adapters/dateTimeSource/composition';
215
238
  // import '../adapters/uuidGenerator/composition';
216
239
  // import '../effects/eventHandler/composition';
@@ -218,6 +241,8 @@ container.registerSingleton(undefined, { identifier: `WidgetsService`, implement
218
241
  // import '../effects/timer/composition';
219
242
  container.registerSingleton(() => window, { identifier: `Window` });
220
243
 
244
+ const DEFAULT_SLIDE_DURATION = 10000;
245
+
221
246
  const arPrototype = Array.prototype;
222
247
  const obPrototype = Object.prototype;
223
248
  const slice = arPrototype.slice;
@@ -542,9 +567,6 @@ class Data {
542
567
  }
543
568
  // var data_priv = new Data();
544
569
  const data_user = new Data();
545
- const getSlideDuration = function (sdkApi, storyId, slideIndex) {
546
- return sdkApi.getSlideDuration(storyId, slideIndex) ?? 10000;
547
- };
548
570
  const getWinWidth = function (env) {
549
571
  return env.innerWidth || env.document.documentElement.clientWidth || env.document.body.clientWidth;
550
572
  };
@@ -1130,6 +1152,18 @@ class EsModuleSdkApi {
1130
1152
  getStorySessionValue(element, key) {
1131
1153
  return this.sdkBinding().getStorySessionValue(key);
1132
1154
  }
1155
+ updateTimeline(slideIndex, action, currentTime, duration, showLoader, showError) {
1156
+ this.sdkBinding().updateTimeline(slideIndex, action, currentTime, duration, showLoader, showError);
1157
+ }
1158
+ storyPausedCallback(currentTime) { }
1159
+ storyResumedCallback(currentTime) { }
1160
+ startDisabledTimeline(storyId, slideIndex) {
1161
+ // old api
1162
+ this.showNextSlide(this.getSlideDuration(storyId, slideIndex) ?? DEFAULT_SLIDE_DURATION);
1163
+ }
1164
+ getStoryFonts() {
1165
+ return this.sdkBinding().getStoryFonts();
1166
+ }
1133
1167
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`() => SDKInterface`]; }
1134
1168
  }
1135
1169
 
@@ -1308,8 +1342,8 @@ class WidgetBase {
1308
1342
  sendStatisticEventToApp(name, data, devPayload) {
1309
1343
  this.constructor.sendStatisticEventToApp(name, data, devPayload);
1310
1344
  }
1311
- showNextSlide() {
1312
- this.sdkApi.showNextSlide(getSlideDuration(this.sdkApi, this.storyId, this.slideIndex));
1345
+ startDisabledTimeline() {
1346
+ this.sdkApi.startDisabledTimeline(this.storyId, this.slideIndex);
1313
1347
  }
1314
1348
  _showLayout(layers, selectIndex, withStatEvent = false) {
1315
1349
  if (this.sdkApi.isExistsShowLayer()) {
@@ -1546,7 +1580,7 @@ class WidgetCopy extends WidgetBase {
1546
1580
  // флаг - что таймер уже стартанул (в layout или добавить объект sharedMemory)
1547
1581
  // смотрим что прозрачный текст - тогда и лоадер прозрачный
1548
1582
  // _log("_showNarrativeNextSlide: " + getSlideDuration(this.narrativeId, this.slideIndex), true);
1549
- this.showNextSlide();
1583
+ this.startDisabledTimeline();
1550
1584
  }
1551
1585
  }
1552
1586
  copyToClipboard(element) {
@@ -1566,6 +1600,7 @@ class WidgetCopy extends WidgetBase {
1566
1600
  return this.localData["_cp_g_" + this.elementId + "_done_at"] !== undefined;
1567
1601
  }
1568
1602
  static api = {
1603
+ widgetClassName: WidgetCopy.widgetClassName,
1569
1604
  refreshUserData: WidgetCopy.refreshUserData,
1570
1605
  initWidget: function (nodeList, localData) {
1571
1606
  // prevent initWidget for result layer
@@ -1630,7 +1665,7 @@ class WidgetDataInput extends WidgetBase {
1630
1665
  if (text) {
1631
1666
  this.element.classList.add("done");
1632
1667
  if (this.disableTimer) {
1633
- this.showNextSlide();
1668
+ this.startDisabledTimeline();
1634
1669
  }
1635
1670
  }
1636
1671
  }
@@ -1747,10 +1782,8 @@ class WidgetDataInput extends WidgetBase {
1747
1782
  this.setLocalData(this.localData, true);
1748
1783
  this._statEventInputSave(text);
1749
1784
  if (this.disableTimer) {
1750
- if ("_showNarrativeNextSlide" in window) {
1751
- this.showNextSlide();
1752
- needResumeUITimer = false;
1753
- }
1785
+ this.startDisabledTimeline();
1786
+ needResumeUITimer = false;
1754
1787
  }
1755
1788
  }
1756
1789
  if (needResumeUITimer && !this.disableTimer) {
@@ -1758,6 +1791,7 @@ class WidgetDataInput extends WidgetBase {
1758
1791
  }
1759
1792
  }
1760
1793
  static api = {
1794
+ widgetClassName: WidgetDataInput.widgetClassName,
1761
1795
  refreshUserData: WidgetDataInput.refreshUserData,
1762
1796
  initWidget: function (nodeList, localData) {
1763
1797
  WidgetDataInput.initWidgets((element, options) => new WidgetDataInput(element, options), slice.call(nodeList), localData);
@@ -1971,6 +2005,7 @@ class WidgetDateCountdown extends WidgetBase {
1971
2005
  return result;
1972
2006
  }
1973
2007
  static api = {
2008
+ widgetClassName: WidgetDateCountdown.widgetClassName,
1974
2009
  refreshUserData: WidgetDateCountdown.refreshUserData,
1975
2010
  initWidget: function (nodeList, layers, localData) {
1976
2011
  WidgetDateCountdown.initWidgets((element, options) => new WidgetDateCountdown(element, { ...options, layers }), slice.call(nodeList), localData);
@@ -2261,7 +2296,7 @@ class WidgetPoll extends WidgetBase {
2261
2296
  // todo poll - если виджет на первом слайде то при повторном заходе автоматически не стартует таймлайн слайда
2262
2297
  // только в web sdk такое
2263
2298
  // если поставить через setTimeout то все ок
2264
- this.showNextSlide();
2299
+ this.startDisabledTimeline();
2265
2300
  });
2266
2301
  }
2267
2302
  }
@@ -2599,6 +2634,7 @@ class WidgetPoll extends WidgetBase {
2599
2634
  return this.localData["_p_g_" + this.elementId + "_sa"] !== undefined;
2600
2635
  }
2601
2636
  static api = {
2637
+ widgetClassName: WidgetPoll.widgetClassName,
2602
2638
  refreshUserData: WidgetPoll.refreshUserData,
2603
2639
  initWidget: function (element, localData) {
2604
2640
  WidgetPoll.initWidgets((element, options) => new WidgetPoll(element, options), [element], localData);
@@ -2727,7 +2763,7 @@ class WidgetPollLayers extends WidgetBase {
2727
2763
  }
2728
2764
  this._showLayout(this.layers, layerIndex, userAction);
2729
2765
  if (this.disableTimer) {
2730
- this.showNextSlide();
2766
+ this.startDisabledTimeline();
2731
2767
  }
2732
2768
  }
2733
2769
  selectVariant(variant) {
@@ -2764,6 +2800,7 @@ class WidgetPollLayers extends WidgetBase {
2764
2800
  return this.localData != null && this.localData["_pl_g_" + this.elementId + "_sa"] !== undefined;
2765
2801
  }
2766
2802
  static api = {
2803
+ widgetClassName: WidgetPollLayers.widgetClassName,
2767
2804
  refreshUserData: WidgetPollLayers.refreshUserData,
2768
2805
  // signature variants
2769
2806
  // (widget, layers, undefined) - modern web sdk
@@ -3047,6 +3084,7 @@ class WidgetQuest extends WidgetBase {
3047
3084
  }
3048
3085
  }
3049
3086
  static api = {
3087
+ widgetClassName: WidgetQuest.widgetClassName,
3050
3088
  refreshUserData: WidgetQuest.refreshUserData,
3051
3089
  initWidget: function (element, localData) {
3052
3090
  return new Promise(function (resolve, reject) {
@@ -3153,7 +3191,7 @@ class WidgetQuiz extends WidgetBase {
3153
3191
  // })
3154
3192
  // }
3155
3193
  if (this.disableTimer) {
3156
- this.showNextSlide();
3194
+ this.startDisabledTimeline();
3157
3195
  }
3158
3196
  }
3159
3197
  _clearAnswerSelection() {
@@ -3245,6 +3283,7 @@ class WidgetQuiz extends WidgetBase {
3245
3283
  return this.localData["_q_g_" + this.elementId + "_sa"] !== undefined;
3246
3284
  }
3247
3285
  static api = {
3286
+ widgetClassName: WidgetQuiz.widgetClassName,
3248
3287
  refreshUserData: WidgetQuiz.refreshUserData,
3249
3288
  initWidget: function (element, localData) {
3250
3289
  WidgetQuiz.initWidgets((element, options) => new WidgetQuiz(element, options), [element], localData);
@@ -3330,7 +3369,7 @@ class WidgetQuizGrouped extends WidgetBase {
3330
3369
  }
3331
3370
  });
3332
3371
  if (this.disableTimer) {
3333
- this.showNextSlide();
3372
+ this.startDisabledTimeline();
3334
3373
  }
3335
3374
  }
3336
3375
  _clearAnswerSelection() {
@@ -3439,6 +3478,7 @@ class WidgetQuizGrouped extends WidgetBase {
3439
3478
  return this.localData["_q_gg_" + this.elementId + "_sa"] !== undefined;
3440
3479
  }
3441
3480
  static api = {
3481
+ widgetClassName: WidgetQuizGrouped.widgetClassName,
3442
3482
  refreshUserData: WidgetQuizGrouped.refreshUserData,
3443
3483
  initWidget: function (element, localData) {
3444
3484
  WidgetQuizGrouped.initWidgets((element, options) => new WidgetQuizGrouped(element, options), [element], localData);
@@ -3691,7 +3731,7 @@ class WidgetRangeSlider extends WidgetBase {
3691
3731
  this.element.classList.add("done");
3692
3732
  this.displayAverageAnswer();
3693
3733
  if (this.disableTimer) {
3694
- this.showNextSlide();
3734
+ this.startDisabledTimeline();
3695
3735
  }
3696
3736
  }
3697
3737
  else {
@@ -3760,7 +3800,7 @@ class WidgetRangeSlider extends WidgetBase {
3760
3800
  }
3761
3801
  });
3762
3802
  // if (this.disableTimer) {
3763
- this.showNextSlide();
3803
+ this.startDisabledTimeline();
3764
3804
  // }
3765
3805
  this.setLocalData(this.localData, true);
3766
3806
  this._statEventInputSave(this.localData["_rs_g_" + this.elementId + "_v"]);
@@ -4048,6 +4088,7 @@ class WidgetRangeSlider extends WidgetBase {
4048
4088
  // .removeData('plugin_' + pluginName);
4049
4089
  }
4050
4090
  static api = {
4091
+ widgetClassName: WidgetRangeSlider.widgetClassName,
4051
4092
  refreshUserData: WidgetRangeSlider.refreshUserData,
4052
4093
  initWidget: function (element, localData) {
4053
4094
  WidgetRangeSlider.initWidgets((element, options) => new WidgetRangeSlider(element, options), [element], localData);
@@ -4172,7 +4213,7 @@ class WidgetRate extends WidgetBase {
4172
4213
  this.localData["_r_g_" + this.elementId + "_ss"] = value;
4173
4214
  this.element.classList.add("done");
4174
4215
  if (this.disableTimer && runTimer) {
4175
- this.showNextSlide();
4216
+ this.startDisabledTimeline();
4176
4217
  }
4177
4218
  }
4178
4219
  _clearSelectedStar() {
@@ -4296,6 +4337,7 @@ class WidgetRate extends WidgetBase {
4296
4337
  return this.localData["_r_g_" + this.elementId + "_sa"] !== undefined;
4297
4338
  }
4298
4339
  static api = {
4340
+ widgetClassName: WidgetRate.widgetClassName,
4299
4341
  refreshUserData: WidgetRate.refreshUserData,
4300
4342
  initWidget: function (nodeList, localData) {
4301
4343
  WidgetRate.initWidgets((element, options) => new WidgetRate(element, options), slice.call(nodeList), localData);
@@ -4418,6 +4460,7 @@ class WidgetShare extends WidgetBase {
4418
4460
  return Boolean(this.localData["_s_" + this.elementId + "_ts"]);
4419
4461
  }
4420
4462
  static api = {
4463
+ widgetClassName: WidgetShare.widgetClassName,
4421
4464
  refreshUserData: WidgetShare.refreshUserData,
4422
4465
  // signature variants
4423
4466
  // (widget, layers, undefined) - modern web sdk
@@ -4537,6 +4580,11 @@ class WidgetTest extends WidgetBase {
4537
4580
  this.timeline.style.transform = "translateX(100%)";
4538
4581
  }
4539
4582
  }
4583
+ else if (this.localData["_&ts_t_g_" + this.elementId + "_a_tspent"] != null) {
4584
+ if (this.timeline) {
4585
+ this.timeline.style.transform = "translateX(" + String(this.localData["_&ts_t_g_" + this.elementId + "_a_tspent"]) + "%)";
4586
+ }
4587
+ }
4540
4588
  }
4541
4589
  }
4542
4590
  // this.refreshUserData(this.options.localData);
@@ -4592,7 +4640,7 @@ class WidgetTest extends WidgetBase {
4592
4640
  }
4593
4641
  });
4594
4642
  if (this.disableTimer) {
4595
- this.showNextSlide();
4643
+ this.startDisabledTimeline();
4596
4644
  }
4597
4645
  }
4598
4646
  selectAnswer(answer) {
@@ -4636,6 +4684,10 @@ class WidgetTest extends WidgetBase {
4636
4684
  }
4637
4685
  // answer on question
4638
4686
  this.localData["_&ts_t_g_" + this.elementId + "_a_at"] = Math.round(new Date().getTime() / 1000);
4687
+ // spent percent of time
4688
+ if (this.slideTestWithTimer()) {
4689
+ this.localData["_&ts_t_g_" + this.elementId + "_a_tspent"] = Math.round((1 - this.timeLeft / this.timeLeftDefault) * 100);
4690
+ }
4639
4691
  if (this.widgetDone) {
4640
4692
  this.widgetDone.classList.add("active", "opacity-active");
4641
4693
  setTimeout(() => {
@@ -4658,6 +4710,7 @@ class WidgetTest extends WidgetBase {
4658
4710
  return Boolean(this.withTimeToAnswer && this.answerTimeout);
4659
4711
  }
4660
4712
  static api = {
4713
+ widgetClassName: WidgetTest.widgetClassName,
4661
4714
  refreshUserData: WidgetTest.refreshUserData,
4662
4715
  initWidget: function (element, localData) {
4663
4716
  WidgetTest.initWidgets((element, options) => new WidgetTest(element, options), [element], localData);
@@ -4711,6 +4764,7 @@ class WidgetVote extends WidgetBase {
4711
4764
  selectedVariant;
4712
4765
  voteAllocation;
4713
4766
  hideClientTotalResult;
4767
+ multipleChoice;
4714
4768
  /**
4715
4769
  * @throws Error
4716
4770
  * @param element
@@ -4729,38 +4783,112 @@ class WidgetVote extends WidgetBase {
4729
4783
  }
4730
4784
  });
4731
4785
  this.hideClientTotalResult = getValueOrDefault(Boolean(getTagDataAsNumber(this.element, "hideClientTotalResult")), false);
4786
+ this.multipleChoice = getValueOrDefault(Boolean(getTagDataAsNumber(this.element, "multipleChoice")), false);
4787
+ this.refreshUserData(this.options.localData);
4788
+ }
4789
+ _initFromLocalData() {
4790
+ const value = this.localData["_v_g_" + this.elementId + "_sa"];
4791
+ if (!this.multipleChoice) {
4792
+ let index = value;
4793
+ if (Array.isArray(value)) {
4794
+ index = value[0];
4795
+ }
4796
+ this._checkVariant(index);
4797
+ this._selectVariant(index, true);
4798
+ if (!this.hideClientTotalResult) {
4799
+ this.displayPercents([index], true);
4800
+ }
4801
+ this._fillWidget(true);
4802
+ }
4803
+ if (this.multipleChoice) {
4804
+ let values = [];
4805
+ if (Array.isArray(value)) {
4806
+ values = value;
4807
+ }
4808
+ else {
4809
+ values.push(value);
4810
+ }
4811
+ for (let i = 0; i < values.length; ++i) {
4812
+ const index = values[i];
4813
+ this._checkVariant(index);
4814
+ this._selectVariant(index, true);
4815
+ }
4816
+ if (!this.hideClientTotalResult) {
4817
+ this.displayPercents(values, true);
4818
+ }
4819
+ this._fillWidget(true);
4820
+ }
4821
+ }
4822
+ refreshUserData(localData) {
4823
+ this.savedData = this.sdkApi.getStoryServerData(this.storyId);
4824
+ this.localData = extend({}, this.savedData ?? {}, localData);
4732
4825
  this.selectedVariant = undefined;
4733
4826
  if (this.localData) {
4734
- if (this.localData["_v_g_" + this.elementId + "_sa"] !== undefined) {
4735
- this._selectVariant(this.localData["_v_g_" + this.elementId + "_sa"], true);
4827
+ if (this.localData["_v_g_" + this.elementId + "_sa"] != null) {
4828
+ this._initFromLocalData();
4829
+ }
4830
+ else {
4831
+ this._clearSelectedVariants();
4832
+ this.element.classList.remove("done");
4833
+ this.element.classList.remove("input-done");
4834
+ this.element.classList.remove("filled");
4736
4835
  }
4737
4836
  }
4738
4837
  this.firstOpenTime = new Date().getTime();
4739
- // this.refreshUserData(this.options.localData);
4740
4838
  }
4741
- refreshUserData(localData) { }
4839
+ _clearSelectedVariants() {
4840
+ this.variants.forEach((variant, index) => {
4841
+ variant.classList.remove("checked");
4842
+ variant.classList.remove("selected");
4843
+ variant.style.setProperty("--selected-variant-view-clip-area", String(100));
4844
+ });
4845
+ }
4742
4846
  _statEventVoteVariant() {
4743
4847
  try {
4744
- if (this.selectedVariant != null) {
4745
- var labelText = this.label?.textContent ?? "";
4746
- var variantText = this.variantsTexts[this.selectedVariant] ? this.variantsTexts[this.selectedVariant] : "";
4747
- var duration = new Date().getTime() - this.firstOpenTime;
4848
+ let isValid = false;
4849
+ let selectedVariant = null;
4850
+ if (!this.multipleChoice) {
4851
+ if (this.selectedVariant != null) {
4852
+ isValid = true;
4853
+ selectedVariant = this.selectedVariant;
4854
+ }
4855
+ }
4856
+ let selectedVariantsLabels = [];
4857
+ let selectedVariantsIdxs = [];
4858
+ if (this.multipleChoice) {
4859
+ selectedVariantsIdxs = this._getCheckedVariants();
4860
+ if (selectedVariantsIdxs.length > 0) {
4861
+ isValid = true;
4862
+ selectedVariant = selectedVariantsIdxs[0];
4863
+ selectedVariantsIdxs.forEach(idx => selectedVariantsLabels.push(this.variantsTexts[idx] ? this.variantsTexts[idx] : ""));
4864
+ }
4865
+ }
4866
+ if (isValid) {
4867
+ let labelText = this.label?.textContent ?? "";
4868
+ let variantText = this.variantsTexts[selectedVariant] ? this.variantsTexts[selectedVariant] : "";
4869
+ let duration = new Date().getTime() - this.firstOpenTime;
4870
+ // доп поля - для multiple choice
4871
+ // первые оставляем пустыми в этом случае
4748
4872
  this.sendStatisticEventToApp("w-vote-answer", {
4749
4873
  i: this.storyId,
4750
4874
  si: this.slideIndex,
4751
4875
  wi: this.elementId,
4752
4876
  wl: labelText,
4753
- wa: this.selectedVariant,
4877
+ wa: selectedVariant,
4754
4878
  wv: variantText,
4755
4879
  d: duration,
4880
+ was: selectedVariantsIdxs,
4881
+ wvs: selectedVariantsLabels,
4756
4882
  }, {
4757
4883
  story_id: this.storyId,
4758
4884
  slide_index: this.slideIndex,
4759
4885
  widget_id: this.elementId,
4760
4886
  widget_label: labelText,
4761
- widget_answer: this.selectedVariant,
4887
+ widget_answer: selectedVariant,
4762
4888
  widget_value: variantText,
4763
4889
  duration_ms: duration,
4890
+ widget_answers: selectedVariantsIdxs,
4891
+ widget_values: selectedVariantsLabels,
4764
4892
  });
4765
4893
  }
4766
4894
  }
@@ -4768,15 +4896,33 @@ class WidgetVote extends WidgetBase {
4768
4896
  console.error(error);
4769
4897
  }
4770
4898
  }
4899
+ // user click on (un)checked (radio btn) variant
4900
+ _checkVariant(index) {
4901
+ if (this.variants[index]) {
4902
+ if (this.variants[index].classList.contains("checked")) {
4903
+ this.variants[index].classList.remove("checked");
4904
+ }
4905
+ else {
4906
+ this.variants[index].classList.add("checked");
4907
+ }
4908
+ }
4909
+ }
4910
+ _getCheckedVariants() {
4911
+ const map = [];
4912
+ this.variants.forEach((variant, index) => {
4913
+ if (variant.classList.contains("checked")) {
4914
+ map.push(index);
4915
+ }
4916
+ });
4917
+ return map;
4918
+ }
4771
4919
  _selectVariant(index, filled = false) {
4772
4920
  if (this.variants[index]) {
4773
4921
  this.variants[index].classList.add("selected");
4774
4922
  }
4775
4923
  this.selectedVariant = index;
4776
- this.localData["_v_g_" + this.elementId + "_sa"] = index;
4777
- this.element.classList.add("done");
4778
- if (filled) {
4779
- this.element.classList.add("filled");
4924
+ if (!this.multipleChoice) {
4925
+ this.localData["_v_g_" + this.elementId + "_sa"] = index;
4780
4926
  }
4781
4927
  if (this.hideClientTotalResult) {
4782
4928
  const cb = () => {
@@ -4791,43 +4937,136 @@ class WidgetVote extends WidgetBase {
4791
4937
  this.env.requestAnimationFrame(cb);
4792
4938
  }
4793
4939
  }
4794
- else {
4795
- this.displayPercents(index, filled);
4940
+ }
4941
+ _fillWidget(filled = false) {
4942
+ this.element.classList.add("done");
4943
+ if (filled) {
4944
+ this.element.classList.add("filled");
4945
+ }
4946
+ if (!this.multipleChoice) {
4947
+ if (this.submitButtonView != null) {
4948
+ this._setInputDone();
4949
+ this._showSubmitBtn();
4950
+ }
4796
4951
  }
4952
+ if (this.multipleChoice) {
4953
+ this._removeInputDone();
4954
+ this._hideSubmitBtn();
4955
+ }
4956
+ if (this.disableTimer) {
4957
+ this.startDisabledTimeline();
4958
+ }
4959
+ }
4960
+ _showSubmitBtn() {
4797
4961
  this.env.requestAnimationFrame(() => {
4798
4962
  if (this.submitButtonAnimatedView != null && this.submitButtonViewHeight != null) {
4799
4963
  this.submitButtonAnimatedView.style.maxHeight = this.submitButtonViewHeight + "px";
4800
4964
  }
4801
4965
  });
4802
- if (this.disableTimer) {
4803
- this.showNextSlide();
4804
- }
4966
+ }
4967
+ _hideSubmitBtn() {
4968
+ this.env.requestAnimationFrame(() => {
4969
+ if (this.submitButtonAnimatedView != null && this.submitButtonViewHeight != null) {
4970
+ this.submitButtonAnimatedView.style.maxHeight = "0px";
4971
+ }
4972
+ });
4805
4973
  }
4806
4974
  selectVariant(variant) {
4807
- if (this.selectedVariant !== undefined) {
4808
- return true;
4975
+ if (!this.multipleChoice) {
4976
+ if (this.selectedVariant != null) {
4977
+ return true;
4978
+ }
4979
+ }
4980
+ if (this.multipleChoice) {
4981
+ if (this.isDone()) {
4982
+ return true;
4983
+ }
4809
4984
  }
4810
4985
  var selectedVariantIndex = this.variants.indexOf(variant);
4811
4986
  if (selectedVariantIndex !== -1) {
4812
- this._selectVariant(selectedVariantIndex);
4813
- this.localData["_v_g_" + this.elementId + "_done_at"] = Math.round(new Date().getTime() / 1000);
4814
- // ответ на вопрос
4815
- this.localData["_&ts_v_g_" + this.elementId + "_a_at"] = Math.round(new Date().getTime() / 1000);
4816
- if (this.widgetDone) {
4817
- this.widgetDone.classList.add("active", "opacity-active");
4818
- setTimeout(() => {
4819
- this.widgetDone?.classList.remove("active");
4820
- setTimeout(() => {
4821
- this.widgetDone?.classList.remove("opacity-active");
4822
- }, 250);
4823
- }, 2000);
4987
+ this._checkVariant(selectedVariantIndex);
4988
+ if (this.multipleChoice) {
4989
+ if (this._getCheckedVariants().length > 0) {
4990
+ this._setInputDone();
4991
+ this._showSubmitBtn();
4992
+ }
4993
+ else {
4994
+ this._removeInputDone();
4995
+ this._hideSubmitBtn();
4996
+ }
4997
+ }
4998
+ if (!this.multipleChoice) {
4999
+ this._selectVariant(selectedVariantIndex);
5000
+ if (!this.hideClientTotalResult) {
5001
+ this.displayPercents([selectedVariantIndex]);
5002
+ }
5003
+ this._fillWidget();
5004
+ this._completeWidget();
4824
5005
  }
4825
- this.setLocalData(this.localData, true);
4826
- this._statEventVoteVariant();
4827
5006
  }
4828
5007
  return false;
4829
5008
  }
4830
- displayPercents(selectedVariantIndex, filled = false) {
5009
+ _setInputDone() {
5010
+ if (this.submitButtonView != null) {
5011
+ this.element.classList.add("input-done");
5012
+ }
5013
+ }
5014
+ _removeInputDone() {
5015
+ // if (this.submitButtonView != null) {
5016
+ setTimeout(() => {
5017
+ this.element.classList.add("border-radius-transition-250");
5018
+ this.env.requestAnimationFrame(() => {
5019
+ this.element.classList.remove("input-done");
5020
+ setTimeout(() => this.element.classList.remove("border-radius-transition-250"), 250);
5021
+ });
5022
+ }, 250);
5023
+ // }
5024
+ }
5025
+ _completeWidget() {
5026
+ this.localData["_v_g_" + this.elementId + "_done_at"] = Math.round(new Date().getTime() / 1000);
5027
+ // ответ на вопрос
5028
+ this.localData["_&ts_v_g_" + this.elementId + "_a_at"] = Math.round(new Date().getTime() / 1000);
5029
+ if (this.widgetDone) {
5030
+ this.widgetDone.classList.add("active", "opacity-active");
5031
+ setTimeout(() => {
5032
+ this.widgetDone?.classList.remove("active");
5033
+ setTimeout(() => {
5034
+ this.widgetDone?.classList.remove("opacity-active");
5035
+ }, 250);
5036
+ }, 2000);
5037
+ }
5038
+ this.setLocalData(this.localData, true);
5039
+ this._statEventVoteVariant();
5040
+ }
5041
+ submitMultipleChoice() {
5042
+ const variants = this._getCheckedVariants();
5043
+ if (variants.length > 0) {
5044
+ this.localData["_v_g_" + this.elementId + "_sa"] = variants;
5045
+ for (let i = 0; i < variants.length; ++i) {
5046
+ const index = variants[i];
5047
+ this._selectVariant(index);
5048
+ }
5049
+ if (!this.hideClientTotalResult) {
5050
+ this.displayPercents(variants);
5051
+ }
5052
+ this._fillWidget();
5053
+ this._completeWidget();
5054
+ }
5055
+ }
5056
+ click() {
5057
+ if (this.isDone()) {
5058
+ return true;
5059
+ }
5060
+ if (this.multipleChoice) {
5061
+ this.submitMultipleChoice();
5062
+ return false;
5063
+ }
5064
+ else {
5065
+ // for single mode - return true and sdk will proceed click as nextClick()
5066
+ return true;
5067
+ }
5068
+ }
5069
+ displayPercents(selectedVariantsIndexes, filled = false) {
4831
5070
  // voteAllocation[0] - variant total count allocation
4832
5071
  // voteAllocation[1]
4833
5072
  // ...
@@ -4849,7 +5088,7 @@ class WidgetVote extends WidgetBase {
4849
5088
  if (voteAllocation[key] === undefined || !isNumber(voteAllocation[key])) {
4850
5089
  voteAllocation[key] = 0;
4851
5090
  }
4852
- if (selectedVariantIndex === key) {
5091
+ if (selectedVariantsIndexes.includes(key)) {
4853
5092
  ++voteAllocation[key];
4854
5093
  }
4855
5094
  });
@@ -4905,12 +5144,13 @@ class WidgetVote extends WidgetBase {
4905
5144
  }
4906
5145
  }
4907
5146
  isDone() {
4908
- return this.localData["_v_g_" + this.elementId + "_done_at"] !== undefined;
5147
+ return this.localData["_v_g_" + this.elementId + "_done_at"] != null;
4909
5148
  }
4910
5149
  slideVoteIsDone() {
4911
- return this.localData["_v_g_" + this.elementId + "_sa"] !== undefined;
5150
+ return this.localData["_v_g_" + this.elementId + "_sa"] != null;
4912
5151
  }
4913
5152
  static api = {
5153
+ widgetClassName: WidgetVote.widgetClassName,
4914
5154
  refreshUserData: WidgetVote.refreshUserData,
4915
5155
  // fix for WidgetVote on every layer of multilayers story
4916
5156
  fallbackInitOnMultiSlide: function (element, localData) {
@@ -4948,6 +5188,16 @@ class WidgetVote extends WidgetBase {
4948
5188
  }
4949
5189
  return false;
4950
5190
  },
5191
+ click: function (element) {
5192
+ const widgetElement = element.closest(`.${WidgetVote.widgetClassName}`);
5193
+ if (widgetElement) {
5194
+ const widget = WidgetVote.getInstance(widgetElement);
5195
+ if (widget) {
5196
+ return widget.click();
5197
+ }
5198
+ }
5199
+ return true;
5200
+ },
4951
5201
  slideVoteIsDone: function (element) {
4952
5202
  const widget = WidgetVote.getInstance(element);
4953
5203
  if (widget) {