@inappstory/slide-api 0.0.8 → 0.0.10

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
@@ -213,6 +213,29 @@ class WidgetsService {
213
213
 
214
214
  container.registerSingleton(undefined, { identifier: `WidgetsService`, implementation: WidgetsService });
215
215
 
216
+ class LayoutService {
217
+ _env;
218
+ _sdkApi;
219
+ _layoutApi;
220
+ constructor(_env, _sdkApi, _layoutApi) {
221
+ this._env = _env;
222
+ this._sdkApi = _sdkApi;
223
+ this._layoutApi = _layoutApi;
224
+ }
225
+ get env() {
226
+ return this._env;
227
+ }
228
+ get sdkApi() {
229
+ return this._sdkApi;
230
+ }
231
+ get layoutApi() {
232
+ return this._layoutApi;
233
+ }
234
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`Window`, `SDKApi`, `ILayoutApi`]; }
235
+ }
236
+
237
+ container.registerSingleton(undefined, { identifier: `LayoutService`, implementation: LayoutService });
238
+
216
239
  // import '../adapters/dateTimeSource/composition';
217
240
  // import '../adapters/uuidGenerator/composition';
218
241
  // import '../effects/eventHandler/composition';
@@ -220,6 +243,8 @@ container.registerSingleton(undefined, { identifier: `WidgetsService`, implement
220
243
  // import '../effects/timer/composition';
221
244
  container.registerSingleton(() => window, { identifier: `Window` });
222
245
 
246
+ const DEFAULT_SLIDE_DURATION = 10000;
247
+
223
248
  const arPrototype = Array.prototype;
224
249
  const obPrototype = Object.prototype;
225
250
  const slice = arPrototype.slice;
@@ -544,9 +569,6 @@ class Data {
544
569
  }
545
570
  // var data_priv = new Data();
546
571
  const data_user = new Data();
547
- const getSlideDuration = function (sdkApi, storyId, slideIndex) {
548
- return sdkApi.getSlideDuration(storyId, slideIndex) ?? 10000;
549
- };
550
572
  const getWinWidth = function (env) {
551
573
  return env.innerWidth || env.document.documentElement.clientWidth || env.document.body.clientWidth;
552
574
  };
@@ -1132,6 +1154,21 @@ class EsModuleSdkApi {
1132
1154
  getStorySessionValue(element, key) {
1133
1155
  return this.sdkBinding().getStorySessionValue(key);
1134
1156
  }
1157
+ updateTimeline(slideIndex, action, currentTime, duration, showLoader, showError) {
1158
+ const updateTimeline = this.sdkBinding().updateTimeline;
1159
+ if (updateTimeline != null) {
1160
+ updateTimeline(slideIndex, action, currentTime, duration, showLoader, showError);
1161
+ }
1162
+ }
1163
+ storyPausedCallback(currentTime) { }
1164
+ storyResumedCallback(currentTime) { }
1165
+ startDisabledTimeline(storyId, slideIndex) {
1166
+ // old api
1167
+ this.showNextSlide(this.getSlideDuration(storyId, slideIndex) ?? DEFAULT_SLIDE_DURATION);
1168
+ }
1169
+ getStoryFonts() {
1170
+ return this.sdkBinding().getStoryFonts();
1171
+ }
1135
1172
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`() => SDKInterface`]; }
1136
1173
  }
1137
1174
 
