@subiz/widget-v4 4.1.126 → 4.1.130

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.
Files changed (62) hide show
  1. package/assets/less/avatar.less +1 -1
  2. package/assets/less/chatbox.less +28 -2
  3. package/assets/less/form.less +77 -2
  4. package/assets/less/message.less +4 -0
  5. package/assets/less/widget.less +20 -0
  6. package/assets/less/widget_header.less +0 -2
  7. package/compiled_src/chatbox/ChatButton.js +10 -4
  8. package/compiled_src/chatbox/ConnectionStatus.js +58 -0
  9. package/compiled_src/chatbox/Event.js +10 -8
  10. package/compiled_src/chatbox/FormAttachment2.js +97 -0
  11. package/compiled_src/chatbox/Widget.js +5 -0
  12. package/compiled_src/form/Form.js +276 -0
  13. package/compiled_src/form/FormPage.js +131 -0
  14. package/compiled_src/form/index.js +72 -0
  15. package/compiled_src/store/api.js +3 -0
  16. package/compiled_src/store/realtime_fake.js +4 -0
  17. package/compiled_src/store/store.js +25 -0
  18. package/compiled_src/util/campaign.js +3 -5
  19. package/compiled_src/util/common.js +2 -2
  20. package/dist/{1964f21ffc8.127.js → 1967c022bc1.127.js} +1 -1
  21. package/dist/{1964f21ffc8.132.js → 1967c022bc1.132.js} +1 -1
  22. package/dist/{1964f21ffc8.185.js → 1967c022bc1.185.js} +1 -1
  23. package/dist/1967c022bc1.278.js +1 -0
  24. package/dist/{1964f21ffc8.490.js → 1967c022bc1.490.js} +1 -1
  25. package/dist/{1964f21ffc8.74.js → 1967c022bc1.74.js} +1 -1
  26. package/dist/1967c022bc1.app.js +1 -0
  27. package/dist/1967c022bc1.form.html +1 -0
  28. package/dist/1967c022bc1.form.js +1 -0
  29. package/dist/{1964f21ffc8.index.html → 1967c022bc1.index.html} +1 -1
  30. package/dist/{1964f21ffc8.library.html → 1967c022bc1.library.html} +1 -1
  31. package/dist/1967c022bc1.library.js +1 -0
  32. package/dist/{1964f21ffc8.preview.html → 1967c022bc1.preview.html} +1 -1
  33. package/dist/1967c022bc1.preview.js +1 -0
  34. package/dist/1967c022bc1.webview.js +1 -0
  35. package/dist/278.js +1 -1
  36. package/dist/HASH +1 -1
  37. package/dist/screenshoot.js +1198 -1001
  38. package/form.html +10 -0
  39. package/package.json +5 -4
  40. package/src/chatbox/ChatButton.js +10 -8
  41. package/src/chatbox/ConnectionStatus.js +42 -0
  42. package/src/chatbox/Event.js +10 -10
  43. package/src/chatbox/FormAttachment2.js +73 -0
  44. package/src/chatbox/Widget.js +2 -0
  45. package/src/form/Form.js +295 -0
  46. package/src/form/FormPage.js +95 -0
  47. package/src/form/index.js +79 -0
  48. package/src/store/api.js +8 -0
  49. package/src/store/realtime_fake.js +8 -4
  50. package/src/store/store.js +29 -0
  51. package/src/util/campaign.js +3 -5
  52. package/src/util/common.js +2 -2
  53. package/webpack.dev.js +2 -0
  54. package/webpack.prod.js +7 -0
  55. package/dist/1964f21ffc8.278.js +0 -1
  56. package/dist/1964f21ffc8.app.js +0 -1
  57. package/dist/1964f21ffc8.library.js +0 -1
  58. package/dist/1964f21ffc8.preview.js +0 -1
  59. package/dist/1964f21ffc8.webview.js +0 -1
  60. /package/dist/{1964f21ffc8.27.js → 1967c022bc1.27.js} +0 -0
  61. /package/dist/{1964f21ffc8.459.js → 1967c022bc1.459.js} +0 -0
  62. /package/dist/{1964f21ffc8.997.js → 1967c022bc1.997.js} +0 -0
@@ -412,6 +412,43 @@ ajax.waterfall = waterfall
412
412
  module.exports = ajax
413
413
 
414
414
 
415
+ /***/ }),
416
+
417
+ /***/ 450:
418
+ /***/ ((module) => {
419
+
420
+ var localStorageMemory = {};
421
+ var cache = {};
422
+ localStorageMemory.length = 0;
423
+ localStorageMemory.getItem = function (key) {
424
+ if (key in cache) return cache[key];
425
+ return null;
426
+ };
427
+ localStorageMemory.setItem = function (key, value) {
428
+ if (typeof value === 'undefined') {
429
+ localStorageMemory.removeItem(key);
430
+ } else {
431
+ if (!Object.prototype.hasOwnProperty.call(cache, key)) {
432
+ localStorageMemory.length++;
433
+ }
434
+ cache[key] = value;
435
+ }
436
+ };
437
+ localStorageMemory.removeItem = function (key) {
438
+ if (Object.prototype.hasOwnProperty.call(cache, key)) {
439
+ delete cache[key];
440
+ localStorageMemory.length--;
441
+ }
442
+ };
443
+ localStorageMemory.key = function (index) {
444
+ return Object.keys(cache)[index] || null;
445
+ };
446
+ localStorageMemory.clear = function () {
447
+ cache = {};
448
+ localStorageMemory.length = 0;
449
+ };
450
+ module.exports = localStorageMemory;
451
+
415
452
  /***/ }),
416
453
 
417
454
  /***/ 940:
@@ -469,95 +506,6 @@ class Gate {
469
506
 
470
507
  /***/ }),
471
508
 
472
- /***/ 1314:
473
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
474
-
475
- "use strict";
476
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
477
- /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
478
- /* harmony export */ });
479
- let KvMaxSize = 500;
480
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (class {
481
- constructor(db, schema) {
482
- this.name = schema;
483
- schema += '_kv';
484
- this.dead = false;
485
- this.db = db;
486
- this.cache = {};
487
- this.initialized = false;
488
- this.init();
489
- }
490
- refreshCache() {
491
- if (this.dead) return;
492
- let inmemItemM = {};
493
- let allitems = this.db.all('items');
494
- allitems.forEach(function (item) {
495
- inmemItemM[item.key] = item.value;
496
- });
497
- this.cache = inmemItemM;
498
- }
499
- init() {
500
- if (this.initialized) return;
501
- let inmemItemM = {};
502
- console.time('KV' + this.name);
503
- let allitems = this.db.all('items');
504
- allitems.forEach(function (item) {
505
- inmemItemM[item.key] = item.value;
506
- });
507
- this.cache = inmemItemM;
508
- let allkeys = Object.keys(this.cache);
509
- if (allkeys.length > KvMaxSize) {
510
- let liveChance = KvMaxSize / 2 / allkeys.lenth;
511
- let removekeys = [];
512
- for (var i = 0; i < KvMaxSize; i++) {
513
- let live = Math.random() <= liveChance;
514
- if (live) continue;
515
- let key = allkeys[i];
516
- delete this.cache[key];
517
- removekeys.push(key);
518
- }
519
- this.db.removes('items', [removekeys]);
520
- }
521
- this.initialized = true;
522
- console.timeEnd('KV' + this.name);
523
- }
524
- all() {
525
- if (this.dead) return [];
526
- if (!this.initialized) return [];
527
- return this.cache;
528
- }
529
- match(key) {
530
- if (this.dead || !this.initialized) return;
531
- if (!key) return;
532
- return this.cache[key];
533
- }
534
- put(key, value) {
535
- if (!key) return;
536
- if (this.dead) return [];
537
- if (!this.initialized) throw new Error('uninitialized');
538
- this.cache[key] = value;
539
- this.db.put('items', key, {
540
- key,
541
- value
542
- });
543
- }
544
- del(key) {
545
- if (this.dead) return;
546
- if (!this.initialized) throw new Error('uninitialized');
547
- delete this.cache[key];
548
- this.db.removes('items', [key]);
549
- }
550
- destroy() {
551
- this.db.clear('items');
552
- this.dead = true;
553
- this.db = undefined;
554
- this.cache = undefined;
555
- this.initialized = false;
556
- }
557
- });
558
-
559
- /***/ }),
560
-
561
509
  /***/ 1370:
562
510
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
563
511
 
@@ -565,109 +513,6 @@ module.exports = __webpack_require__.p + "assets/img/convos_empty.2353007.svg";
565
513
 
566
514
  /***/ }),
567
515
 
568
- /***/ 1428:
569
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
570
-
571
- "use strict";
572
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
573
- /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
574
- /* harmony export */ });
575
- let memlocalStorage = (__webpack_require__(1554)/* ["default"] */ .A);
576
- let requestIdleCallback = window.requestIdleCallback || (cb => cb());
577
- const LIMIT = 80;
578
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (class {
579
- constructor(schema, inmem) {
580
- this.localStorage = memlocalStorage;
581
- this.allkeys = {};
582
- if (!inmem) {
583
- try {
584
- window.localStorage.setItem('sbzstore1029', '?');
585
- window.localStorage.removeItem('sbzstore1029');
586
- this.localStorage = window.localStorage;
587
- } catch (e) {}
588
- }
589
- this.schema = schema;
590
- }
591
- all(table) {
592
- let items = [];
593
- for (var i = 0; i < this.localStorage.length; i++) {
594
- let key = this.localStorage.key(i);
595
- if (!key.startsWith(this.schema + '#' + table + '#')) continue;
596
- this.allkeys[key] = true;
597
- items.push(JSON.parse(this.localStorage.getItem(key)));
598
- }
599
- return items;
600
- }
601
- removes(table, keys) {
602
- for (var i = 0; i < keys.length; i++) {
603
- delete this.allkeys[this.schema + '#' + table + '#' + keys[i]];
604
- this.localStorage.removeItem(this.schema + '#' + table + '#' + keys[i]);
605
- }
606
- }
607
- clear(table) {
608
- let matchkeys = [];
609
- for (var i = 0; i < this.localStorage.length; i++) {
610
- let key = this.localStorage.key(i);
611
- if (!key.startsWith(this.schema + '#' + table + '#')) continue;
612
- matchkeys.push(key);
613
- }
614
- for (var i = 0; i < matchkeys.length; i++) this.localStorage.removeItem(matchkeys[i]);
615
- this.allkeys = {};
616
- }
617
- put(table, key, value) {
618
- this.allkeys[this.schema + '#' + table + '#' + key] = true;
619
- if (Object.keys(this.allkeys).length > LIMIT) this.clear(table);
620
- requestIdleCallback(() => {
621
- try {
622
- this.localStorage.setItem(this.schema + '#' + table + '#' + key, toString(value));
623
- } catch (e) {
624
- this.clear(table);
625
- }
626
- });
627
- }
628
- });
629
- function toString(obj) {
630
- if (obj === undefined) return 'null';
631
- return JSON.stringify(obj);
632
- }
633
-
634
- /***/ }),
635
-
636
- /***/ 1554:
637
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
638
-
639
- "use strict";
640
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
641
- /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
642
- /* harmony export */ });
643
- var localStorageMemory = {};
644
- var cache = {};
645
- localStorageMemory.length = 0;
646
- localStorageMemory.getItem = function (key) {
647
- if (key in cache) return cache[key];
648
- return null;
649
- };
650
- localStorageMemory.setItem = function (key, value) {
651
- if (typeof value === 'undefined') localStorageMemory.removeItem(key);else cache[key] = '' + value;
652
- localStorageMemory.length = Object.keys(cache).length;
653
- };
654
- localStorageMemory.removeItem = function (key) {
655
- if (Object.prototype.hasOwnProperty.call(cache, key)) {
656
- delete cache[key];
657
- localStorageMemory.length = Object.keys(cache).length;
658
- }
659
- };
660
- localStorageMemory.key = function (index) {
661
- return Object.keys(cache)[index] || null;
662
- };
663
- localStorageMemory.clear = function () {
664
- cache = {};
665
- localStorageMemory.length = 0;
666
- };
667
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (localStorageMemory);
668
-
669
- /***/ }),
670
-
671
516
  /***/ 1620:
672
517
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
673
518
 
@@ -837,121 +682,174 @@ var {xhrsend, parseJSON, Pubsub} = __webpack_require__(7695)
837
682
  // as fast as possible through onEvents callback.
838
683
  //
839
684
  // It will try it best to keep the communication with the realtime
840
- // server. But if the user is offline for too long or her network can't
841
- // keep up with the incomming events (rarely happend with today
842
- // internet speed). The connection will be halt. Dead.
685
+ // server. But if the user is offline for too long or the network can't
686
+ // keep up with incomming events (rarely happend with today internet speed).
687
+ // The connection will be killed. Dead.
843
688
  //
844
689
  // Once dead, onDead will be called. After that, the connection is
845
690
  // useless, all resources will be released.
846
691
  function Conn(apiUrl, credential, onDead, onEvents, callAPI, accid) {
847
692
  callAPI = callAPI || xhrsend // allow hook
848
693
  credential = credential || {}
849
- // tell if connection is dead
850
- var dead = false
851
694
 
852
695
  var lastToken = ''
853
- // kill force the connection to dead state
854
- this.kill = function () {
855
- dead = true
856
- }
857
696
  if (!accid) accid = ''
858
697
 
859
- // long polling loop, polling will run sequentialy. Each polling will start right
860
- // after the previous returned. In case of error, polling loop will pause based on
861
- // exponential backoff algorithm. Polling loop will terminate if it encounter an
862
- // un-retryable error
863
- // the polling loop starts after the first subscribe call finished successfully
698
+ var is_dead = false // tell if the connection is dead
699
+ var is_polling_stuck = false // tell if we've having trouble doing /poll
700
+ var is_sub_stuck = false // tell if we've having trouble doing /subscribe
701
+
702
+ // The long polling loop runs sequentially, with each poll starting immediately
703
+ // after the previous one completes. If an error occurs, the loop will pause
704
+ // using an exponential backoff strategy. It will terminate if an unretryable
705
+ // error is encountered.
706
+ // The first loop begins after the first subscription call completes successfully
864
707
  var polling = function (backoff) {
865
- if (dead) return
866
- callAPI('get', apiUrl + 'poll?version=2&token=' + lastToken + '&account-id=' + accid, undefined, function (body, code) {
867
- if (dead) return
868
- if (retryable(code)) return setTimeout(polling, calcNextBackoff(backoff), backoff + 1)
708
+ if (is_dead) return
709
+ callAPI('get', apiUrl + 'poll?token=' + lastToken + '&account-id=' + accid, undefined, function (body, code) {
710
+ if (is_dead) return
711
+ if (retryable(code)) {
712
+ is_polling_stuck = true
713
+ return setTimeout(polling, calcNextBackoff(backoff), backoff + 1)
714
+ }
715
+
869
716
  if (code !== 200) {
870
717
  // unretryable error, should kill
871
- dead = true
872
- return onDead('poll')
718
+ is_polling_stuck = true
719
+ return kill('poll')
873
720
  }
874
721
 
875
722
  // 200, success
723
+ is_polling_stuck = false
876
724
  body = parseJSON(body) || {}
877
725
  if (body.host) apiUrl = absUrl(body.host)
878
726
 
879
727
  var seqToken = body.sequential_token
880
- // the server returns a malform payload. We should retry and hope it heal soon
881
- if (!seqToken) return setTimeout(polling, calcNextBackoff(backoff), backoff + 1)
728
+ // the server returns a malform payload. We should end
729
+ if (!seqToken) return kill('poll')
882
730
  lastToken = seqToken
883
731
  onEvents(body.events || [])
884
732
  return polling(0)
885
733
  })
886
734
  }
887
735
 
888
- var subQueue = flow.batch(50, 100, function (events) {
889
- if (dead) return ['dead']
890
- if (events.length <= 0) return []
891
-
892
- var out = []
893
- return flow
894
- .loop(function () {
895
- return new Promise(function (rs) {
896
- var query = '?token=' + lastToken
897
- credential.getAccessToken().then(function (access_token) {
898
- if (credential.user_ref) query += '&user_ref=' + encodeURIComponent(credential.user_ref)
899
- else if (credential.user_mask) query += '&user-mask=' + encodeURIComponent(credential.user_mask)
900
- else if (access_token) query += '&access-token=' + access_token
901
-
902
- let fullurl = apiUrl + 'subs' + query + '&version=2&account-id=' + encodeURIComponent(accid || credential.account_id)
903
- callAPI('post', fullurl, JSON.stringify({events: events}), function (body, code) {
904
- if (dead) {
905
- out = repeat('dead', events.length)
906
- return rs(false) // break loop
907
- }
908
-
909
- if (retryable(code)) return setTimeout(rs, 3000, true)
910
- // unretryable error
911
- if (code !== 200) {
912
- // we are unable to start the communication with realtime server.
913
- // Must notify the user by killing the connection
914
- dead = true
915
- onDead('subscribe', body, code)
916
- out = repeat('dead', events.length)
917
- return rs(false)
918
- }
919
-
920
- if (lastToken) return rs(false)
921
-
922
- // first time sub, should grab the initial token
923
- body = parseJSON(body) || {}
924
- var initialToken = body.initial_token
925
- // the server returns a malform payload. We should retry and hope it heal soon
926
- if (!initialToken) return setTimeout(rs, 3000, true)
927
- if (body.host) apiUrl = absUrl(body.host)
928
-
929
- lastToken = initialToken
930
- polling(0)
736
+ var subQueue = flow.batch(50, 100, function (topics) {
737
+ if (is_dead) return Promise.resolve(repeat('dead', topics.length))
738
+ if (topics.length <= 0) return Promise.resolve([])
739
+
740
+ var resolve
741
+ var promise = new Promise((rs) => {
742
+ resolve = rs
743
+ })
744
+
745
+ var done = false
746
+ setTimeout(function () {
747
+ if (!done && !is_dead) is_sub_stuck = true
748
+ }, 4000)
749
+
750
+ setTimeout(() => {
751
+ // too long, kill
752
+ if (done) return
753
+ done = true
754
+ resolve(repeat('dead', topics.length))
755
+ if (is_dead) return
756
+ kill('subs')
757
+ }, 60000)
758
+
759
+ flow.loop(function () {
760
+ return new Promise(function (rs) {
761
+ if (is_dead) {
762
+ resolve(repeat('dead', topics.length))
763
+ return rs(false) // break loop
764
+ }
765
+
766
+ var query = '?token=' + lastToken
767
+ credential.getAccessToken().then(function (access_token) {
768
+ if (is_dead) {
769
+ resolve(repeat('dead', topics.length))
770
+ return rs(false) // break loop
771
+ }
772
+
773
+ if (credential.user_ref) query += '&user_ref=' + encodeURIComponent(credential.user_ref)
774
+ else if (credential.user_mask) query += '&user-mask=' + encodeURIComponent(credential.user_mask)
775
+ else if (access_token) query += '&access-token=' + access_token
776
+
777
+ var fullurl = apiUrl + 'subs' + query + '&account-id=' + encodeURIComponent(accid || credential.account_id)
778
+ callAPI('post', fullurl, JSON.stringify({events: topics}), function (body, code) {
779
+ if (done) return
780
+ if (is_dead) {
781
+ resolve(repeat('dead', topics.length))
782
+ return rs(false) // break loop
783
+ }
784
+
785
+ if (retryable(code)) {
786
+ is_sub_stuck = true
787
+ return setTimeout(rs, 3000, true)
788
+ }
789
+
790
+ // unretryable error
791
+ if (code !== 200) {
792
+ // we are unable to start the communication with the realtime server.
793
+ // Must notify the user by killing the connection
794
+ kill('subs')
795
+ resolve(repeat('dead', topics.length))
931
796
  return rs(false)
932
- })
797
+ }
798
+ is_sub_stuck = false
799
+ done = true
800
+ if (lastToken) {
801
+ resolve(topics)
802
+ return rs(false)
803
+ }
804
+
805
+ // first time sub, should grab the initial token
806
+ body = parseJSON(body) || {}
807
+ var initialToken = body.initial_token
808
+ // the server returns a malform payload. We should end
809
+ if (!initialToken) {
810
+ kill('subs')
811
+ resolve(repeat('dead', topics.length))
812
+ return rs(false) // break loop
813
+ }
814
+
815
+ // learn new host
816
+ if (body.host) apiUrl = absUrl(body.host)
817
+
818
+ lastToken = initialToken
819
+ polling(0)
820
+ resolve(topics)
821
+ return rs(false) // to break the loop
933
822
  })
934
823
  })
935
824
  })
936
- .then(function () {
937
- return out
938
- })
825
+ })
826
+
827
+ return promise
939
828
  })
940
829
 
941
830
  // subscribe call /subs API to tell server that we are listening for those events
942
831
  // this function may start polling loop if it hasn't been started yet
943
- // Note: this function is not design to be thread safed so, do not call this
944
- // function multiple times at once
832
+ // its safe to call this function multiple times
945
833
  this.subscribe = subQueue.push.bind(subQueue)
834
+
835
+ this.getStatus = function () {
836
+ if (is_dead) return 'dead'
837
+ if (is_sub_stuck || is_polling_stuck) return 'connecting'
838
+ return 'active'
839
+ }
840
+
841
+ // kill force the connection to dead state
842
+ var kill = function (reason) {
843
+ is_dead = true
844
+ onDead(reason)
845
+ }
846
+ this.kill = kill
946
847
  }
947
848
 
948
- // Realtime is just a stronger Conn.
949
- // This class helps you subscribe and listen realtime event from the
849
+ // Realtime helps you subscribe and listen realtime event from th
950
850
  // realtime server
951
- // additional features compare to conn:
952
- // + auto recreate and resub if the last conn is dead
953
- // + don't subscribe already subscribed events
954
- function Realtime(apiUrls, credential, callAPI, accid) {
851
+ // Realtime is just a stronger Conn.
852
+ function Realtime(apiUrls, credential, callAPI, accid, skipautoreconnect) {
955
853
  if (typeof apiUrls === 'string' || apiUrls instanceof String) apiUrls = [apiUrls]
956
854
  credential = credential || {}
957
855
  if (!credential.getAccessToken) {
@@ -963,19 +861,13 @@ function Realtime(apiUrls, credential, callAPI, accid) {
963
861
  var pubsub = new Pubsub()
964
862
 
965
863
  // holds all topics that realtime must subscribed
966
- // {
967
- // a: 'online',
968
- // b: 'offline',
969
- // c: 'connecting',
970
- // }
971
864
  var topics = {}
972
865
 
973
866
  // stop the connection
974
- var stop = false
975
867
  this.stop = function () {
976
- if (!conn || stop) return
977
- stop = true
868
+ if (!conn) return
978
869
  conn.kill()
870
+ conn = undefined
979
871
  pubsub.emit('interrupted')
980
872
  }
981
873
 
@@ -987,9 +879,13 @@ function Realtime(apiUrls, credential, callAPI, accid) {
987
879
  return pubsub.on('interrupted', cb)
988
880
  }
989
881
 
990
- var conn
882
+ this.getStatus = function () {
883
+ if (!conn) return 'dead'
884
+ return conn.getStatus()
885
+ }
886
+
991
887
  this.subscribe = function (events) {
992
- if (stop) return Promise.resolve({})
888
+ if (!conn) return Promise.resolve({error: 'dead'})
993
889
  if (typeof events === 'string') events = [events]
994
890
  if (!Array.isArray(events)) return Promise.resolve({error: 'param should be an array or string'})
995
891
 
@@ -998,46 +894,46 @@ function Realtime(apiUrls, credential, callAPI, accid) {
998
894
  for (var i = 0; i < events.length; i++) {
999
895
  var topic = events[i]
1000
896
  if (!topic) continue
1001
- if (!topics[topic]) all.push(conn.subscribe(topic))
897
+ if (topics[topic]) continue
898
+ topics[topic] = true // mark so next time we wont subscribe this event (topic) again
899
+ all.push(conn.subscribe(topic))
1002
900
  }
1003
901
  if (all.length === 0) return Promise.resolve({})
1004
- return Promise.all(all).then(function (errs) {
1005
- for (var i = 0; i < errs.length; i++) if (errs[i]) return {error: errs[i]}
1006
- for (var j = 0; j < events.length; j++) topics[events[j]] = true
902
+ return Promise.all(all).then(function () {
903
+ if (!conn || conn.getStatus() == 'dead') return {error: 'dead'}
1007
904
  return {}
1008
905
  })
1009
906
  }
1010
907
 
1011
908
  // reconnect make sure there is alway a Conn running in the background
1012
909
  // if the Conn is dead, it recreate a new one
1013
- var reconnect = function () {
1014
- if (stop) return
1015
- // reset subscribed topic
1016
- var allTopics = Object.keys(topics)
1017
- for (var i = 0; i < allTopics.length; i++) topics[allTopics[i]] = false
1018
-
910
+ var conn
911
+ this.reconnect = function () {
1019
912
  var randomUrl = apiUrls[Math.floor(Math.random() * apiUrls.length)]
1020
- conn = new Conn(
913
+ if (conn) conn.kill() // kill old connection
914
+ let myconn = new Conn(
1021
915
  randomUrl,
1022
916
  credential,
1023
917
  function (code, body, status) {
1024
- if (stop) return
918
+ if (myconn != conn) return // outdated
1025
919
  pubsub.emit('interrupted', code, body, status)
1026
- setTimeout(reconnect, 2000) // reconnect and resubscribe after 2 sec
920
+ if (!skipautoreconnect) setTimeout(this.reconnect, 2000) // reconnect and resubscribe after 2 sec
1027
921
  },
1028
- function (topics) {
1029
- if (stop) return
1030
- for (var i = 0; i < topics.length; i++) pubsub.emit('event', topics[i])
922
+ function (events) {
923
+ if (myconn != conn) return
924
+ for (var i = 0; i < events.length; i++) pubsub.emit('event', events[i])
1031
925
  },
1032
926
  callAPI,
1033
927
  accid,
1034
928
  )
929
+ conn = myconn
1035
930
 
931
+ var copyTopics = Object.keys(topics)
932
+ topics = {}
1036
933
  // resubscribe all subscribed events
1037
- var topicKeys = Object.keys(topics)
1038
- for (var i = 0; i < topicKeys.length; i++) conn.subscribe(topicKeys[i])
934
+ return this.subscribe(copyTopics)
1039
935
  }
1040
- reconnect()
936
+ this.reconnect()
1041
937
  }
1042
938
 
1043
939
  // calcNextBackoff returns number of seconds we must wait
@@ -1264,244 +1160,14 @@ function eqFloat(a, b) {
1264
1160
 
1265
1161
  /***/ }),
1266
1162
 
1267
- /***/ 3118:
1163
+ /***/ 3259:
1268
1164
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1269
1165
 
1270
1166
  "use strict";
1167
+ __webpack_require__.r(__webpack_exports__);
1271
1168
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1272
- /* harmony export */ A: () => (/* binding */ Chain)
1273
- /* harmony export */ });
1274
- const ChainMaxSize = 50;
1275
- class Chain {
1276
- constructor(db, schema, inmem) {
1277
- this.schema = schema + '_chain';
1278
- this.dead = false;
1279
- this.db = db;
1280
- this.anchorCache = {};
1281
- this.cache = {};
1282
- this.init();
1283
- }
1284
- init() {
1285
- let inmemItemM = {};
1286
- let allitems = this.db.all('items');
1287
- allitems.map(item => {
1288
- inmemItemM[item.chain] = inmemItemM[item.chain] || {};
1289
- inmemItemM[item.chain][item.id] = {
1290
- id: item.id,
1291
- chain: item.chain,
1292
- full_id: item.full_id,
1293
- index: item.index,
1294
- value: item.value
1295
- };
1296
- });
1297
- map(inmemItemM, (itemM, chain) => {
1298
- if (size(itemM) < ChainMaxSize) return;
1299
- let items = orderBy(map(itemM), ['index'], 'desc');
1300
- let removekeys = [];
1301
- for (var i = ChainMaxSize; i < items.length; i++) {
1302
- removekeys.push(items[i].full_id);
1303
- delete itemM[items[i].id];
1304
- }
1305
- this.db.removes('items', removekeys);
1306
- inmemItemM[chain] = itemM;
1307
- });
1308
- this.cache = inmemItemM;
1309
- }
1310
- destroy() {
1311
- this.db.clear('items');
1312
- this.dead = true;
1313
- this.cache = {};
1314
- this.anchorCache = {};
1315
- this.db = undefined;
1316
- }
1317
- put(chain, id, node_index, value) {
1318
- if (this.dead) return;
1319
- let inmemItemM = this.cache[chain] || {};
1320
- let bottom = minIndex(inmemItemM) || {};
1321
- let bottomIndex = bottom.index || 'z';
1322
- let item = {
1323
- id,
1324
- index: node_index,
1325
- value,
1326
- chain,
1327
- full_id: chain + ':' + id
1328
- };
1329
- delete inmemItemM[item.id];
1330
- if (bottomIndex > item.index + '') return;
1331
- inmemItemM[item.id] = item;
1332
- this.cache[chain] = inmemItemM;
1333
- this.db.put('items', item.full_id, item);
1334
- }
1335
- listM(chain) {
1336
- if (this.dead) return {};
1337
- let inmemItemM = this.cache[chain] || {};
1338
- let out = {};
1339
- map(inmemItemM, (item, id) => {
1340
- out[id] = item.value;
1341
- });
1342
- return out;
1343
- }
1344
- async fetchMore(chain, limit = 20, api) {
1345
- if (this.dead) return {
1346
- error: 'dead'
1347
- };
1348
- if (!api) return {
1349
- error: 'no api'
1350
- };
1351
- let anchor = this.anchorCache[chain] || '';
1352
- var [apiItems, newanchor, error] = await api(chain, anchor, limit);
1353
- if (error) return {
1354
- error
1355
- };
1356
- if (this.dead) return {
1357
- error: 'dead'
1358
- };
1359
- let inmemItemM = this.cache[chain] || {};
1360
- if (apiItems.length === 0) return {
1361
- end: true
1362
- };
1363
- apiItems.forEach(item => {
1364
- item.chain = chain;
1365
- item.full_id = chain + ':' + item.id;
1366
- inmemItemM[item.id] = item;
1367
- this.db.put('items', item.full_id, item);
1368
- });
1369
- this.anchorCache[chain] = newanchor;
1370
- this.cache[chain] = inmemItemM;
1371
- return {};
1372
- }
1373
- del(chain, id) {
1374
- if (this.dead) return;
1375
- let inmemItemM = this.cache[chain] || {};
1376
- let full_id = chain + ':' + id;
1377
- delete inmemItemM[id];
1378
- this.db.removes('items', [full_id]);
1379
- }
1380
- match(chain, id) {
1381
- return this.listM(chain)[id];
1382
- }
1383
- async reload(chain, api) {
1384
- if (this.dead) return;
1385
- let top = maxIndex(this.listM(chain)) || {};
1386
- let topindex = top.index;
1387
- if (!topindex) topindex = Date.now();
1388
- var lastanchor = '';
1389
- var fetchedItems = {};
1390
- for (;;) {
1391
- if (this.dead) return;
1392
- let [newItems, newanchor, error] = await api(chain, lastanchor, 50);
1393
- if (error) return;
1394
- if (this.dead) return;
1395
- newItems.map(item => {
1396
- fetchedItems[item.id] = Object.assign({}, item, {
1397
- chain,
1398
- full_id: chain + ':' + item.id
1399
- });
1400
- });
1401
- if (newItems.length === 0 || newanchor === lastanchor) break;
1402
- if (fetchedItems.length >= 200) {
1403
- let inmemItemM = this.cache[chain] || {};
1404
- let removeids = [];
1405
- map(inmemItemM, item => {
1406
- if (item.chain !== chain) return;
1407
- removeids.push(item.full_id);
1408
- });
1409
- this.db.removes('items', removeids);
1410
- this.cache[chain] = {};
1411
- break;
1412
- }
1413
- let minindexitem = minIndex(fetchedItems) || {};
1414
- if (minindexitem.index <= topindex) {
1415
- lastanchor = this.anchorCache[chain] || newanchor;
1416
- break;
1417
- }
1418
- lastanchor = newanchor;
1419
- }
1420
- for (var i = 0; i < Object.keys(fetchedItems).length; i++) {
1421
- let item = fetchedItems[Object.keys(fetchedItems)[i]];
1422
- this.db.put('items', item.full_id, item);
1423
- this.cache[item.chain] = this.cache[item.chain] || {};
1424
- this.cache[item.chain][item.id] = item;
1425
- }
1426
- this.anchorCache[chain] = lastanchor;
1427
- }
1428
- }
1429
- function minIndex(obj) {
1430
- if (!obj) return;
1431
- let keys = Object.keys(obj);
1432
- if (!keys.length) return;
1433
- let min = Infinity;
1434
- let minKey = Object.keys(obj)[0];
1435
- for (var i = 0; i < keys.length; i++) {
1436
- let index = obj[keys[i]] && obj[keys[i]].index || Infinity;
1437
- if (index < min) {
1438
- min = index;
1439
- minKey = keys[i];
1440
- }
1441
- }
1442
- return obj[minKey];
1443
- }
1444
- function maxIndex(obj) {
1445
- if (!obj) return;
1446
- let keys = Object.keys(obj);
1447
- if (!keys.length) return;
1448
- let max = -Infinity;
1449
- let maxKey = Object.keys(obj)[0];
1450
- for (var i = 0; i < keys.length; i++) {
1451
- let index = obj[keys[i]] && obj[keys[i]].index || -Infinity;
1452
- if (index > max) {
1453
- max = index;
1454
- maxKey = keys[i];
1455
- }
1456
- }
1457
- return obj[keys[maxKey]];
1458
- }
1459
- function map(collection, predicate) {
1460
- if (!collection) return [];
1461
- if (!predicate) return collection;
1462
- var out = [];
1463
- if (Array.isArray(collection)) {
1464
- for (let i = 0; i < collection.length; i++) {
1465
- out.push(predicate(collection[i], i));
1466
- }
1467
- return out;
1468
- }
1469
- if (typeof collection === 'object') {
1470
- var keys = Object.keys(collection);
1471
- for (let i = 0; i < keys.length; i++) {
1472
- var k = keys[i];
1473
- out.push(predicate(collection[k], k));
1474
- }
1475
- return out;
1476
- }
1477
- return out;
1478
- }
1479
- function size(o) {
1480
- if (!o) return 0;
1481
- if (o.length !== undefined) return o.length;
1482
- return Object.keys(o).length;
1483
- }
1484
- function orderBy(a, k, d) {
1485
- var clone = [];
1486
- map(a, v => clone.push(v));
1487
- clone.sort((i, j) => {
1488
- if (i[k] === j[k]) return 0;
1489
- var r = i[k] < j[k] ? -1 : 1;
1490
- return d === 'desc' ? -r : r;
1491
- });
1492
- return clone;
1493
- }
1494
-
1495
- /***/ }),
1496
-
1497
- /***/ 3259:
1498
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1499
-
1500
- "use strict";
1501
- __webpack_require__.r(__webpack_exports__);
1502
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1503
- /* harmony export */ get: () => (/* binding */ get),
1504
- /* harmony export */ set: () => (/* binding */ set)
1169
+ /* harmony export */ get: () => (/* binding */ get),
1170
+ /* harmony export */ set: () => (/* binding */ set)
1505
1171
  /* harmony export */ });
1506
1172
  var toStr = Object.prototype.toString;
1507
1173
  var isArray = Array.isArray || function (obj) {
@@ -2183,8 +1849,8 @@ var xhrsend = function (method, url, body, cb) {
2183
1849
  request.send(body)
2184
1850
  }
2185
1851
 
2186
- // JSON.parse without exeption
2187
- // return undefined when parsing invalid JSON string
1852
+ // JSON.parse without exception
1853
+ // return undefined when input is an invalid JSON
2188
1854
  function parseJSON(str) {
2189
1855
  try {
2190
1856
  return JSON.parse(str)
@@ -2312,10 +1978,7 @@ function trackInactivity(seconds = 0, cb) {
2312
1978
  document.addEventListener(ev, resetTime, false);
2313
1979
  }
2314
1980
  }
2315
- let timeOnPage = 0;
2316
- campaign_common.setInterval(() => {
2317
- timeOnPage += 5;
2318
- }, 5000);
1981
+ let _pageLoaded = campaign_common.Date.now();
2319
1982
  function trackTimeOnPage(seconds = 0, cb) {
2320
1983
  if (seconds < 1) {
2321
1984
  return campaign_common.setTimeout(function () {
@@ -2323,10 +1986,11 @@ function trackTimeOnPage(seconds = 0, cb) {
2323
1986
  }, 100);
2324
1987
  }
2325
1988
  let timer = campaign_common.setInterval(() => {
1989
+ let timeOnPage = (campaign_common.Date.now() - _pageLoaded) / 1000;
2326
1990
  if (timeOnPage < seconds) return;
2327
1991
  if (cb) cb(timeOnPage);
2328
1992
  campaign_common.clearInterval(timer);
2329
- }, 1000);
1993
+ }, 200);
2330
1994
  }
2331
1995
  function on(eventName, selector, fn) {
2332
1996
  document.addEventListener(eventName, function (event) {
@@ -2524,6 +2188,7 @@ __webpack_require__.r(__webpack_exports__);
2524
2188
  /* harmony export */ getUserAttr: () => (/* binding */ getUserAttr),
2525
2189
  /* harmony export */ hslToRgb: () => (/* binding */ hslToRgb),
2526
2190
  /* harmony export */ includes: () => (/* binding */ includes),
2191
+ /* harmony export */ isBlockEmpty: () => (/* binding */ isBlockEmpty),
2527
2192
  /* harmony export */ isConvoSeen: () => (/* binding */ isConvoSeen),
2528
2193
  /* harmony export */ isEmail: () => (/* binding */ isEmail),
2529
2194
  /* harmony export */ isNumber: () => (/* binding */ isNumber),
@@ -3708,6 +3373,20 @@ const ALL_CURRENCIES = [{
3708
3373
  function blockToText(block) {
3709
3374
  return _blockToText(block).trim();
3710
3375
  }
3376
+ function isBlockEmpty(block) {
3377
+ return _isBlockEmpty(block);
3378
+ }
3379
+ function _isBlockEmpty(block = {}) {
3380
+ if (!size(block.content)) {
3381
+ if ((block.text || '').trim()) return false;
3382
+ return true;
3383
+ }
3384
+ let result = true;
3385
+ map(block.content, content => {
3386
+ result = result && _isBlockEmpty(content);
3387
+ });
3388
+ return result;
3389
+ }
3711
3390
  function _blockToText(block) {
3712
3391
  if (!block || !block.type) return '';
3713
3392
  let out = '';
@@ -4008,17 +3687,6 @@ var __webpack_exports__ = {};
4008
3687
 
4009
3688
  // EXTERNAL MODULE: ./src/util/index.js + 1 modules
4010
3689
  var util = __webpack_require__(8150);
4011
- ;// ./node_modules/@subiz/storage/index.js
4012
- var kv = (__webpack_require__(1314)/* ["default"] */ .A);
4013
- var chain = (__webpack_require__(3118)/* ["default"] */ .A);
4014
- var inmem_localstorage = (__webpack_require__(1554)/* ["default"] */ .A);
4015
- var lsdb = (__webpack_require__(1428)/* ["default"] */ .A);
4016
- /* harmony default export */ const storage = ({
4017
- kv,
4018
- lsdb,
4019
- chain,
4020
- inmem_localstorage
4021
- });
4022
3690
  ;// ./src/store/api.js
4023
3691
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4024
3692
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
@@ -4125,6 +3793,8 @@ function jsonifyTextPlain(param, done) {
4125
3793
  _defineProperty(this, "list_provinces", () => this.apireq.get(`/accounts/${this.accid}/provinces`));
4126
3794
  _defineProperty(this, "list_districts", p => this.apireq.setQuery(p).get(`/accounts/${this.accid}/districts`));
4127
3795
  _defineProperty(this, "list_wards", p => this.apireq.setQuery(p).get(`/accounts/${this.accid}/wards`));
3796
+ _defineProperty(this, "checkFormToken", token => this.api41.get(`/submissions/${token}`));
3797
+ _defineProperty(this, "submitForm2", (token, data) => this.api41.post(`/submissions/${token}`, data));
4128
3798
  _defineProperty(this, "suggest_address", keyword => this.apireq.setQuery({
4129
3799
  keyword: keyword
4130
3800
  }).get(`/accounts/${this.accid}/addresses`));
@@ -4132,6 +3802,7 @@ function jsonifyTextPlain(param, done) {
4132
3802
  this.refreshLock = new util/* default */.A.Mutex();
4133
3803
  this.FileURL = FileURL;
4134
3804
  this.ApiURL = ApiURL;
3805
+ this.api41 = ajax.setBaseUrl('https://api5.subiz.com.vn/4.1').withCredentials(true).setContentType('text/plain').beforeHook(jsonifyTextPlain).setParser('json');
4135
3806
  this.apireq = ajax.setBaseUrl(ApiURL).withCredentials(true).addQuery('v', '6').setContentType('text/plain').beforeHook(jsonifyTextPlain).setParser('json').beforeHook((param, done) => {
4136
3807
  if (this.token_generator) {
4137
3808
  let user_id = this.profile_id;
@@ -4269,31 +3940,394 @@ function jsonifyTextPlain(param, done) {
4269
3940
  id: this.uid
4270
3941
  };
4271
3942
  }
4272
- return {
4273
- error: 'invalid_auth'
4274
- };
3943
+ return {
3944
+ error: 'invalid_auth'
3945
+ };
3946
+ }
3947
+ sendContentView(device, pageUrl, pageTitle, id, source_id, sku) {
3948
+ if (!id) id = undefined;
3949
+ if (!source_id) source_id = undefined;
3950
+ return this.sendEvent({
3951
+ by: {
3952
+ id: this.uid,
3953
+ device: device
3954
+ },
3955
+ type: 'content_viewed',
3956
+ data: {
3957
+ product: {
3958
+ id: id,
3959
+ source_id: source_id,
3960
+ url: pageUrl,
3961
+ name: pageTitle,
3962
+ title: pageTitle,
3963
+ sku: sku
3964
+ }
3965
+ }
3966
+ });
3967
+ }
3968
+ });
3969
+ ;// ./src/store/lsdb.js
3970
+ let memlocalStorage = __webpack_require__(450);
3971
+
3972
+ let requestIdleCallback = typeof window !== 'undefined' ? window.requestIdleCallback : null;
3973
+ if (!requestIdleCallback) requestIdleCallback = cb => cb();
3974
+ const LIMIT = 80;
3975
+ /* harmony default export */ const lsdb = (class {
3976
+ constructor(schema, inmem) {
3977
+ this.localStorage = memlocalStorage;
3978
+ this.inmem = inmem;
3979
+ this.allkeys = {};
3980
+ if (!inmem) {
3981
+ try {
3982
+ window.localStorage.setItem('sbzstore1029', '?');
3983
+ window.localStorage.removeItem('sbzstore1029');
3984
+ this.localStorage = window.localStorage;
3985
+ } catch (e) {}
3986
+ }
3987
+ this.schema = schema;
3988
+ }
3989
+ all(table) {
3990
+ let items = [];
3991
+ for (var i = 0; i < this.localStorage.length; i++) {
3992
+ let key = this.localStorage.key(i);
3993
+ if (!key.startsWith(this.schema + '#' + table + '#')) continue;
3994
+ this.allkeys[key] = true;
3995
+ if (this.inmem) items.push(this.localStorage.getItem(key));else items.push(util/* default */.A.parseJSON(this.localStorage.getItem(key)));
3996
+ }
3997
+ return items;
3998
+ }
3999
+ removes(table, keys) {
4000
+ for (var i = 0; i < keys.length; i++) {
4001
+ delete this.allkeys[this.schema + '#' + table + '#' + keys[i]];
4002
+ this.localStorage.removeItem(this.schema + '#' + table + '#' + keys[i]);
4003
+ }
4004
+ }
4005
+ clear(table) {
4006
+ for (var i = 0; i < this.localStorage.length; i++) {
4007
+ let key = this.localStorage.key(i);
4008
+ if (!key.startsWith(this.schema + '#' + table + '#')) continue;
4009
+ this.localStorage.removeItem(key);
4010
+ }
4011
+ this.allkeys = {};
4012
+ }
4013
+ put(table, key, value) {
4014
+ this.allkeys[this.schema + '#' + table + '#' + key] = true;
4015
+ if (this.inmem) return this.localStorage.setItem(this.schema + '#' + table + '#' + key, value);
4016
+ if (Object.keys(this.allkeys).length > LIMIT) this.clear(table);
4017
+ requestIdleCallback(() => {
4018
+ try {
4019
+ this.localStorage.setItem(this.schema + '#' + table + '#' + key, lsdb_toString(value));
4020
+ } catch (e) {
4021
+ this.clear(table);
4022
+ }
4023
+ });
4024
+ }
4025
+ });
4026
+ function lsdb_toString(obj) {
4027
+ if (obj === undefined) return 'null';
4028
+ return JSON.stringify(obj);
4029
+ }
4030
+ ;// ./src/store/chain.js
4031
+ const ChainMaxSize = 50;
4032
+ class Chain {
4033
+ constructor(db, schema, inmem) {
4034
+ this.schema = schema + '_chain';
4035
+ this.dead = false;
4036
+ this.db = db;
4037
+ this.anchorCache = {};
4038
+ this.cache = {};
4039
+ this.init();
4040
+ }
4041
+ init() {
4042
+ let inmemItemM = {};
4043
+ let allitems = this.db.all('items');
4044
+ allitems.map(item => {
4045
+ inmemItemM[item.chain] = inmemItemM[item.chain] || {};
4046
+ inmemItemM[item.chain][item.id] = {
4047
+ id: item.id,
4048
+ chain: item.chain,
4049
+ full_id: item.full_id,
4050
+ index: item.index,
4051
+ value: item.value
4052
+ };
4053
+ });
4054
+ map(inmemItemM, (itemM, chain) => {
4055
+ if (size(itemM) < ChainMaxSize) return;
4056
+ let items = orderBy(map(itemM), ['index'], 'desc');
4057
+ let removekeys = [];
4058
+ for (var i = ChainMaxSize; i < items.length; i++) {
4059
+ removekeys.push(items[i].full_id);
4060
+ delete itemM[items[i].id];
4061
+ }
4062
+ this.db.removes('items', removekeys);
4063
+ inmemItemM[chain] = itemM;
4064
+ });
4065
+ this.cache = inmemItemM;
4066
+ }
4067
+ destroy() {
4068
+ this.db.clear('items');
4069
+ this.dead = true;
4070
+ this.cache = {};
4071
+ this.anchorCache = {};
4072
+ this.db = undefined;
4073
+ }
4074
+ put(chain, id, node_index, value) {
4075
+ if (this.dead) return;
4076
+ let inmemItemM = this.cache[chain] || {};
4077
+ let bottom = minIndex(inmemItemM) || {};
4078
+ let bottomIndex = bottom.index || 'z';
4079
+ if (size(inmemItemM) == 0) bottomIndex = '';
4080
+ let item = {
4081
+ id,
4082
+ index: node_index,
4083
+ value,
4084
+ chain,
4085
+ full_id: chain + ':' + id
4086
+ };
4087
+ delete inmemItemM[item.id];
4088
+ if (bottomIndex > item.index + '') return;
4089
+ inmemItemM[item.id] = item;
4090
+ this.cache[chain] = inmemItemM;
4091
+ this.db.put('items', item.full_id, item);
4092
+ }
4093
+ listM(chain) {
4094
+ if (this.dead) return {};
4095
+ let inmemItemM = this.cache[chain] || {};
4096
+ let out = {};
4097
+ map(inmemItemM, (item, id) => {
4098
+ out[id] = item.value;
4099
+ });
4100
+ return out;
4101
+ }
4102
+ async fetchMore(chain, limit = 20, api) {
4103
+ if (this.dead) return {
4104
+ error: 'dead'
4105
+ };
4106
+ if (!api) return {
4107
+ error: 'no api'
4108
+ };
4109
+ let anchor = this.anchorCache[chain] || '';
4110
+ var [apiItems, newanchor, error] = await api(chain, anchor, limit);
4111
+ if (error) return {
4112
+ error
4113
+ };
4114
+ if (this.dead) return {
4115
+ error: 'dead'
4116
+ };
4117
+ let inmemItemM = this.cache[chain] || {};
4118
+ if (apiItems.length === 0) return {
4119
+ end: true
4120
+ };
4121
+ apiItems.forEach(item => {
4122
+ item.chain = chain;
4123
+ item.full_id = chain + ':' + item.id;
4124
+ inmemItemM[item.id] = item;
4125
+ this.db.put('items', item.full_id, item);
4126
+ });
4127
+ this.anchorCache[chain] = newanchor;
4128
+ this.cache[chain] = inmemItemM;
4129
+ return {};
4130
+ }
4131
+ del(chain, id) {
4132
+ if (this.dead) return;
4133
+ let inmemItemM = this.cache[chain] || {};
4134
+ let full_id = chain + ':' + id;
4135
+ delete inmemItemM[id];
4136
+ this.db.removes('items', [full_id]);
4137
+ }
4138
+ match(chain, id) {
4139
+ return this.listM(chain)[id];
4140
+ }
4141
+ async reload(chain, api) {
4142
+ if (this.dead) return;
4143
+ let top = maxIndex(this.listM(chain)) || {};
4144
+ let topindex = top.index;
4145
+ if (!topindex) topindex = Date.now();
4146
+ var lastanchor = '';
4147
+ var fetchedItems = {};
4148
+ for (;;) {
4149
+ if (this.dead) return;
4150
+ let [newItems, newanchor, error] = await api(chain, lastanchor, 50);
4151
+ if (error) return;
4152
+ if (this.dead) return;
4153
+ newItems.map(item => {
4154
+ fetchedItems[item.id] = Object.assign({}, item, {
4155
+ chain,
4156
+ full_id: chain + ':' + item.id
4157
+ });
4158
+ });
4159
+ if (newItems.length === 0 || newanchor === lastanchor) break;
4160
+ if (fetchedItems.length >= 200) {
4161
+ let inmemItemM = this.cache[chain] || {};
4162
+ let removeids = [];
4163
+ map(inmemItemM, item => {
4164
+ if (item.chain !== chain) return;
4165
+ removeids.push(item.full_id);
4166
+ });
4167
+ this.db.removes('items', removeids);
4168
+ this.cache[chain] = {};
4169
+ break;
4170
+ }
4171
+ let minindexitem = minIndex(fetchedItems) || {};
4172
+ if (minindexitem.index <= topindex) {
4173
+ lastanchor = this.anchorCache[chain] || newanchor;
4174
+ break;
4175
+ }
4176
+ lastanchor = newanchor;
4177
+ }
4178
+ for (var i = 0; i < Object.keys(fetchedItems).length; i++) {
4179
+ let item = fetchedItems[Object.keys(fetchedItems)[i]];
4180
+ this.db.put('items', item.full_id, item);
4181
+ this.cache[item.chain] = this.cache[item.chain] || {};
4182
+ this.cache[item.chain][item.id] = item;
4183
+ }
4184
+ this.anchorCache[chain] = lastanchor;
4185
+ }
4186
+ }
4187
+ function minIndex(obj) {
4188
+ if (!obj) return;
4189
+ let keys = Object.keys(obj);
4190
+ if (!keys.length) return;
4191
+ let min = Infinity;
4192
+ let minKey = Object.keys(obj)[0];
4193
+ for (var i = 0; i < keys.length; i++) {
4194
+ let index = obj[keys[i]] && obj[keys[i]].index || Infinity;
4195
+ if (index < min) {
4196
+ min = index;
4197
+ minKey = keys[i];
4198
+ }
4199
+ }
4200
+ return obj[minKey];
4201
+ }
4202
+ function maxIndex(obj) {
4203
+ if (!obj) return;
4204
+ let keys = Object.keys(obj);
4205
+ if (!keys.length) return;
4206
+ let max = -Infinity;
4207
+ let maxKey = Object.keys(obj)[0];
4208
+ for (var i = 0; i < keys.length; i++) {
4209
+ let index = obj[keys[i]] && obj[keys[i]].index || -Infinity;
4210
+ if (index > max) {
4211
+ max = index;
4212
+ maxKey = keys[i];
4213
+ }
4214
+ }
4215
+ return obj[keys[maxKey]];
4216
+ }
4217
+ function map(collection, predicate) {
4218
+ if (!collection) return [];
4219
+ if (!predicate) return collection;
4220
+ var out = [];
4221
+ if (Array.isArray(collection)) {
4222
+ for (let i = 0; i < collection.length; i++) {
4223
+ out.push(predicate(collection[i], i));
4224
+ }
4225
+ return out;
4226
+ }
4227
+ if (typeof collection === 'object') {
4228
+ var keys = Object.keys(collection);
4229
+ for (let i = 0; i < keys.length; i++) {
4230
+ var k = keys[i];
4231
+ out.push(predicate(collection[k], k));
4232
+ }
4233
+ return out;
4234
+ }
4235
+ return out;
4236
+ }
4237
+ function size(o) {
4238
+ if (!o) return 0;
4239
+ if (o.length !== undefined) return o.length;
4240
+ return Object.keys(o).length;
4241
+ }
4242
+ function orderBy(a, k, d) {
4243
+ var clone = [];
4244
+ map(a, v => clone.push(v));
4245
+ clone.sort((i, j) => {
4246
+ if (i[k] === j[k]) return 0;
4247
+ var r = i[k] < j[k] ? -1 : 1;
4248
+ return d === 'desc' ? -r : r;
4249
+ });
4250
+ return clone;
4251
+ }
4252
+ ;// ./src/store/kv.js
4253
+ let KvMaxSize = 500;
4254
+ /* harmony default export */ const kv = (class {
4255
+ constructor(db, schema) {
4256
+ this.name = schema;
4257
+ schema += '_kv';
4258
+ this.dead = false;
4259
+ this.db = db;
4260
+ this.cache = {};
4261
+ this.initialized = false;
4262
+ this.init();
4263
+ }
4264
+ refreshCache() {
4265
+ if (this.dead) return;
4266
+ let inmemItemM = {};
4267
+ let allitems = this.db.all('items');
4268
+ allitems.forEach(function (item) {
4269
+ inmemItemM[item.key] = item.value;
4270
+ });
4271
+ this.cache = inmemItemM;
4272
+ }
4273
+ init() {
4274
+ if (this.initialized) return;
4275
+ let inmemItemM = {};
4276
+ console.time('KV' + this.name);
4277
+ let allitems = this.db.all('items');
4278
+ allitems.forEach(function (item) {
4279
+ inmemItemM[item.key] = item.value;
4280
+ });
4281
+ this.cache = inmemItemM;
4282
+ let allkeys = Object.keys(this.cache);
4283
+ if (allkeys.length > KvMaxSize) {
4284
+ let liveChance = KvMaxSize / 2 / allkeys.lenth;
4285
+ let removekeys = [];
4286
+ for (var i = 0; i < KvMaxSize; i++) {
4287
+ let live = Math.random() <= liveChance;
4288
+ if (live) continue;
4289
+ let key = allkeys[i];
4290
+ delete this.cache[key];
4291
+ removekeys.push(key);
4292
+ }
4293
+ this.db.removes('items', [removekeys]);
4294
+ }
4295
+ this.initialized = true;
4296
+ console.timeEnd('KV' + this.name);
4275
4297
  }
4276
- sendContentView(device, pageUrl, pageTitle, id, source_id, sku) {
4277
- if (!id) id = undefined;
4278
- if (!source_id) source_id = undefined;
4279
- return this.sendEvent({
4280
- by: {
4281
- id: this.uid,
4282
- device: device
4283
- },
4284
- type: 'content_viewed',
4285
- data: {
4286
- product: {
4287
- id: id,
4288
- source_id: source_id,
4289
- url: pageUrl,
4290
- name: pageTitle,
4291
- title: pageTitle,
4292
- sku: sku
4293
- }
4294
- }
4298
+ all() {
4299
+ if (this.dead) return [];
4300
+ if (!this.initialized) return [];
4301
+ return this.cache;
4302
+ }
4303
+ match(key) {
4304
+ if (this.dead || !this.initialized) return;
4305
+ if (!key) return;
4306
+ return this.cache[key];
4307
+ }
4308
+ put(key, value) {
4309
+ if (!key) return;
4310
+ if (this.dead) return [];
4311
+ if (!this.initialized) throw new Error('uninitialized');
4312
+ this.cache[key] = value;
4313
+ this.db.put('items', key, {
4314
+ key,
4315
+ value
4295
4316
  });
4296
4317
  }
4318
+ del(key) {
4319
+ if (this.dead) return;
4320
+ if (!this.initialized) throw new Error('uninitialized');
4321
+ delete this.cache[key];
4322
+ this.db.removes('items', [key]);
4323
+ }
4324
+ destroy() {
4325
+ this.db.clear('items');
4326
+ this.dead = true;
4327
+ this.db = undefined;
4328
+ this.cache = undefined;
4329
+ this.initialized = false;
4330
+ }
4297
4331
  });
4298
4332
  ;// ./src/store/api_fake.js
4299
4333
  function api_fake_defineProperty(e, r, t) { return (r = api_fake_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -4679,6 +4713,10 @@ function makeFakeMessages(accid, convoid, userid, agentid) {
4679
4713
  onInterrupted() {}
4680
4714
  subscribe() {}
4681
4715
  stop() {}
4716
+ getStatus() {
4717
+ return 'active';
4718
+ }
4719
+ reconnect() {}
4682
4720
  });
4683
4721
  ;// ./src/store/store.js
4684
4722
  function store_defineProperty(e, r, t) { return (r = store_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -4690,6 +4728,8 @@ var flow = __webpack_require__(8193);
4690
4728
 
4691
4729
 
4692
4730
 
4731
+
4732
+
4693
4733
  var Realtime = __webpack_require__(2839);
4694
4734
  var cookie = __webpack_require__(5672);
4695
4735
  cookie.defaults.path = '/';
@@ -4701,6 +4741,7 @@ class Store {
4701
4741
  constructor(ApiURL, FileURL, RealtimeURL, inmem, fakeapi) {
4702
4742
  store_defineProperty(this, "inmem", false);
4703
4743
  store_defineProperty(this, "cookie", cookie);
4744
+ store_defineProperty(this, "getConnectionStatus", () => this.connectionStatus);
4704
4745
  store_defineProperty(this, "_currentViewingProduct", {});
4705
4746
  store_defineProperty(this, "new_visitor", true);
4706
4747
  store_defineProperty(this, "matchUser", () => {
@@ -4808,6 +4849,8 @@ class Store {
4808
4849
  store_defineProperty(this, "matchIsOpen", () => !!this.kv.match('isopen'));
4809
4850
  store_defineProperty(this, "matchHasManuallyClosed", () => !!this.kv.match('hasManuallyClosed'));
4810
4851
  store_defineProperty(this, "matchClosePreviewAt", () => this.kv.match('close_preview_at') || 0);
4852
+ store_defineProperty(this, "checkFormToken", token => this.api.checkFormToken(token));
4853
+ store_defineProperty(this, "submitForm2", (token, data) => this.api.submitForm2(token, data));
4811
4854
  store_defineProperty(this, "sendPresence", util/* default */.A.throttle(async () => {
4812
4855
  if (this._die) return dieErr;
4813
4856
  await this.readyGate.entry();
@@ -4834,6 +4877,7 @@ class Store {
4834
4877
  this.seenQueue.push(id);
4835
4878
  });
4836
4879
  store_defineProperty(this, "onUpdate", (o, cb) => this.pubsub.on2(o, 'account', cb));
4880
+ store_defineProperty(this, "onConnection", (o, cb) => this.pubsub.on2(o, 'connection', cb));
4837
4881
  store_defineProperty(this, "onResetCSS", (o, cb) => this.pubsub.on2(o, 'resetCSS', cb));
4838
4882
  store_defineProperty(this, "onHighlight", (o, cb) => this.pubsub.on2(o, 'highlight', cb));
4839
4883
  store_defineProperty(this, "setHasManuallyClosed", () => this.kv.put('hasManuallyClosed', true));
@@ -4855,6 +4899,9 @@ class Store {
4855
4899
  });
4856
4900
  });
4857
4901
  store_defineProperty(this, "timeDiff", 0);
4902
+ this.connectionStatus = 'active';
4903
+ this.CONNECTION_CHECK_INTERVAL = 3000;
4904
+ this.reconnectTimestamp = 0;
4858
4905
  this.g_sync = {};
4859
4906
  this._die = false;
4860
4907
  this.forceDevice = null;
@@ -4881,9 +4928,9 @@ class Store {
4881
4928
  }
4882
4929
  cleanLocalStorage();
4883
4930
  this.pubsub = new util/* default */.A.Pubsub();
4884
- this.kv = new storage.kv(new storage.lsdb('sbz2023', this.inmem), 'kv');
4885
- this.cache = new storage.kv(new storage.lsdb('sbz2023', true), 'kv');
4886
- this.chain = new storage.chain(new storage.lsdb('cbz2023', true), 'ch');
4931
+ this.kv = new kv(new lsdb('sbz2023', this.inmem), 'kv');
4932
+ this.cache = new kv(new lsdb('sbz2023', true), 'kv');
4933
+ this.chain = new Chain(new lsdb('cbz2023', true), 'ch');
4887
4934
  this.getLocaleContent = this.api.getLocaleContent;
4888
4935
  this.g_haveSentSeenM = {};
4889
4936
  this.last_focused = util/* default */.A.Date.now();
@@ -4941,6 +4988,23 @@ class Store {
4941
4988
  }
4942
4989
  }, 2000);
4943
4990
  }
4991
+ async loopCheckConnectionStatus() {
4992
+ while (true) {
4993
+ if (this._die) break;
4994
+ await util/* default */.A.sleep(this.CONNECTION_CHECK_INTERVAL);
4995
+ if (!this.realtime) continue;
4996
+ if (!this.realtime.getStatus || !this.realtime.reconnect) continue;
4997
+ if (this.connectionStatus === 'dead') {
4998
+ await this.realtime.reconnect();
4999
+ }
5000
+ let currentStatus = this.connectionStatus;
5001
+ this.connectionStatus = this.realtime.getStatus();
5002
+ if (currentStatus !== this.connectionStatus) {
5003
+ console.log('publish connectionStatus', this.connectionStatus);
5004
+ this.pubsub.publish('connection');
5005
+ }
5006
+ }
5007
+ }
4944
5008
  linkProduct(p) {
4945
5009
  if (!p) {
4946
5010
  this._currentViewingProduct = {};
@@ -5119,6 +5183,7 @@ class Store {
5119
5183
  });
5120
5184
  this.readyGate.open();
5121
5185
  this.reconnectWs(accid, user.id);
5186
+ this.loopCheckConnectionStatus();
5122
5187
  return user;
5123
5188
  }
5124
5189
  async login(accid, user_id, tokenGenerator) {
@@ -5716,9 +5781,9 @@ class Store {
5716
5781
  if ((k || '').startsWith('__sb')) this.cookie.remove(k);
5717
5782
  });
5718
5783
  this.kv.destroy();
5719
- this.kv = new storage.kv(new storage.lsdb('sbz2023', this.inmem), 'kv');
5784
+ this.kv = new kv(new lsdb('sbz2023', this.inmem), 'kv');
5720
5785
  this.chain.destroy();
5721
- this.chain = new storage.chain(new storage.lsdb('cbz2023', true), 'ch');
5786
+ this.chain = new Chain(new lsdb('cbz2023', true), 'ch');
5722
5787
  }
5723
5788
  destroy() {
5724
5789
  this._die = true;
@@ -5940,9 +6005,15 @@ class ChatButton extends common/* Com */.Mw {
5940
6005
  isquickreplies = true;
5941
6006
  }
5942
6007
  });
5943
- if (isquickreplies) return;
5944
- var tags = util/* default */.A.filter(util/* default */.A.map(this.renderMessagePreview(ev), tag => util/* default */.A.trim(tag)), a => a);
5945
- if (util/* default */.A.size(tags) > 0) this.setState({
6008
+ let format = util/* default */.A.get(ev, 'data.message.format');
6009
+ let block = util/* default */.A.get(ev, 'data.message.block');
6010
+ if (block || format == 'block') {
6011
+ if (util/* default */.A.isBlockEmpty(block) && isquickreplies) return;
6012
+ } else {
6013
+ let message = util/* default */.A.get(ev, 'data.message.text') || '';
6014
+ if (!message && isquickreplies) return;
6015
+ }
6016
+ this.setState({
5946
6017
  displayPreview: true,
5947
6018
  previewEvent: ev
5948
6019
  });
@@ -6256,11 +6327,20 @@ class ChatButton extends common/* Com */.Mw {
6256
6327
  }
6257
6328
  renderMessagePreview(ev, defmsg) {
6258
6329
  defmsg = defmsg || this.props.t('sent_you_a_message');
6259
- var format = util/* default */.A.get(ev, 'data.message.format');
6330
+ let format = util/* default */.A.get(ev, 'data.message.format');
6260
6331
  let block = util/* default */.A.get(ev, 'data.message.block');
6261
- if (block || format == 'block') return (0,preact_module.h)(chatbox_block/* default */.A, {
6262
- block: block
6263
- });
6332
+ if (block || format == 'block') {
6333
+ if (util/* default */.A.isBlockEmpty(block)) {
6334
+ let attachments = util/* default */.A.get(ev, 'data.message.attachments');
6335
+ if (util/* default */.A.size(attachments) > 0) {
6336
+ return (0,preact_module.h)("div", null, `${this.props.t('send')} ${util/* default */.A.size(attachments)} ${util/* default */.A.size(attachments) > 1 ? this.props.t('attachments') : this.props.t('attachment')}`);
6337
+ }
6338
+ return defmsg;
6339
+ }
6340
+ return (0,preact_module.h)(chatbox_block/* default */.A, {
6341
+ block: block
6342
+ });
6343
+ }
6264
6344
  let message = util/* default */.A.get(ev, 'data.message.text', defmsg);
6265
6345
  if (!message && util/* default */.A.size(util/* default */.A.get(ev, 'data.message.attachments')) > 0) message = defmsg;
6266
6346
  if (!message) return null;
@@ -6457,6 +6537,17 @@ class Header extends common/* Com */.Mw {
6457
6537
  constructor(props) {
6458
6538
  super(props);
6459
6539
  }
6540
+ renderAccountAvatar() {
6541
+ let acc = this.props.store.matchAccount() || {};
6542
+ if (!acc.logo_url) return null;
6543
+ return (0,preact_module.h)("img", {
6544
+ width: 38,
6545
+ height: 38,
6546
+ alt: acc.name,
6547
+ class: "avatar avatar__account",
6548
+ src: this.props.store.replaceFileUrl(acc.logo_url) || __webpack_require__(3582)
6549
+ });
6550
+ }
6460
6551
  render() {
6461
6552
  let headerMode = 'collapsed';
6462
6553
  let cls = 'widget-header';
@@ -6492,7 +6583,7 @@ class Header extends common/* Com */.Mw {
6492
6583
  return (0,preact_module.h)("div", {
6493
6584
  class: cls,
6494
6585
  style: style
6495
- }, $back, (0,preact_module.h)("div", {
6586
+ }, $back, this.renderAccountAvatar(), (0,preact_module.h)("div", {
6496
6587
  class: "widget-header--title-container"
6497
6588
  }, (0,preact_module.h)("div", {
6498
6589
  class: "widget-header--title"
@@ -7304,429 +7395,382 @@ class QuickReplies extends common/* Com */.Mw {
7304
7395
  }, $replies);
7305
7396
  }
7306
7397
  }
7307
- ;// ./src/chatbox/ListField.js
7398
+ ;// ./src/form/Form.js
7399
+ function Form_defineProperty(e, r, t) { return (r = Form_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
7400
+ function Form_toPropertyKey(t) { var i = Form_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
7401
+ function Form_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7308
7402
 
7309
7403
 
7310
7404
 
7311
- class ListField extends common/* Com */.Mw {
7405
+
7406
+ class Form2 extends common/* Com */.Mw {
7312
7407
  constructor(props) {
7313
7408
  super(props);
7314
- this.setState({
7315
- search: '',
7316
- isShow: false
7317
- });
7318
- }
7319
- render() {
7320
- let fields = util/* default */.A.filter(this.props.items, item => {
7321
- let search = this.state.search.toLowerCase();
7322
- let name = item || '';
7323
- return name.toLowerCase().indexOf(search) > -1;
7324
- });
7325
- let $fields = util/* default */.A.map(fields, field => {
7326
- return (0,preact_module.h)("li", {
7327
- class: "custom-select--item-options",
7328
- onClick: () => this.add(field)
7329
- }, field);
7330
- });
7331
- let $selected = util/* default */.A.map(this.props.selected, (item, i) => {
7409
+ Form_defineProperty(this, "state", {
7410
+ errorFields: {},
7411
+ submiting: false
7412
+ });
7413
+ Form_defineProperty(this, "renderFormComponent", (com, idx) => {
7414
+ if (com.type === 'input') return this.renderField(com, idx);
7415
+ if (com.type === 'submit_button') return this.renderSubmitButton(com, idx);
7416
+ if (this.props.isSubmited) return;
7332
7417
  return (0,preact_module.h)("div", {
7333
- class: "custom-select--selected-item",
7334
- onClick: e => this.remove(e, i)
7335
- }, item, (0,preact_module.h)("i", {
7336
- class: "icn-delete delete-tag"
7418
+ class: "form-component form-component-block"
7419
+ }, (0,preact_module.h)(chatbox_block/* default */.A, {
7420
+ block: com
7337
7421
  }));
7338
7422
  });
7339
- let $dropdown = (0,preact_module.h)("div", {
7340
- class: "custom-select--wrap-options"
7341
- }, (0,preact_module.h)("input", {
7342
- onClick: e => {
7343
- e.preventDefault();
7344
- e.stopPropagation();
7345
- this.setState({
7346
- isShow: true
7347
- });
7348
- },
7349
- type: "text",
7350
- onInput: e => this.setState({
7351
- search: e.target.value
7352
- }),
7353
- value: this.state.search,
7354
- placeholder: "T\xECm ki\u1EBFm",
7355
- class: "custom-select--input-search"
7356
- }), (0,preact_module.h)("ul", {
7357
- class: "custom-select--items-options"
7358
- }, $fields));
7359
- if (!this.state.isShow) {
7360
- $dropdown = null;
7361
- }
7362
- return (0,preact_module.h)("div", {
7363
- class: "form-control custom-select"
7364
- }, (0,preact_module.h)(common/* Clickaway */.tW, {
7365
- onClickaway: e => this.clickaway()
7366
- }, (0,preact_module.h)("div", {
7367
- class: "custom-select--wrap-selected",
7368
- onClick: () => this.setState({
7369
- isShow: !this.state.isShow
7370
- })
7371
- }, (0,preact_module.h)("div", {
7372
- class: "custom-select--selected-items"
7373
- }, $selected), $dropdown, (0,preact_module.h)("div", {
7374
- class: "custom-select--icon-dropdown"
7375
- }, (0,preact_module.h)("svg", {
7376
- width: "24",
7377
- height: "24",
7378
- viewBox: "0 0 24 24",
7379
- fill: "none",
7380
- xmlns: "http://www.w3.org/2000/svg"
7381
- }, (0,preact_module.h)("g", {
7382
- opacity: "0.6"
7383
- }, (0,preact_module.h)("path", {
7384
- d: "M7 9.5L12 14.5L17 9.5H7Z",
7385
- fill: "black"
7386
- })))))));
7387
- }
7388
- clickaway() {
7389
- this.setState({
7390
- isShow: false
7391
- });
7392
- }
7393
- add(field) {
7394
- this.props.onAddItem && this.props.onAddItem(field);
7395
- }
7396
- remove(e, index) {
7397
- e.preventDefault();
7398
- e.stopPropagation();
7399
- this.props.onRemoveItem && this.props.onRemoveItem(index);
7400
- }
7401
- }
7402
- ;// ./src/chatbox/FormAttachment.js
7403
-
7404
-
7405
-
7406
-
7407
- class FormAttachment extends common/* Com */.Mw {
7408
- constructor(props) {
7409
- super(props);
7410
- this.props.store.onUpdate(this, _ => this.forceUpdate());
7411
- let user = this.props.store.matchUser();
7412
- let fields = util/* default */.A.get(this.props.form, 'fields') || [];
7413
- let formData = util/* default */.A.map(fields, field => {
7414
- let is_required = field.is_required || false;
7415
- var state = util/* default */.A.parseJSON(field.state) || {};
7416
- if (!is_required) is_required = state.require || false;
7417
- var userattr = util/* default */.A.getUserAttr(user, field.name, state.type || 'text');
7418
- return {
7419
- name: field.name,
7420
- items: field.items,
7421
- value: util/* default */.A.parseJSON(field.answer) || util/* default */.A.parseJSON(field.default_answer) || userattr,
7422
- is_required,
7423
- label: field.title,
7424
- type: field.input_type
7425
- };
7426
- });
7427
- this.setState({
7428
- formData
7429
- });
7430
- }
7431
- isSummited() {
7432
- let found = util/* default */.A.find(this.state.formData, field => !!field.answered);
7433
- if (found) return true;
7434
- let convo = this.props.store.matchConvo(util/* default */.A.convoOfEv(this.props.ev));
7435
- return convo.state === 'ended';
7436
- }
7437
- render() {
7438
- if (util/* default */.A.size(this.state.formData) === 0) return null;
7439
- let $fields = this.renderFields();
7440
- let $submitbutton = null;
7441
- if (!this.isSummited()) {
7442
- $submitbutton = (0,preact_module.h)("div", {
7443
- class: "mt-2"
7444
- }, (0,preact_module.h)("button", {
7445
- onClick: _ => this.submit(),
7446
- type: "button",
7447
- class: "form-attachment--submit-btn"
7448
- }, this.props.t('btn_submit_form_attachment')));
7449
- }
7450
- return (0,preact_module.h)("div", {
7451
- class: "form-attachment",
7452
- onClick: e => e.stopPropagation()
7453
- }, this.props.t(this.props.form.title) || this.props.t('capture_lead_title'), $fields, $submitbutton);
7454
- }
7455
- focus() {
7456
- if (this.props.store.isPreview) return;
7457
- if (util/* default */.A.size(this.state.formData) === 0) return;
7458
- let $field;
7459
- if (this.isFormFilled()) {
7460
- var keys = Object.keys(this.state.formData);
7461
- var lastkey = keys[util/* default */.A.size(keys) - 1];
7462
- var lastfield = this.state.formData[lastkey];
7463
- $field = this['field.' + encode(lastfield.name)];
7464
- } else {
7465
- var firstunfilledfield = this.firstUnfilledField();
7466
- if (!firstunfilledfield) return;
7467
- $field = this['field.' + encode(firstunfilledfield.name)];
7468
- }
7469
- if ($field) $field.focus();
7470
- }
7471
- firstUnfilledField() {
7472
- return util/* default */.A.find(this.state.formData, field => field.value == null || field.value === '');
7473
- }
7474
- isFormFilled() {
7475
- return !util/* default */.A.find(this.state.formData, field => field.value == null || field.value === '');
7476
- }
7477
- onInputChange(index, val) {
7478
- let formData = util/* default */.A.cloneDeep(this.state.formData);
7479
- formData[index].value = val;
7480
- this.setState({
7481
- formData
7482
- });
7483
- }
7484
- onListAddItem(index, val) {
7485
- let formData = util/* default */.A.cloneDeep(this.state.formData);
7486
- let field = formData[index];
7487
- field.value = field.value || [];
7488
- field.value.push(val);
7489
- this.setState({
7490
- formData
7491
- });
7492
- }
7493
- onListRemoveItem(index, vindex) {
7494
- let formData = util/* default */.A.cloneDeep(this.state.formData);
7495
- let field = formData[index];
7496
- field.value = field.value || [];
7497
- field.value.splice(vindex, 1);
7498
- this.setState({
7499
- formData
7500
- });
7501
- }
7502
- renderFields() {
7503
- if (util/* default */.A.size(this.state.formData) === 0) return null;
7504
- let $fields = null;
7505
- $fields = util/* default */.A.map(this.state.formData, (field, index) => {
7506
- let $field = null;
7507
- var errclass = field.error ? 'input--error' : '';
7508
- if (field.type === 'text') {
7509
- if (this.isSummited()) {
7510
- $field = (0,preact_module.h)("div", {
7511
- class: "form-control--container"
7512
- }, (0,preact_module.h)("input", {
7513
- disabled: true,
7514
- ref: ref => {
7515
- this['field.' + encode(field.name)] = ref;
7516
- },
7517
- value: field.value,
7518
- onInput: e => this.onInputChange(index, e.target.value),
7519
- class: `form-control ${errclass}`,
7520
- type: "text"
7521
- }), (0,preact_module.h)("i", {
7522
- class: "form-control--check"
7523
- }));
7524
- } else {
7525
- $field = (0,preact_module.h)("input", {
7526
- ref: ref => {
7527
- this['field.' + encode(field.name)] = ref;
7528
- },
7529
- value: field.value,
7530
- onInput: e => this.onInputChange(index, e.target.value),
7531
- class: `form-control ${errclass}`,
7532
- type: "text"
7533
- });
7423
+ Form_defineProperty(this, "renderSubmitButton", (com, idx) => {
7424
+ if (this.props.isSubmited) return;
7425
+ return (0,preact_module.h)("div", {
7426
+ class: "form-component form-component-submit-button"
7427
+ }, (0,preact_module.h)("div", {
7428
+ class: "form-control--valid-input--error"
7429
+ }, this.props.errorMessage), (0,preact_module.h)("div", null, (0,preact_module.h)("button", {
7430
+ class: "btn--start-convo",
7431
+ disabled: this.props.submiting
7432
+ }, com.label)));
7433
+ });
7434
+ Form_defineProperty(this, "renderField", (com, idx) => {
7435
+ let errorMsg = this.state.errorFields[com.key];
7436
+ if (this.props.isSubmited) {
7437
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7438
+ val = val.value || '""';
7439
+ val = util/* default */.A.parseJSON(val);
7440
+ if (Array.isArray(val)) val = val.join(', ');
7441
+ return (0,preact_module.h)("div", {
7442
+ class: "form-component submitted",
7443
+ key: com.key
7444
+ }, (0,preact_module.h)("label", {
7445
+ class: "label"
7446
+ }, com.label), (0,preact_module.h)("div", null, val || (0,preact_module.h)("span", {
7447
+ class: "text-muted text-italic"
7448
+ }, this.props.t('no_info_input'))));
7449
+ }
7450
+ return (0,preact_module.h)("div", {
7451
+ class: "form-component",
7452
+ key: com.key
7453
+ }, (0,preact_module.h)("label", {
7454
+ class: "label"
7455
+ }, com.label, " ", com.is_required && (0,preact_module.h)("span", {
7456
+ class: "red"
7457
+ }, "*")), com.input_type === 'text' && this.renderFieldTextInput(com, idx), com.input_type === 'multiple' && this.renderFieldTextareaInput(com, idx), com.input_type === 'date' && this.renderFieldDateInput(com, idx), com.input_type === 'radio' && this.renderFieldRadioInput(com, idx), com.input_type === 'checkbox' && this.renderFieldCheckboxInput(com, idx), com.input_type === 'dropdown' && this.renderFieldDropdownInput(com, idx), errorMsg && (0,preact_module.h)("div", {
7458
+ class: "form-control--valid-input--error"
7459
+ }, errorMsg));
7460
+ });
7461
+ Form_defineProperty(this, "renderFieldTextInput", (com, idx) => {
7462
+ let cls = 'form-control';
7463
+ if (this.state.errorFields[com.key]) cls = 'form-control input--error';
7464
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7465
+ val = val.value || '""';
7466
+ val = util/* default */.A.parseJSON(val);
7467
+ return (0,preact_module.h)("input", {
7468
+ ref: this[`${com.key}_input`],
7469
+ type: "text",
7470
+ class: cls,
7471
+ placeholder: com.placeholder,
7472
+ value: val,
7473
+ onInput: e => {
7474
+ this.onChangeValue(com.key, e.target.value);
7475
+ this.clearError(com.key);
7534
7476
  }
7535
- } else if (field.type === 'number') {
7536
- if (this.isSummited()) {
7537
- $field = (0,preact_module.h)("div", {
7538
- class: "form-control--container"
7539
- }, (0,preact_module.h)("input", {
7540
- disabled: true,
7541
- ref: ref => {
7542
- this['field.' + encode(field.name)] = ref;
7543
- },
7544
- value: field.value,
7545
- onInput: e => this.onInputChange(index, e.target.value),
7546
- class: `form-control ${errclass}`,
7547
- type: "number"
7548
- }), (0,preact_module.h)("i", {
7549
- class: "form-control--check"
7550
- }));
7551
- } else {
7552
- $field = (0,preact_module.h)("input", {
7553
- ref: ref => {
7554
- this['field.' + encode(field.name)] = ref;
7555
- },
7556
- value: field.value,
7557
- onInput: e => this.onInputChange(index, e.target.value),
7558
- class: `form-control ${errclass}`,
7559
- type: "number"
7560
- });
7477
+ });
7478
+ });
7479
+ Form_defineProperty(this, "renderFieldDateInput", (com, idx) => {
7480
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7481
+ val = val.value || '""';
7482
+ val = util/* default */.A.parseJSON(val);
7483
+ return (0,preact_module.h)("input", {
7484
+ ref: this[`${com.key}_input`],
7485
+ class: "form-control",
7486
+ type: "date",
7487
+ value: val,
7488
+ onInput: e => {
7489
+ this.onChangeValue(com.key, e.target.value);
7490
+ this.clearError(com.key);
7561
7491
  }
7562
- } else if (field.type === 'boolean') {
7563
- $field = (0,preact_module.h)("div", {
7492
+ });
7493
+ });
7494
+ Form_defineProperty(this, "renderFieldRadioInput", (com, idx) => {
7495
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7496
+ val = val.value || '""';
7497
+ val = util/* default */.A.parseJSON(val);
7498
+ return util/* default */.A.map(com.input_options, (option, oidx) => {
7499
+ let id = com.key + '_' + oidx;
7500
+ return (0,preact_module.h)("div", {
7501
+ class: "radio"
7502
+ }, (0,preact_module.h)("input", {
7503
+ type: "radio",
7504
+ name: com.key,
7505
+ id: id,
7506
+ checked: option.value === val,
7507
+ onChange: () => this.toggleRadioField(com.key, option.value)
7508
+ }), (0,preact_module.h)("label", {
7509
+ class: "radio--label",
7510
+ for: id
7511
+ }, option.label), (0,preact_module.h)("div", {
7512
+ class: "radio--check"
7513
+ }));
7514
+ });
7515
+ });
7516
+ Form_defineProperty(this, "renderFieldCheckboxInput", (com, idx) => {
7517
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7518
+ val = val.value || '[]';
7519
+ val = util/* default */.A.parseJSON(val);
7520
+ return util/* default */.A.map(com.input_options, (option, oidx) => {
7521
+ let id = com.key + '_' + oidx;
7522
+ return (0,preact_module.h)("div", {
7564
7523
  class: "checkbox"
7565
7524
  }, (0,preact_module.h)("input", {
7566
- ref: ref => {
7567
- this['field.' + encode(field.name)] = ref;
7568
- },
7569
7525
  type: "checkbox",
7570
- id: 'checkbox.' + this.props.ev.id + '.' + field.name,
7571
- onChange: e => this.onInputChange(index, ev.target.checked),
7572
- checked: field.value
7526
+ name: com.key,
7527
+ id: id,
7528
+ checked: val.includes(option.value),
7529
+ onChange: () => this.toggleCheckboxField(com.key, option.value)
7573
7530
  }), (0,preact_module.h)("label", {
7574
7531
  class: "checkbox--label",
7575
- for: 'checkbox.' + this.props.ev.id + '.' + field.name
7576
- }, field.label), (0,preact_module.h)("div", {
7532
+ for: id
7533
+ }, option.label), (0,preact_module.h)("div", {
7577
7534
  class: "checkbox--check"
7578
- }, (0,preact_module.h)("div", null)));
7579
- } else if (field.type === 'list') {
7580
- let selected = field.value || [];
7581
- let items = util/* default */.A.filter(util/* default */.A.get(field, 'items', []), item => !selected.includes(item));
7582
- $field = (0,preact_module.h)(ListField, {
7583
- selected: selected,
7584
- items: items,
7585
- onAddItem: e => this.onListAddItem(index, e),
7586
- onRemoveItem: item => this.onListRemoveItem(index, item)
7587
- });
7588
- } else if (field.type === 'datetime') {
7589
- $field = (0,preact_module.h)("input", {
7590
- ref: ref => {
7591
- this['field.' + encode(field.name)] = ref;
7592
- },
7593
- value: field.value,
7594
- onInput: e => this.onInputChange(index, e.target.value),
7595
- class: `form-control ${errclass}`,
7596
- type: "date"
7597
- });
7598
- }
7599
- let label = field.label;
7600
- if (field.name === 'fullname') {
7601
- label = this.props.t('fullname');
7602
- } else if (field.name === 'emails') {
7603
- label = this.props.t('email');
7604
- } else if (field.name === 'phones') {
7605
- label = this.props.t('phones');
7606
- }
7607
- return (0,preact_module.h)("div", null, (0,preact_module.h)("p", {
7608
- class: "label mt-3"
7609
- }, label, field.is_required ? (0,preact_module.h)("span", {
7610
- class: "ml-1 red"
7611
- }, "*") : ''), field.error ? (0,preact_module.h)("div", {
7612
- class: "form-control--valid-input--error"
7613
- }, field.error) : '', $field);
7535
+ }));
7536
+ });
7614
7537
  });
7615
- return (0,preact_module.h)("div", null, $fields);
7616
- }
7617
- async submit() {
7618
- var hasError = false;
7619
- util/* default */.A.map(this.state.formData, field => {
7620
- if (field.is_required && (field.value === undefined || field.value === '' || util/* default */.A.size(field.value) === 0 && Array.isArray(field.value))) {
7621
- field.error = this.props.t('error_empty');
7622
- hasError = true;
7623
- } else {
7624
- field.error = '';
7625
- }
7626
- if (field.name === 'emails' && field.value) {
7627
- if (!util/* default */.A.isEmail(field.value)) {
7628
- field.error = this.props.t('error_email_invalid');
7629
- hasError = true;
7538
+ Form_defineProperty(this, "renderFieldDropdownInput", (com, idx) => {
7539
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7540
+ val = val.value || '""';
7541
+ val = util/* default */.A.parseJSON(val);
7542
+ return (0,preact_module.h)("select", {
7543
+ class: "form-control",
7544
+ ref: this[`${com.key}_input`],
7545
+ onChange: e => {
7546
+ this.onChangeValue(com.key, e.target.value);
7547
+ this.clearError(com.key);
7630
7548
  }
7631
- }
7549
+ }, util/* default */.A.map(com.input_options, option => {
7550
+ return (0,preact_module.h)("option", {
7551
+ value: option.value
7552
+ }, option.label);
7553
+ }));
7632
7554
  });
7633
- this.forceUpdate();
7634
- if (hasError) return;
7635
- let user = {};
7636
- let formData = util/* default */.A.cloneDeep(this.state.formData);
7637
- util/* default */.A.map(formData, field => {
7638
- var attr = {
7639
- key: field.name
7640
- };
7641
- field.answered = new util/* default */.A.Date().getTime();
7642
- if (field.type === 'number') {
7643
- attr.number = parseInt(field.value);
7644
- field.answer = util/* default */.A.stringify(attr.number);
7645
- }
7646
- if (field.type === 'datetime') {
7647
- attr.datetime = new util/* default */.A.Date(field.value).toISOString();
7648
- field.answer = util/* default */.A.stringify(attr.datetime);
7649
- }
7650
- if (field.type === 'list') {
7651
- attr.list = field.value;
7652
- field.answer = util/* default */.A.stringify(attr.list);
7653
- }
7654
- if (field.type === 'text' || field.type === 'boolean') {
7655
- attr[field.type] = field.value;
7656
- field.answer = util/* default */.A.stringify(field.value);
7555
+ Form_defineProperty(this, "renderFieldTextareaInput", (com, idx) => {
7556
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7557
+ val = val.value || '""';
7558
+ val = util/* default */.A.parseJSON(val);
7559
+ return (0,preact_module.h)("textarea", {
7560
+ onInput: e => {
7561
+ this.onChangeValue(com.key, e.target.value);
7562
+ this.clearError(com.key);
7563
+ },
7564
+ ref: this[`${com.key}_input`],
7565
+ rows: "3",
7566
+ class: "form-control",
7567
+ placeholder: com.placeholder
7568
+ });
7569
+ });
7570
+ Form_defineProperty(this, "onSubmit", e => {
7571
+ e.preventDefault();
7572
+ if (!this.validateForm()) return;
7573
+ this.props.onSubmit();
7574
+ });
7575
+ Form_defineProperty(this, "validateForm", () => {
7576
+ let result = true;
7577
+ let ref = '';
7578
+ let errors = {};
7579
+ let components = util/* default */.A.get(this.props.formSetting, 'components') || [];
7580
+ util/* default */.A.each(components, com => {
7581
+ if (com.type === 'input') {
7582
+ if (com.is_required) {
7583
+ let val = util/* default */.A.find(this.props.formValues, f => f.key === com.key) || {};
7584
+ val = val.value || '""';
7585
+ val = util/* default */.A.parseJSON(val);
7586
+ if (typeof val === 'string' && !val.trim()) {
7587
+ result = false;
7588
+ errors[com.key] = this.props.t('cannot_be_empty');
7589
+ if (!ref && com.input_type !== 'checkbox' && com.input_type !== 'radio') ref = `${com.key}_input`;
7590
+ }
7591
+ if (Array.isArray(val) && val.length === 0) {
7592
+ result = false;
7593
+ errors[com.key] = this.props.t('cannot_be_empty');
7594
+ }
7595
+ }
7596
+ }
7597
+ });
7598
+ if (ref && this[ref] && this[ref].current) {
7599
+ this[ref].current.focus();
7657
7600
  }
7658
- util/* default */.A.setUserAttr(user, attr);
7601
+ this.setState({
7602
+ errorFields: errors
7603
+ });
7604
+ return result;
7659
7605
  });
7660
- util/* default */.A.map(formData, field => {
7661
- let ffield = util/* default */.A.find(this.props.form.fields, ffield => ffield.name === field.name);
7662
- if (!ffield) return;
7663
- ffield.answered = field.answered;
7606
+ Form_defineProperty(this, "onChangeValue", (key, v) => {
7607
+ let formValues = this.props.formValues;
7608
+ let f = util/* default */.A.find(formValues, field => field.key === key);
7609
+ if (!f) {
7610
+ formValues.push({
7611
+ key,
7612
+ value: JSON.stringify(v)
7613
+ });
7614
+ } else {
7615
+ f.value = JSON.stringify(v);
7616
+ }
7617
+ this.props.onChangeFormValues(formValues);
7664
7618
  });
7665
- this.setState({
7666
- formData
7619
+ Form_defineProperty(this, "clearError", key => {
7620
+ let errors = this.state.errorFields;
7621
+ errors[key] = '';
7622
+ this.setState({
7623
+ errorFields: errors
7624
+ });
7667
7625
  });
7668
- this.props.store.setUser(user);
7669
- let message = {
7670
- attachments: [{
7671
- type: 'form_submit',
7672
- form_submit: {
7673
- state: '{"user_id":"' + this.props.store.matchUser().id + '"}',
7674
- form_message_id: util/* default */.A.get(this.props.ev, 'id'),
7675
- fields: formData
7676
- }
7677
- }]
7678
- };
7679
- let cid = util/* default */.A.convoOfEv(this.props.ev);
7680
- this.props.store.sendConvoEvent(cid, 'message_sent', {
7681
- message
7626
+ let _components = util/* default */.A.get(this.props.formSetting, 'components') || [];
7627
+ util/* default */.A.each(_components, com => {
7628
+ if (com.type === 'input' && com.input_type !== 'checkbox' && com.input_type !== 'radio') {
7629
+ this[`${com.key}_input`] = (0,preact_module/* createRef */._3)();
7630
+ }
7682
7631
  });
7683
- this.props.onSubmit && this.props.onSubmit();
7632
+ }
7633
+ toggleRadioField(key, v) {
7634
+ this.clearError(key);
7635
+ this.onChangeValue(key, v);
7636
+ }
7637
+ toggleCheckboxField(key, v) {
7638
+ let currentValues = util/* default */.A.find(this.props.formValues, f => f.key === key) || {};
7639
+ currentValues = currentValues.value || '[]';
7640
+ currentValues = util/* default */.A.parseJSON(currentValues);
7641
+ if (currentValues.includes(v)) {
7642
+ currentValues = currentValues.filter(s => s !== v);
7643
+ } else {
7644
+ currentValues.push(v);
7645
+ }
7646
+ this.clearError(key);
7647
+ this.onChangeValue(key, currentValues);
7648
+ }
7649
+ render() {
7650
+ let components = util/* default */.A.get(this.props.formSetting, 'components') || [];
7651
+ let cls = 'form-wrapper form';
7652
+ if (this.props.mode === 'attachment') cls += ' form-wrapper-attachment';
7653
+ return (0,preact_module.h)("div", {
7654
+ class: cls
7655
+ }, this.props.isSubmited && (0,preact_module.h)("div", {
7656
+ class: "form-component"
7657
+ }, this.props.t('you_have_submitted_info_successfully')), (0,preact_module.h)("form", {
7658
+ onSubmit: this.onSubmit
7659
+ }, util/* default */.A.map(components, this.renderFormComponent)));
7684
7660
  }
7685
7661
  }
7686
- function encode(key) {
7687
- return btoa(key).split('=').join('');
7688
- }
7689
- ;// ./src/chatbox/FormAttachments.js
7662
+ ;// ./src/chatbox/FormAttachment2.js
7663
+ function FormAttachment2_defineProperty(e, r, t) { return (r = FormAttachment2_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
7664
+ function FormAttachment2_toPropertyKey(t) { var i = FormAttachment2_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
7665
+ function FormAttachment2_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7690
7666
 
7691
7667
 
7692
7668
 
7693
7669
 
7694
- class FormAttachments extends common/* Com */.Mw {
7670
+ class FormAttachment extends common/* Com */.Mw {
7695
7671
  constructor(props) {
7696
7672
  super(props);
7697
- }
7698
- render() {
7699
- let byType = util/* default */.A.get(this.props.ev, 'by.type');
7700
- if (byType === 'user') return;
7701
- let forms = [];
7702
- let attachments = util/* default */.A.get(this.props.ev, 'data.message.attachments') || [];
7703
- util/* default */.A.each(attachments, att => {
7704
- if (!att) return;
7705
- if (att.type !== 'form' && att.type !== 'ask_info_form') return;
7706
- att.form._type = att.type;
7707
- forms.push(att.form);
7673
+ FormAttachment2_defineProperty(this, "state", {
7674
+ formValues: [],
7675
+ submiting: false,
7676
+ isSubmited: false,
7677
+ errorMessage: '',
7678
+ step: 1
7679
+ });
7680
+ FormAttachment2_defineProperty(this, "onChangeFormValues", values => {
7681
+ this.setState({
7682
+ formValues: values
7683
+ });
7708
7684
  });
7709
- let $forms = util/* default */.A.map(forms, (form, formIndex) => {
7710
- return (0,preact_module.h)(FormAttachment, {
7711
- store: this.props.store,
7712
- onSubmit: this.props.onSubmit,
7713
- ref: ref => {
7714
- this['form.' + formIndex] = ref;
7715
- },
7716
- key: formIndex,
7717
- form: form,
7718
- ev: this.props.ev,
7719
- t: this.props.t
7685
+ FormAttachment2_defineProperty(this, "onSubmit", async () => {
7686
+ console.log('submittttttt', this.state.formValues);
7687
+ this.setState({
7688
+ errorMessage: ''
7689
+ });
7690
+ if (this.state.submiting) return;
7691
+ this.setState({
7692
+ submiting: true
7693
+ });
7694
+ await util/* default */.A.sleep(1_500);
7695
+ this.setState({
7696
+ submiting: false,
7697
+ isSubmited: true
7720
7698
  });
7721
7699
  });
7722
- if ($forms.length === 0) return null;
7723
- return (0,preact_module.h)("div", {
7724
- class: "message-agent"
7725
- }, $forms);
7726
7700
  }
7727
- focus() {
7728
- var $form = this['form.0'];
7729
- if ($form) $form.focus();
7701
+ render() {
7702
+ if (this.props.ev.id !== 'evshpgaeetsplfqprzmynrvrl') return;
7703
+ const formSetting = {
7704
+ components: [{
7705
+ type: 'text',
7706
+ text: 'Đặt lịch khám'
7707
+ }, {
7708
+ type: 'input',
7709
+ key: 'fullname',
7710
+ default_value: '234',
7711
+ link_attribute: 'email',
7712
+ placeholder: 'Nguyen Van A',
7713
+ label: 'Họ và tên',
7714
+ input_type: 'text',
7715
+ is_required: true
7716
+ }, {
7717
+ type: 'input',
7718
+ key: 'phone',
7719
+ validation: 'phone',
7720
+ label: 'SĐT',
7721
+ input_type: 'text',
7722
+ is_required: true
7723
+ }, {
7724
+ type: 'input',
7725
+ label: 'Chọn ca',
7726
+ is_required: true,
7727
+ input_type: 'radio',
7728
+ key: 'shift',
7729
+ input_options: [{
7730
+ value: 'Buổi sáng',
7731
+ label: 'Buổi sáng'
7732
+ }, {
7733
+ value: 'Buổi chiều',
7734
+ label: 'Buổi chiều'
7735
+ }]
7736
+ }, {
7737
+ type: 'input',
7738
+ label: 'Chọn ca 2',
7739
+ is_required: true,
7740
+ input_type: 'checkbox',
7741
+ key: 'shift_2',
7742
+ input_options: [{
7743
+ value: 'Buổi sáng',
7744
+ label: 'Buổi sáng'
7745
+ }, {
7746
+ value: 'Buổi chiều',
7747
+ label: 'Buổi chiều'
7748
+ }]
7749
+ }, {
7750
+ type: 'input',
7751
+ key: 'schedule',
7752
+ label: 'Chọn ngày',
7753
+ is_required: true,
7754
+ input_type: 'date'
7755
+ }, {
7756
+ type: 'submit_button',
7757
+ label: 'Submit'
7758
+ }]
7759
+ };
7760
+ return (0,preact_module.h)("div", {
7761
+ onClick: e => e.stopPropagation()
7762
+ }, (0,preact_module.h)(Form2, {
7763
+ store: this.props.store,
7764
+ formSetting: formSetting,
7765
+ mode: "attachment",
7766
+ t: this.props.t,
7767
+ formValues: this.state.formValues,
7768
+ errorMessage: this.state.errorMessage,
7769
+ isSubmited: this.state.isSubmited,
7770
+ submiting: this.state.submiting,
7771
+ onChangeFormValues: this.onChangeFormValues,
7772
+ onSubmit: this.onSubmit
7773
+ }));
7730
7774
  }
7731
7775
  }
7732
7776
  ;// ./src/chatbox/FormSubmitAttachments.js
@@ -8384,6 +8428,9 @@ class Event extends common/* Com */.Mw {
8384
8428
  }
8385
8429
  renderMessageSent() {
8386
8430
  let ev = this.props.event.ev;
8431
+ let attachments = util/* default */.A.get(ev, 'data.message.attachments');
8432
+ let hasForm = util/* default */.A.find(attachments, att => att.type === 'form');
8433
+ if (ev.id === 'evshpgaeetsplfqprzmynrvrl') hasForm = true;
8387
8434
  this.tryLoadOrder(ev);
8388
8435
  let t = new util/* default */.A.Date(ev.created).toLocaleString();
8389
8436
  if (util/* default */.A.get(ev, 'by.type') !== 'user') {
@@ -8391,10 +8438,12 @@ class Event extends common/* Com */.Mw {
8391
8438
  if (this.props.event.mode === 'lead') $sender = this.renderAgentAvatar(ev);
8392
8439
  let innercls = 'agent-convo-event-inner';
8393
8440
  if (this.props.isLast) innercls += ' last';
8441
+ let wrappercls = 'agent-convo-event-wrapper';
8442
+ if (hasForm) wrappercls += ' full';
8394
8443
  return (0,preact_module.h)("div", {
8395
8444
  class: "convo-event agent-message"
8396
8445
  }, $sender, (0,preact_module.h)("div", {
8397
- class: "agent-convo-event-wrapper"
8446
+ class: wrappercls
8398
8447
  }, (0,preact_module.h)("div", {
8399
8448
  class: innercls
8400
8449
  }, (0,preact_module.h)(TextMessage, {
@@ -8419,10 +8468,8 @@ class Event extends common/* Com */.Mw {
8419
8468
  store: this.props.store,
8420
8469
  ev: ev,
8421
8470
  t: this.props.t
8422
- }), (0,preact_module.h)(FormAttachments, {
8471
+ }), (0,preact_module.h)(FormAttachment, {
8423
8472
  store: this.props.store,
8424
- onSubmit: this.props.onFormSubmit,
8425
- ref: this.refForm,
8426
8473
  ev: ev,
8427
8474
  t: this.props.t
8428
8475
  }), (0,preact_module.h)(FormSubmitAttachments, {
@@ -8506,10 +8553,9 @@ class Event extends common/* Com */.Mw {
8506
8553
  store: this.props.store,
8507
8554
  ev: ev,
8508
8555
  t: this.props.t
8509
- }), (0,preact_module.h)(FormAttachments, {
8556
+ }), (0,preact_module.h)(FormAttachment, {
8510
8557
  store: this.props.store,
8511
- onSubmit: this.props.onFormSubmit,
8512
- ref: this.refForm,
8558
+ t: this.props.t,
8513
8559
  ev: ev
8514
8560
  }), (0,preact_module.h)(ProductAttachments, {
8515
8561
  t: this.props.t,
@@ -8728,7 +8774,7 @@ class Events extends common/* Com */.Mw {
8728
8774
  render() {
8729
8775
  if (this.state.error) return this.renderError();
8730
8776
  let events = util/* default */.A.map(this.props.store.listEvents(this.props.cid));
8731
- if (!this.state.loading && util/* default */.A.size(events) === 0) {
8777
+ if (!this.state.loading && util/* default */.A.size(events) === 0 && !this.props.cid) {
8732
8778
  return (0,preact_module.h)("div", {
8733
8779
  ref: ref => this.refBody = ref,
8734
8780
  class: "widget-body--events-container"
@@ -9258,6 +9304,152 @@ class Rating extends common/* Com */.Mw {
9258
9304
  });
9259
9305
  }
9260
9306
  }
9307
+ ;// ./src/chatbox/ConnectionStatus.js
9308
+ function ConnectionStatus_defineProperty(e, r, t) { return (r = ConnectionStatus_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
9309
+ function ConnectionStatus_toPropertyKey(t) { var i = ConnectionStatus_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
9310
+ function ConnectionStatus_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
9311
+
9312
+
9313
+
9314
+ class ConnectionStatus extends common/* Com */.Mw {
9315
+ constructor(props) {
9316
+ super(props);
9317
+ ConnectionStatus_defineProperty(this, "onChangeConnectionStatus", () => {
9318
+ let newstatus = this.props.store.getConnectionStatus();
9319
+ let currentstatus = this.state.status;
9320
+ this.setState({
9321
+ status: newstatus
9322
+ });
9323
+ if (currentstatus !== 'active' && newstatus === 'active') this.changeStatusFailedToSuccess();
9324
+ });
9325
+ ConnectionStatus_defineProperty(this, "changeStatusFailedToSuccess", () => {
9326
+ this.setState({
9327
+ status: 'just_active'
9328
+ });
9329
+ if (this.props.cid) this.props.store.fetchMoreEvents(this.props.cid);
9330
+ if (this._timeout) clearTimeout(this._timeout);
9331
+ this._timeout = setTimeout(() => {
9332
+ this.setState({
9333
+ status: 'active'
9334
+ });
9335
+ }, 2000);
9336
+ });
9337
+ this.props.store.onConnection(this, this.onChangeConnectionStatus);
9338
+ this.state = {
9339
+ status: this.props.store.getConnectionStatus()
9340
+ };
9341
+ }
9342
+ render() {
9343
+ if (this.state.status === 'active') return;
9344
+ let cls = 'widget-internet-status';
9345
+ let text = '';
9346
+ if (this.state.status !== 'just_active') {
9347
+ cls += ' negative';
9348
+ text = `${this.props.t('network_error')}. ${this.props.t('try_reconnecting')}...`;
9349
+ } else {
9350
+ cls += ' positive';
9351
+ text = this.props.t('reconnect_successfully');
9352
+ }
9353
+ return (0,preact_module.h)("div", {
9354
+ class: cls
9355
+ }, text);
9356
+ }
9357
+ }
9358
+ ;// ./src/chatbox/ListField.js
9359
+
9360
+
9361
+
9362
+ class ListField extends common/* Com */.Mw {
9363
+ constructor(props) {
9364
+ super(props);
9365
+ this.setState({
9366
+ search: '',
9367
+ isShow: false
9368
+ });
9369
+ }
9370
+ render() {
9371
+ let fields = util/* default */.A.filter(this.props.items, item => {
9372
+ let search = this.state.search.toLowerCase();
9373
+ let name = item || '';
9374
+ return name.toLowerCase().indexOf(search) > -1;
9375
+ });
9376
+ let $fields = util/* default */.A.map(fields, field => {
9377
+ return (0,preact_module.h)("li", {
9378
+ class: "custom-select--item-options",
9379
+ onClick: () => this.add(field)
9380
+ }, field);
9381
+ });
9382
+ let $selected = util/* default */.A.map(this.props.selected, (item, i) => {
9383
+ return (0,preact_module.h)("div", {
9384
+ class: "custom-select--selected-item",
9385
+ onClick: e => this.remove(e, i)
9386
+ }, item, (0,preact_module.h)("i", {
9387
+ class: "icn-delete delete-tag"
9388
+ }));
9389
+ });
9390
+ let $dropdown = (0,preact_module.h)("div", {
9391
+ class: "custom-select--wrap-options"
9392
+ }, (0,preact_module.h)("input", {
9393
+ onClick: e => {
9394
+ e.preventDefault();
9395
+ e.stopPropagation();
9396
+ this.setState({
9397
+ isShow: true
9398
+ });
9399
+ },
9400
+ type: "text",
9401
+ onInput: e => this.setState({
9402
+ search: e.target.value
9403
+ }),
9404
+ value: this.state.search,
9405
+ placeholder: "T\xECm ki\u1EBFm",
9406
+ class: "custom-select--input-search"
9407
+ }), (0,preact_module.h)("ul", {
9408
+ class: "custom-select--items-options"
9409
+ }, $fields));
9410
+ if (!this.state.isShow) {
9411
+ $dropdown = null;
9412
+ }
9413
+ return (0,preact_module.h)("div", {
9414
+ class: "form-control custom-select"
9415
+ }, (0,preact_module.h)(common/* Clickaway */.tW, {
9416
+ onClickaway: e => this.clickaway()
9417
+ }, (0,preact_module.h)("div", {
9418
+ class: "custom-select--wrap-selected",
9419
+ onClick: () => this.setState({
9420
+ isShow: !this.state.isShow
9421
+ })
9422
+ }, (0,preact_module.h)("div", {
9423
+ class: "custom-select--selected-items"
9424
+ }, $selected), $dropdown, (0,preact_module.h)("div", {
9425
+ class: "custom-select--icon-dropdown"
9426
+ }, (0,preact_module.h)("svg", {
9427
+ width: "24",
9428
+ height: "24",
9429
+ viewBox: "0 0 24 24",
9430
+ fill: "none",
9431
+ xmlns: "http://www.w3.org/2000/svg"
9432
+ }, (0,preact_module.h)("g", {
9433
+ opacity: "0.6"
9434
+ }, (0,preact_module.h)("path", {
9435
+ d: "M7 9.5L12 14.5L17 9.5H7Z",
9436
+ fill: "black"
9437
+ })))))));
9438
+ }
9439
+ clickaway() {
9440
+ this.setState({
9441
+ isShow: false
9442
+ });
9443
+ }
9444
+ add(field) {
9445
+ this.props.onAddItem && this.props.onAddItem(field);
9446
+ }
9447
+ remove(e, index) {
9448
+ e.preventDefault();
9449
+ e.stopPropagation();
9450
+ this.props.onRemoveItem && this.props.onRemoveItem(index);
9451
+ }
9452
+ }
9261
9453
  ;// ./src/chatbox/Widget.js
9262
9454
  function Widget_defineProperty(e, r, t) { return (r = Widget_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
9263
9455
  function Widget_toPropertyKey(t) { var i = Widget_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
@@ -9273,6 +9465,7 @@ var empty = __webpack_require__(9419);
9273
9465
 
9274
9466
 
9275
9467
 
9468
+
9276
9469
  let Order = false;
9277
9470
  const LoadOrder = () => __webpack_require__.e(/* import() */ 185).then(__webpack_require__.bind(__webpack_require__, 4185));
9278
9471
 
@@ -9690,12 +9883,12 @@ class Widget extends common/* Com */.Mw {
9690
9883
  class: "checkbox"
9691
9884
  }, (0,preact_module.h)("input", {
9692
9885
  type: "checkbox",
9693
- id: 'form-checkbox' + Widget_encode(field.key) + item.value,
9886
+ id: 'form-checkbox' + encode(field.key) + item.value,
9694
9887
  onChange: e => this.toggleCheckboxField(field.key, item.value),
9695
9888
  checked: values.includes(item.value)
9696
9889
  }), (0,preact_module.h)("label", {
9697
9890
  class: "checkbox--label",
9698
- for: 'form-checkbox' + Widget_encode(field.key) + item.value
9891
+ for: 'form-checkbox' + encode(field.key) + item.value
9699
9892
  }, this.props.t.i18n(item.i18n_label) || item.label || item.value), (0,preact_module.h)("div", {
9700
9893
  class: "checkbox--check"
9701
9894
  }, (0,preact_module.h)("div", null)));
@@ -9727,13 +9920,13 @@ class Widget extends common/* Com */.Mw {
9727
9920
  class: "radio"
9728
9921
  }, (0,preact_module.h)("input", {
9729
9922
  type: "radio",
9730
- name: 'form-radio' + Widget_encode(field.key),
9731
- id: 'form-radio' + Widget_encode(field.key) + item.value,
9923
+ name: 'form-radio' + encode(field.key),
9924
+ id: 'form-radio' + encode(field.key) + item.value,
9732
9925
  onChange: e => this.toggleRadioField(field.key, item.value),
9733
9926
  checked: value === item.value
9734
9927
  }), (0,preact_module.h)("label", {
9735
9928
  class: "radio--label",
9736
- for: 'form-radio' + Widget_encode(field.key) + item.value
9929
+ for: 'form-radio' + encode(field.key) + item.value
9737
9930
  }, this.props.t.i18n(item.i18n_label) || item.label || item.value), (0,preact_module.h)("div", {
9738
9931
  class: "radio--check"
9739
9932
  }, (0,preact_module.h)("div", null)));
@@ -9782,9 +9975,9 @@ class Widget extends common/* Com */.Mw {
9782
9975
  $field = (0,preact_module.h)("textarea", {
9783
9976
  class: `form-control ${errclass}`,
9784
9977
  ref: ref => {
9785
- this['form_' + Widget_encode(key)] = ref;
9978
+ this['form_' + encode(key)] = ref;
9786
9979
  },
9787
- id: 'form_' + Widget_encode(key),
9980
+ id: 'form_' + encode(key),
9788
9981
  value: field.value || '',
9789
9982
  onInput: e => this.onInputChange(key, e.target.value),
9790
9983
  onChange: e => this.onInputChange(key, e.target.value),
@@ -9798,13 +9991,13 @@ class Widget extends common/* Com */.Mw {
9798
9991
  $field = this.renderDropdownField(field);
9799
9992
  } else {
9800
9993
  $field = (0,preact_module.h)("input", {
9801
- id: 'form_' + Widget_encode(key),
9994
+ id: 'form_' + encode(key),
9802
9995
  value: field.value || '',
9803
9996
  onInput: e => this.onInputChange(key, e.target.value),
9804
9997
  onChange: e => this.onInputChange(key, e.target.value),
9805
9998
  onKeyDown: e => this.onKeywordField(e, form, formName, key),
9806
9999
  ref: ref => {
9807
- this['form_' + Widget_encode(key)] = ref;
10000
+ this['form_' + encode(key)] = ref;
9808
10001
  },
9809
10002
  class: `form-control ${errclass}`,
9810
10003
  type: "text"
@@ -9812,11 +10005,11 @@ class Widget extends common/* Com */.Mw {
9812
10005
  }
9813
10006
  } else if (field.type === 'number') {
9814
10007
  $field = (0,preact_module.h)("input", {
9815
- id: 'form_' + Widget_encode(key),
10008
+ id: 'form_' + encode(key),
9816
10009
  value: field.value,
9817
10010
  onInput: e => this.onInputChange(key, e.target.value),
9818
10011
  ref: ref => {
9819
- this['form_' + Widget_encode(key)] = ref;
10012
+ this['form_' + encode(key)] = ref;
9820
10013
  },
9821
10014
  class: `form-control ${errclass}`,
9822
10015
  type: "number"
@@ -9826,12 +10019,12 @@ class Widget extends common/* Com */.Mw {
9826
10019
  class: "checkbox"
9827
10020
  }, (0,preact_module.h)("input", {
9828
10021
  type: "checkbox",
9829
- id: 'form-checkbox' + Widget_encode(key),
10022
+ id: 'form-checkbox' + encode(key),
9830
10023
  onInput: e => this.onBooleanChange(key, e),
9831
10024
  checked: field.value
9832
10025
  }), (0,preact_module.h)("label", {
9833
10026
  class: "checkbox--label",
9834
- for: 'form-checkbox' + Widget_encode(key)
10027
+ for: 'form-checkbox' + encode(key)
9835
10028
  }, field.label), (0,preact_module.h)("div", {
9836
10029
  class: "checkbox--check"
9837
10030
  }, (0,preact_module.h)("div", null)));
@@ -9840,12 +10033,12 @@ class Widget extends common/* Com */.Mw {
9840
10033
  class: "radio"
9841
10034
  }, (0,preact_module.h)("input", {
9842
10035
  type: "radio",
9843
- id: 'form-radio' + Widget_encode(key) + Widget_encode(item.value),
10036
+ id: 'form-radio' + encode(key) + encode(item.value),
9844
10037
  checked: field.value === item.value,
9845
10038
  onInput: e => this.onInputChange(key, item.value)
9846
10039
  }), (0,preact_module.h)("label", {
9847
10040
  class: "radio--label",
9848
- for: 'form-radio' + Widget_encode(key) + Widget_encode(item.value)
10041
+ for: 'form-radio' + encode(key) + encode(item.value)
9849
10042
  }, this.props.t.i18n(item.i18n_label) || item.label || item.value), (0,preact_module.h)("div", {
9850
10043
  class: "radio--check"
9851
10044
  }, (0,preact_module.h)("div", {
@@ -9865,7 +10058,7 @@ class Widget extends common/* Com */.Mw {
9865
10058
  $field = this.renderDropdownField(field);
9866
10059
  } else if (field.type === 'datetime') {
9867
10060
  $field = (0,preact_module.h)("input", {
9868
- id: 'form_' + Widget_encode(key),
10061
+ id: 'form_' + encode(key),
9869
10062
  value: field.value,
9870
10063
  onInput: e => this.onInputChange(key, e.target.value),
9871
10064
  class: `form-control ${errclass}`,
@@ -9884,10 +10077,10 @@ class Widget extends common/* Com */.Mw {
9884
10077
  }
9885
10078
  if (field.label) label = field.label;
9886
10079
  return (0,preact_module.h)("div", {
9887
- key: 'form_' + Widget_encode(key)
10080
+ key: 'form_' + encode(key)
9888
10081
  }, (0,preact_module.h)("label", {
9889
10082
  class: "label",
9890
- for: 'form_' + Widget_encode(key)
10083
+ for: 'form_' + encode(key)
9891
10084
  }, label, field.is_required ? (0,preact_module.h)("span", {
9892
10085
  class: "red"
9893
10086
  }, "*") : ''), $field, field.error ? (0,preact_module.h)("div", {
@@ -10006,14 +10199,14 @@ class Widget extends common/* Com */.Mw {
10006
10199
  if (focusfieldkey || field.type !== 'text') return;
10007
10200
  if (!field.value || field.error) focusfieldkey = key;
10008
10201
  });
10009
- var $input = this['form_' + Widget_encode(focusfieldkey)];
10202
+ var $input = this['form_' + encode(focusfieldkey)];
10010
10203
  if ($input) $input.focus();
10011
10204
  util/* default */.A.setTimeout(() => {
10012
10205
  util/* default */.A.map(this.state.formData, (field, key) => {
10013
10206
  if (focusfieldkey || field.type !== 'text') return;
10014
10207
  if (!field.value || field.error) focusfieldkey = key;
10015
10208
  });
10016
- var $input = this['form_' + Widget_encode(focusfieldkey)];
10209
+ var $input = this['form_' + encode(focusfieldkey)];
10017
10210
  if ($input) $input.focus();
10018
10211
  }, 200);
10019
10212
  return;
@@ -10086,6 +10279,10 @@ class Widget extends common/* Com */.Mw {
10086
10279
  onPostback: e => this.createPostback(e),
10087
10280
  t: this.props.t,
10088
10281
  plugin: this.props.plugin
10282
+ }), (0,preact_module.h)(ConnectionStatus, {
10283
+ cid: this.props.cid,
10284
+ store: this.props.store,
10285
+ t: this.props.t
10089
10286
  })), (0,preact_module.h)(Rating, {
10090
10287
  forceView: this.props.view,
10091
10288
  plugin: this.props.plugin,
@@ -10351,7 +10548,7 @@ class FormMounter extends common/* Com */.Mw {
10351
10548
  this.props.onMount(this.props.form);
10352
10549
  }
10353
10550
  }
10354
- function Widget_encode(key) {
10551
+ function encode(key) {
10355
10552
  return encodeURIComponent(key);
10356
10553
  }
10357
10554
  ;// ./src/chatbox/main.js