@@ -1310,8 +1347,8 @@ class WidgetBase {
1310
1347
  sendStatisticEventToApp(name, data, devPayload) {
1311
1348
  this.constructor.sendStatisticEventToApp(name, data, devPayload);
1312
1349
  }
1313
- showNextSlide() {
1314
- this.sdkApi.showNextSlide(getSlideDuration(this.sdkApi, this.storyId, this.slideIndex));
1350
+ startDisabledTimeline() {
1351
+ this.sdkApi.startDisabledTimeline(this.storyId, this.slideIndex);
1315
1352
  }
1316
1353
  _showLayout(layers, selectIndex, withStatEvent = false) {
1317
1354
  if (this.sdkApi.isExistsShowLayer()) {
@@ -1548,7 +1585,7 @@ class WidgetCopy extends WidgetBase {
1548
1585
  // флаг - что таймер уже стартанул (в layout или добавить объект sharedMemory)
1549
1586
  // смотрим что прозрачный текст - тогда и лоадер прозрачный
1550
1587
  // _log("_showNarrativeNextSlide: " + getSlideDuration(this.narrativeId, this.slideIndex), true);
1551
- this.showNextSlide();
1588
+ this.startDisabledTimeline();
1552
1589
  }
1553
1590
  }
1554
1591
  copyToClipboard(element) {
@@ -1568,6 +1605,7 @@ class WidgetCopy extends WidgetBase {
1568
1605
  return this.localData["_cp_g_" + this.elementId + "_done_at"] !== undefined;
1569
1606
  }
1570
1607
  static api = {
1608
+ widgetClassName: WidgetCopy.widgetClassName,
1571
1609
  refreshUserData: WidgetCopy.refreshUserData,
1572
1610
  initWidget: function (nodeList, localData) {
1573
1611
  // prevent initWidget for result layer
@@ -1632,7 +1670,7 @@ class WidgetDataInput extends WidgetBase {
1632
1670
  if (text) {
1633
1671
  this.element.classList.add("done");
1634
1672
  if (this.disableTimer) {
1635
- this.showNextSlide();
1673
+ this.startDisabledTimeline();
1636
1674
  }
1637
1675
  }
1638
1676
  }
@@ -1749,7 +1787,7 @@ class WidgetDataInput extends WidgetBase {
1749
1787
  this.setLocalData(this.localData, true);
1750
1788
  this._statEventInputSave(text);
1751
1789
  if (this.disableTimer) {
1752
- this.showNextSlide();
1790
+ this.startDisabledTimeline();
1753
1791
  needResumeUITimer = false;
1754
1792
  }
1755
1793
  }
@@ -1758,6 +1796,7 @@ class WidgetDataInput extends WidgetBase {
1758
1796
  }
1759
1797
  }
1760
1798
  static api = {
1799
+ widgetClassName: WidgetDataInput.widgetClassName,
1761
1800
  refreshUserData: WidgetDataInput.refreshUserData,
1762
1801
  initWidget: function (nodeList, localData) {
1763
1802
  WidgetDataInput.initWidgets((element, options) => new WidgetDataInput(element, options), slice.call(nodeList), localData);
@@ -1971,6 +2010,7 @@ class WidgetDateCountdown extends WidgetBase {
1971
2010
  return result;
1972
2011
  }
1973
2012
  static api = {
2013
+ widgetClassName: WidgetDateCountdown.widgetClassName,
1974
2014
  refreshUserData: WidgetDateCountdown.refreshUserData,
1975
2015
  initWidget: function (nodeList, layers, localData) {
1976
2016
  WidgetDateCountdown.initWidgets((element, options) => new WidgetDateCountdown(element, { ...options, layers }), slice.call(nodeList), localData);
@@ -2261,7 +2301,7 @@ class WidgetPoll extends WidgetBase {
2261
2301
  // todo poll - если виджет на первом слайде то при повторном заходе автоматически не стартует таймлайн слайда
2262
2302
  // только в web sdk такое
2263
2303
  // если поставить через setTimeout то все ок
2264
- this.showNextSlide();
2304
+ this.startDisabledTimeline();
2265
2305
  });
2266
2306
  }
2267
2307
  }
@@ -2599,6 +2639,7 @@ class WidgetPoll extends WidgetBase {
2599
2639
  return this.localData["_p_g_" + this.elementId + "_sa"] !== undefined;
2600
2640
  }
2601
2641
  static api = {
2642
+ widgetClassName: WidgetPoll.widgetClassName,
2602
2643
  refreshUserData: WidgetPoll.refreshUserData,
2603
2644
  initWidget: function (element, localData) {
2604
2645
  WidgetPoll.initWidgets((element, options) => new WidgetPoll(element, options), [element], localData);
@@ -2727,7 +2768,7 @@ class WidgetPollLayers extends WidgetBase {
2727
2768
  }
2728
2769
  this._showLayout(this.layers, layerIndex, userAction);
2729
2770
  if (this.disableTimer) {
2730
- this.showNextSlide();
2771
+ this.startDisabledTimeline();
2731
2772
  }
2732
2773
  }
2733
2774
  selectVariant(variant) {
@@ -2764,6 +2805,7 @@ class WidgetPollLayers extends WidgetBase {
2764
2805
  return this.localData != null && this.localData["_pl_g_" + this.elementId + "_sa"] !== undefined;
2765
2806
  }
2766
2807
  static api = {
2808
+ widgetClassName: WidgetPollLayers.widgetClassName,
2767
2809
  refreshUserData: WidgetPollLayers.refreshUserData,
2768
2810
  // signature variants
2769
2811
  // (widget, layers, undefined) - modern web sdk
@@ -3047,6 +3089,7 @@ class WidgetQuest extends WidgetBase {
3047
3089
  }
3048
3090
  }
3049
3091
  static api = {
3092
+ widgetClassName: WidgetQuest.widgetClassName,
3050
3093
  refreshUserData: WidgetQuest.refreshUserData,
3051
3094
  initWidget: function (element, localData) {
3052
3095
  return new Promise(function (resolve, reject) {
@@ -3153,7 +3196,7 @@ class WidgetQuiz extends WidgetBase {
3153
3196
  // })
3154
3197
  // }
3155
3198
  if (this.disableTimer) {
3156
- this.showNextSlide();
3199
+ this.startDisabledTimeline();
3157
3200
  }
3158
3201
  }
3159
3202
  _clearAnswerSelection() {
@@ -3245,6 +3288,7 @@ class WidgetQuiz extends WidgetBase {
3245
3288
  return this.localData["_q_g_" + this.elementId + "_sa"] !== undefined;
3246
3289
  }
3247
3290
  static api = {
3291
+ widgetClassName: WidgetQuiz.widgetClassName,
3248
3292
  refreshUserData: WidgetQuiz.refreshUserData,
3249
3293
  initWidget: function (element, localData) {
3250
3294
  WidgetQuiz.initWidgets((element, options) => new WidgetQuiz(element, options), [element], localData);
@@ -3330,7 +3374,7 @@ class WidgetQuizGrouped extends WidgetBase {
3330
3374
  }
3331
3375
  });
3332
3376
  if (this.disableTimer) {
3333
- this.showNextSlide();
3377
+ this.startDisabledTimeline();
3334
3378
  }
3335
3379
  }
3336
3380
  _clearAnswerSelection() {
@@ -3439,6 +3483,7 @@ class WidgetQuizGrouped extends WidgetBase {
3439
3483
  return this.localData["_q_gg_" + this.elementId + "_sa"] !== undefined;
3440
3484
  }
3441
3485
  static api = {
3486
+ widgetClassName: WidgetQuizGrouped.widgetClassName,
3442
3487
  refreshUserData: WidgetQuizGrouped.refreshUserData,
3443
3488
  initWidget: function (element, localData) {
3444
3489
  WidgetQuizGrouped.initWidgets((element, options) => new WidgetQuizGrouped(element, options), [element], localData);
@@ -3691,7 +3736,7 @@ class WidgetRangeSlider extends WidgetBase {
3691
3736
  this.element.classList.add("done");
3692
3737
  this.displayAverageAnswer();
3693
3738
  if (this.disableTimer) {
3694
- this.showNextSlide();
3739
+ this.startDisabledTimeline();
3695
3740
  }
3696
3741
  }
3697
3742
  else {
@@ -3760,7 +3805,7 @@ class WidgetRangeSlider extends WidgetBase {
3760
3805
  }
3761
3806
  });
3762
3807
  // if (this.disableTimer) {
3763
- this.showNextSlide();
3808
+ this.startDisabledTimeline();
3764
3809
  // }
3765
3810
  this.setLocalData(this.localData, true);
3766
3811
  this._statEventInputSave(this.localData["_rs_g_" + this.elementId + "_v"]);
@@ -4048,6 +4093,7 @@ class WidgetRangeSlider extends WidgetBase {
4048
4093
  // .removeData('plugin_' + pluginName);
4049
4094
  }
4050
4095
  static api = {
4096
+ widgetClassName: WidgetRangeSlider.widgetClassName,
4051
4097
  refreshUserData: WidgetRangeSlider.refreshUserData,
4052
4098
  initWidget: function (element, localData) {
4053
4099
  WidgetRangeSlider.initWidgets((element, options) => new WidgetRangeSlider(element, options), [element], localData);
@@ -4172,7 +4218,7 @@ class WidgetRate extends WidgetBase {
4172
4218
  this.localData["_r_g_" + this.elementId + "_ss"] = value;
4173
4219
  this.element.classList.add("done");
4174
4220
  if (this.disableTimer && runTimer) {
4175
- this.showNextSlide();
4221
+ this.startDisabledTimeline();
4176
4222
  }
4177
4223
  }
4178
4224
  _clearSelectedStar() {
@@ -4296,6 +4342,7 @@ class WidgetRate extends WidgetBase {
4296
4342
  return this.localData["_r_g_" + this.elementId + "_sa"] !== undefined;
4297
4343
  }
4298
4344
  static api = {
4345
+ widgetClassName: WidgetRate.widgetClassName,
4299
4346
  refreshUserData: WidgetRate.refreshUserData,
4300
4347
  initWidget: function (nodeList, localData) {
4301
4348
  WidgetRate.initWidgets((element, options) => new WidgetRate(element, options), slice.call(nodeList), localData);
@@ -4418,6 +4465,7 @@ class WidgetShare extends WidgetBase {
4418
4465
  return Boolean(this.localData["_s_" + this.elementId + "_ts"]);
4419
4466
  }
4420
4467
  static api = {
4468
+ widgetClassName: WidgetShare.widgetClassName,
4421
4469
  refreshUserData: WidgetShare.refreshUserData,
4422
4470
  // signature variants
4423
4471
  // (widget, layers, undefined) - modern web sdk
@@ -4537,6 +4585,11 @@ class WidgetTest extends WidgetBase {
4537
4585
  this.timeline.style.transform = "translateX(100%)";
4538
4586
  }
4539
4587
  }
4588
+ else if (this.localData["_&ts_t_g_" + this.elementId + "_a_tspent"] != null) {
4589
+ if (this.timeline) {
4590
+ this.timeline.style.transform = "translateX(" + String(this.localData["_&ts_t_g_" + this.elementId + "_a_tspent"]) + "%)";
4591
+ }
4592
+ }
4540
4593
  }
4541
4594
  }
4542
4595
  // this.refreshUserData(this.options.localData);
@@ -4592,7 +4645,7 @@ class WidgetTest extends WidgetBase {
4592
4645
  }
4593
4646
  });
4594
4647
  if (this.disableTimer) {
4595
- this.showNextSlide();
4648
+ this.startDisabledTimeline();
4596
4649
  }
4597
4650
  }
4598
4651
  selectAnswer(answer) {
@@ -4636,6 +4689,10 @@ class WidgetTest extends WidgetBase {
4636
4689
  }
4637
4690
  // answer on question
4638
4691
  this.localData["_&ts_t_g_" + this.elementId + "_a_at"] = Math.round(new Date().getTime() / 1000);
4692
+ // spent percent of time
4693
+ if (this.slideTestWithTimer()) {
4694
+ this.localData["_&ts_t_g_" + this.elementId + "_a_tspent"] = Math.round((1 - this.timeLeft / this.timeLeftDefault) * 100);
4695
+ }
4639
4696
  if (this.widgetDone) {
4640
4697
  this.widgetDone.classList.add("active", "opacity-active");
4641
4698
  setTimeout(() => {
@@ -4658,6 +4715,7 @@ class WidgetTest extends WidgetBase {
4658
4715
  return Boolean(this.withTimeToAnswer && this.answerTimeout);
4659
4716
  }
4660
4717
  static api = {
4718
+ widgetClassName: WidgetTest.widgetClassName,
4661
4719
  refreshUserData: WidgetTest.refreshUserData,
4662
4720
  initWidget: function (element, localData) {
4663
4721
  WidgetTest.initWidgets((element, options) => new WidgetTest(element, options), [element], localData);
@@ -4711,6 +4769,7 @@ class WidgetVote extends WidgetBase {
4711
4769
  selectedVariant;
4712
4770
  voteAllocation;
4713
4771
  hideClientTotalResult;
4772
+ multipleChoice;
4714
4773
  /**
4715
4774
  * @throws Error
4716
4775
  * @param element
@@ -4729,38 +4788,112 @@ class WidgetVote extends WidgetBase {
4729
4788
  }
4730
4789
  });
4731
4790
  this.hideClientTotalResult = getValueOrDefault(Boolean(getTagDataAsNumber(this.element, "hideClientTotalResult")), false);
4791
+ this.multipleChoice = getValueOrDefault(Boolean(getTagDataAsNumber(this.element, "multipleChoice")), false);
4792
+ this.refreshUserData(this.options.localData);
4793
+ }
4794
+ _initFromLocalData() {
4795
+ const value = this.localData["_v_g_" + this.elementId + "_sa"];
4796
+ if (!this.multipleChoice) {
4797
+ let index = value;
4798
+ if (Array.isArray(value)) {
4799
+ index = value[0];
4800
+ }
4801
+ this._checkVariant(index);
4802
+ this._selectVariant(index, true);
4803
+ if (!this.hideClientTotalResult) {
4804
+ this.displayPercents([index], true);
4805
+ }
4806
+ this._fillWidget(true);
4807
+ }
4808
+ if (this.multipleChoice) {
4809
+ let values = [];
4810
+ if (Array.isArray(value)) {
4811
+ values = value;
4812
+ }
4813
+ else {
4814
+ values.push(value);
4815
+ }
4816
+ for (let i = 0; i < values.length; ++i) {
4817
+ const index = values[i];
4818
+ this._checkVariant(index);
4819
+ this._selectVariant(index, true);
4820
+ }
4821
+ if (!this.hideClientTotalResult) {
4822
+ this.displayPercents(values, true);
4823
+ }
4824
+ this._fillWidget(true);
4825
+ }
4826
+ }
4827
+ refreshUserData(localData) {
4828
+ this.savedData = this.sdkApi.getStoryServerData(this.storyId);
4829
+ this.localData = extend({}, this.savedData ?? {}, localData);
4732
4830
  this.selectedVariant = undefined;
4733
4831
  if (this.localData) {
4734
- if (this.localData["_v_g_" + this.elementId + "_sa"] !== undefined) {
4735
- this._selectVariant(this.localData["_v_g_" + this.elementId + "_sa"], true);
4832
+ if (this.localData["_v_g_" + this.elementId + "_sa"] != null) {
4833
+ this._initFromLocalData();
4834
+ }
4835
+ else {
4836
+ this._clearSelectedVariants();
4837
+ this.element.classList.remove("done");
4838
+ this.element.classList.remove("input-done");
4839
+ this.element.classList.remove("filled");
4736
4840
  }
4737
4841
  }
4738
4842
  this.firstOpenTime = new Date().getTime();
4739
- // this.refreshUserData(this.options.localData);
4740
4843
  }
4741
- refreshUserData(localData) { }
4844
+ _clearSelectedVariants() {
4845
+ this.variants.forEach((variant, index) => {
4846
+ variant.classList.remove("checked");
4847
+ variant.classList.remove("selected");
4848
+ variant.style.setProperty("--selected-variant-view-clip-area", String(100));
4849
+ });
4850
+ }
4742
4851
  _statEventVoteVariant() {
4743
4852
  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;
4853
+ let isValid = false;
4854
+ let selectedVariant = null;
4855
+ if (!this.multipleChoice) {
4856
+ if (this.selectedVariant != null) {
4857
+ isValid = true;
4858
+ selectedVariant = this.selectedVariant;
4859
+ }
4860
+ }
4861
+ let selectedVariantsLabels = [];
4862
+ let selectedVariantsIdxs = [];
4863
+ if (this.multipleChoice) {
4864
+ selectedVariantsIdxs = this._getCheckedVariants();
4865
+ if (selectedVariantsIdxs.length > 0) {
4866
+ isValid = true;
4867
+ selectedVariant = selectedVariantsIdxs[0];
4868
+ selectedVariantsIdxs.forEach(idx => selectedVariantsLabels.push(this.variantsTexts[idx] ? this.variantsTexts[idx] : ""));
4869
+ }
4870
+ }
4871
+ if (isValid) {
4872
+ let labelText = this.label?.textContent ?? "";
4873
+ let variantText = this.variantsTexts[selectedVariant] ? this.variantsTexts[selectedVariant] : "";
4874
+ let duration = new Date().getTime() - this.firstOpenTime;
4875
+ // доп поля - для multiple choice
4876
+ // первые оставляем пустыми в этом случае
4748
4877
  this.sendStatisticEventToApp("w-vote-answer", {
4749
4878
  i: this.storyId,
4750
4879
  si: this.slideIndex,
4751
4880
  wi: this.elementId,
4752
4881
  wl: labelText,
4753
- wa: this.selectedVariant,
4882
+ wa: selectedVariant,
4754
4883
  wv: variantText,
4755
4884
  d: duration,
4885
+ was: selectedVariantsIdxs,
4886
+ wvs: selectedVariantsLabels,
4756
4887
  }, {
4757
4888
  story_id: this.storyId,
4758
4889
  slide_index: this.slideIndex,
4759
4890
  widget_id: this.elementId,
4760
4891
  widget_label: labelText,
4761
- widget_answer: this.selectedVariant,
4892
+ widget_answer: selectedVariant,
4762
4893
  widget_value: variantText,
4763
4894
  duration_ms: duration,
4895
+ widget_answers: selectedVariantsIdxs,
4896
+ widget_values: selectedVariantsLabels,
4764
4897
  });
4765
4898
  }
4766
4899
  }
@@ -4768,15 +4901,33 @@ class WidgetVote extends WidgetBase {
4768
4901
  console.error(error);
4769
4902
  }
4770
4903
  }
4904
+ // user click on (un)checked (radio btn) variant
4905
+ _checkVariant(index) {
4906
+ if (this.variants[index]) {
4907
+ if (this.variants[index].classList.contains("checked")) {
4908
+ this.variants[index].classList.remove("checked");
4909
+ }
4910
+ else {
4911
+ this.variants[index].classList.add("checked");
4912
+ }
4913
+ }
4914
+ }
4915
+ _getCheckedVariants() {
4916
+ const map = [];
4917
+ this.variants.forEach((variant, index) => {
4918
+ if (variant.classList.contains("checked")) {
4919
+ map.push(index);
4920
+ }
4921
+ });
4922
+ return map;
4923
+ }
4771
4924
  _selectVariant(index, filled = false) {
4772
4925
  if (this.variants[index]) {
4773
4926
  this.variants[index].classList.add("selected");
4774
4927
  }
4775
4928
  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");
4929
+ if (!this.multipleChoice) {
4930
+ this.localData["_v_g_" + this.elementId + "_sa"] = index;
4780
4931
  }
4781
4932
  if (this.hideClientTotalResult) {
4782
4933
  const cb = () => {
@@ -4791,43 +4942,136 @@ class WidgetVote extends WidgetBase {
4791
4942
  this.env.requestAnimationFrame(cb);
4792
4943
  }
4793
4944
  }
4794
- else {
4795
- this.displayPercents(index, filled);
4945
+ }
4946
+ _fillWidget(filled = false) {
4947
+ this.element.classList.add("done");
4948
+ if (filled) {
4949
+ this.element.classList.add("filled");
4950
+ }
4951
+ if (!this.multipleChoice) {
4952
+ if (this.submitButtonView != null) {
4953
+ this._setInputDone();
4954
+ this._showSubmitBtn();
4955
+ }
4796
4956
  }
4957
+ if (this.multipleChoice) {
4958
+ this._removeInputDone();
4959
+ this._hideSubmitBtn();
4960
+ }
4961
+ if (this.disableTimer) {
4962
+ this.startDisabledTimeline();
4963
+ }
4964
+ }
4965
+ _showSubmitBtn() {
4797
4966
  this.env.requestAnimationFrame(() => {
4798
4967
  if (this.submitButtonAnimatedView != null && this.submitButtonViewHeight != null) {
4799
4968
  this.submitButtonAnimatedView.style.maxHeight = this.submitButtonViewHeight + "px";
4800
4969
  }
4801
4970
  });
4802
- if (this.disableTimer) {
4803
- this.showNextSlide();
4804
- }
4971
+ }
4972
+ _hideSubmitBtn() {
4973
+ this.env.requestAnimationFrame(() => {
4974
+ if (this.submitButtonAnimatedView != null && this.submitButtonViewHeight != null) {
4975
+ this.submitButtonAnimatedView.style.maxHeight = "0px";
4976
+ }
4977
+ });
4805
4978
  }
4806
4979
  selectVariant(variant) {
4807
- if (this.selectedVariant !== undefined) {
4808
- return true;
4980
+ if (!this.multipleChoice) {
4981
+ if (this.selectedVariant != null) {
4982
+ return true;
4983
+ }
4984
+ }
4985
+ if (this.multipleChoice) {
4986
+ if (this.isDone()) {
4987
+ return true;
4988
+ }
4809
4989
  }
4810
4990
  var selectedVariantIndex = this.variants.indexOf(variant);
4811
4991
  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);
4992
+ this._checkVariant(selectedVariantIndex);
4993
+ if (this.multipleChoice) {
4994
+ if (this._getCheckedVariants().length > 0) {
4995
+ this._setInputDone();
4996
+ this._showSubmitBtn();
4997
+ }
4998
+ else {
4999
+ this._removeInputDone();
5000
+ this._hideSubmitBtn();
5001
+ }
5002
+ }
5003
+ if (!this.multipleChoice) {
5004
+ this._selectVariant(selectedVariantIndex);
5005
+ if (!this.hideClientTotalResult) {
5006
+ this.displayPercents([selectedVariantIndex]);
5007
+ }
5008
+ this._fillWidget();
5009
+ this._completeWidget();
4824
5010
  }
4825
- this.setLocalData(this.localData, true);
4826
- this._statEventVoteVariant();
4827
5011
  }
4828
5012
  return false;
4829
5013
  }
4830
- displayPercents(selectedVariantIndex, filled = false) {
5014
+ _setInputDone() {
5015
+ if (this.submitButtonView != null) {
5016
+ this.element.classList.add("input-done");
5017
+ }
5018
+ }
5019
+ _removeInputDone() {
5020
+ // if (this.submitButtonView != null) {
5021
+ setTimeout(() => {
5022
+ this.element.classList.add("border-radius-transition-250");
5023
+ this.env.requestAnimationFrame(() => {
5024
+ this.element.classList.remove("input-done");
5025
+ setTimeout(() => this.element.classList.remove("border-radius-transition-250"), 250);
5026
+ });
5027
+ }, 250);
5028
+ // }
5029
+ }
5030
+ _completeWidget() {
5031
+ this.localData["_v_g_" + this.elementId + "_done_at"] = Math.round(new Date().getTime() / 1000);
5032
+ // ответ на вопрос
5033
+ this.localData["_&ts_v_g_" + this.elementId + "_a_at"] = Math.round(new Date().getTime() / 1000);
5034
+ if (this.widgetDone) {
5035
+ this.widgetDone.classList.add("active", "opacity-active");
5036
+ setTimeout(() => {
5037
+ this.widgetDone?.classList.remove("active");
5038
+ setTimeout(() => {
5039
+ this.widgetDone?.classList.remove("opacity-active");
5040
+ }, 250);
5041
+ }, 2000);
5042
+ }
5043
+ this.setLocalData(this.localData, true);
5044
+ this._statEventVoteVariant();
5045
+ }
5046
+ submitMultipleChoice() {
5047
+ const variants = this._getCheckedVariants();
5048
+ if (variants.length > 0) {
5049
+ this.localData["_v_g_" + this.elementId + "_sa"] = variants;
5050
+ for (let i = 0; i < variants.length; ++i) {
5051
+ const index = variants[i];
5052
+ this._selectVariant(index);
5053
+ }
5054
+ if (!this.hideClientTotalResult) {
5055
+ this.displayPercents(variants);
5056
+ }
5057
+ this._fillWidget();
5058
+ this._completeWidget();
5059
+ }
5060
+ }
5061
+ click() {
5062
+ if (this.isDone()) {
5063
+ return true;
5064
+ }
5065
+ if (this.multipleChoice) {
5066
+ this.submitMultipleChoice();
5067
+ return false;
5068
+ }
5069
+ else {
5070
+ // for single mode - return true and sdk will proceed click as nextClick()
5071
+ return true;
5072
+ }
5073
+ }
5074
+ displayPercents(selectedVariantsIndexes, filled = false) {
4831
5075
  // voteAllocation[0] - variant total count allocation
4832
5076
  // voteAllocation[1]
4833
5077
  // ...
@@ -4849,7 +5093,7 @@ class WidgetVote extends WidgetBase {
4849
5093
  if (voteAllocation[key] === undefined || !isNumber(voteAllocation[key])) {
4850
5094
  voteAllocation[key] = 0;
4851
5095
  }
4852
- if (selectedVariantIndex === key) {
5096
+ if (selectedVariantsIndexes.includes(key)) {
4853
5097
  ++voteAllocation[key];
4854
5098
  }
4855
5099
  });
@@ -4905,12 +5149,13 @@ class WidgetVote extends WidgetBase {
4905
5149
  }
4906
5150
  }
4907
5151
  isDone() {
4908
- return this.localData["_v_g_" + this.elementId + "_done_at"] !== undefined;
5152
+ return this.localData["_v_g_" + this.elementId + "_done_at"] != null;
4909
5153
  }
4910
5154
  slideVoteIsDone() {
4911
- return this.localData["_v_g_" + this.elementId + "_sa"] !== undefined;
5155
+ return this.localData["_v_g_" + this.elementId + "_sa"] != null;
4912
5156
  }
4913
5157
  static api = {
5158
+ widgetClassName: WidgetVote.widgetClassName,
4914
5159
  refreshUserData: WidgetVote.refreshUserData,
4915
5160
  // fix for WidgetVote on every layer of multilayers story
4916
5161
  fallbackInitOnMultiSlide: function (element, localData) {
@@ -4948,6 +5193,16 @@ class WidgetVote extends WidgetBase {
4948
5193
  }
4949
5194
  return false;
4950
5195
  },
5196
+ click: function (element) {
5197
+ const widgetElement = element.closest(`.${WidgetVote.widgetClassName}`);
5198
+ if (widgetElement) {
5199
+ const widget = WidgetVote.getInstance(widgetElement);
5200
+ if (widget) {
5201
+ return widget.click();
5202
+ }
5203
+ }
5204
+ return true;
5205
+ },
4951
5206
  slideVoteIsDone: function (element) {
4952
5207
  const widget = WidgetVote.getInstance(element);
4953
5208
  if (widget) {