@subiz/widget-v4 4.1.185 → 4.1.186
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/less/chatbox.less +1 -0
- package/assets/less/widget.less +45 -13
- package/compiled_src/chatbox/ChatButton.js +14 -9
- package/compiled_src/chatbox/main.js +2 -0
- package/compiled_src/store/store.js +1 -1
- package/compiled_src/util/common.js +1 -0
- package/compiled_src/util/index.js +1 -0
- package/compiled_src/util/op.js +9 -0
- package/package.json +1 -1
- package/src/chatbox/ChatButton.js +16 -8
- package/src/chatbox/main.js +2 -0
- package/src/store/store.js +1 -1
- package/src/util/common.js +1 -0
- package/src/util/index.js +1 -0
- package/src/util/op.js +18 -6
package/assets/less/chatbox.less
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
@desktop-chat-button-margin-x: '@desktop_button.margin_x'; //20px;
|
|
20
20
|
@desktop-chat-button-margin-y: '@desktop_button.margin_y'; // 20px;
|
|
21
21
|
@desktop-widget-max-height: '@desktop_widget_max_height'; // calc(100% - desktop_buttom.margin_y)
|
|
22
|
+
@preview-max-width: '@preview_max_width';
|
|
22
23
|
|
|
23
24
|
@form-page-background-color: '@form_background_color';
|
|
24
25
|
@form-page-header-font-size: '@form_header_font_size';
|
package/assets/less/widget.less
CHANGED
|
@@ -645,6 +645,34 @@
|
|
|
645
645
|
&.right {
|
|
646
646
|
align-items: flex-end;
|
|
647
647
|
}
|
|
648
|
+
|
|
649
|
+
&.horizontal {
|
|
650
|
+
flex-direction: row;
|
|
651
|
+
flex-wrap: wrap;
|
|
652
|
+
align-items: center;
|
|
653
|
+
gap: 10px;
|
|
654
|
+
|
|
655
|
+
&.right {
|
|
656
|
+
justify-content: flex-end;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
&.left {
|
|
660
|
+
justify-content: flex-start;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
.widget-preview-quick-reply-wrapper.horizontal .widget-preview-quick-reply-item {
|
|
666
|
+
margin: 0;
|
|
667
|
+
max-width: 200px;
|
|
668
|
+
overflow: hidden;
|
|
669
|
+
text-overflow: ellipsis;
|
|
670
|
+
white-space: nowrap;
|
|
671
|
+
padding: 6px 15px;
|
|
672
|
+
|
|
673
|
+
&:last-child {
|
|
674
|
+
margin-bottom: 0;
|
|
675
|
+
}
|
|
648
676
|
}
|
|
649
677
|
|
|
650
678
|
.widget-preview-quick-reply-item {
|
|
@@ -719,7 +747,7 @@
|
|
|
719
747
|
}
|
|
720
748
|
|
|
721
749
|
.widget-preview-new-wrapper {
|
|
722
|
-
max-width:
|
|
750
|
+
max-width: @preview-max-width;
|
|
723
751
|
position: relative;
|
|
724
752
|
opacity: 1;
|
|
725
753
|
transition:
|
|
@@ -740,18 +768,6 @@
|
|
|
740
768
|
display: flex;
|
|
741
769
|
}
|
|
742
770
|
}
|
|
743
|
-
|
|
744
|
-
.widget-preview--btn-close {
|
|
745
|
-
width: 32px;
|
|
746
|
-
height: 32px;
|
|
747
|
-
background-color: #00000040;
|
|
748
|
-
background-size: 16px 16px;
|
|
749
|
-
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMi4yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXIteCI+PGxpbmUgeDE9IjE4IiB5MT0iNiIgeDI9IjYiIHkyPSIxOCI+PC9saW5lPjxsaW5lIHgxPSI2IiB5MT0iNiIgeDI9IjE4IiB5Mj0iMTgiPjwvbGluZT48L3N2Zz4K');
|
|
750
|
-
|
|
751
|
-
&:hover {
|
|
752
|
-
background-color: #00000066;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
771
|
}
|
|
756
772
|
|
|
757
773
|
.widget-preview-x-wrapper {
|
|
@@ -763,9 +779,25 @@
|
|
|
763
779
|
left: -20px;
|
|
764
780
|
bottom: 100%;
|
|
765
781
|
|
|
782
|
+
&.mobile {
|
|
783
|
+
display: flex;
|
|
784
|
+
}
|
|
785
|
+
|
|
766
786
|
&.right {
|
|
767
787
|
justify-content: flex-end;
|
|
768
788
|
left: unset;
|
|
769
789
|
right: -20px;
|
|
770
790
|
}
|
|
791
|
+
|
|
792
|
+
.widget-preview--btn-close {
|
|
793
|
+
width: 32px;
|
|
794
|
+
height: 32px;
|
|
795
|
+
background-color: #00000040;
|
|
796
|
+
background-size: 16px 16px;
|
|
797
|
+
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMi4yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXIteCI+PGxpbmUgeDE9IjE4IiB5MT0iNiIgeDI9IjYiIHkyPSIxOCI+PC9saW5lPjxsaW5lIHgxPSI2IiB5MT0iNiIgeDI9IjE4IiB5Mj0iMTgiPjwvbGluZT48L3N2Zz4K');
|
|
798
|
+
|
|
799
|
+
&:hover {
|
|
800
|
+
background-color: #00000066;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
771
803
|
}
|
|
@@ -48,11 +48,14 @@ class ChatButton extends _common.Com {
|
|
|
48
48
|
if (screen === 'widget') return;
|
|
49
49
|
if (minimized && Date.now() - minimized < Ms30Mins) return;
|
|
50
50
|
if (this.props.store.isMobile()) {
|
|
51
|
-
this.props.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
let mobileDisabled = _index.default.get(this.props.plugin, 'chatbox.greeting.mobile_disabled');
|
|
52
|
+
if (mobileDisabled) {
|
|
53
|
+
this.props.store.updateLastview({
|
|
54
|
+
previewEvent: ev
|
|
55
|
+
});
|
|
56
|
+
this.forceUpdate();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
this.props.store.updateLastview({
|
|
58
61
|
screen: 'preview',
|
|
@@ -210,7 +213,8 @@ class ChatButton extends _common.Com {
|
|
|
210
213
|
let greeting = _index.default.get(accountSetting, 'greeting', {});
|
|
211
214
|
let text = this.props.t.i18n(_index.default.get(greeting, 'greeting', {})) || greeting.message;
|
|
212
215
|
let enabled = greeting.enabled;
|
|
213
|
-
|
|
216
|
+
let mobileDisabled = this.props.store.isMobile() && greeting.mobile_disabled;
|
|
217
|
+
if (!text || !enabled || mobileDisabled) {
|
|
214
218
|
return;
|
|
215
219
|
}
|
|
216
220
|
this.ShowGreeting();
|
|
@@ -269,7 +273,6 @@ class ChatButton extends _common.Com {
|
|
|
269
273
|
return agent;
|
|
270
274
|
}
|
|
271
275
|
renderPreview() {
|
|
272
|
-
if (this.props.store.isMobile()) return;
|
|
273
276
|
if (!this.state.hasPreviewDom) return;
|
|
274
277
|
let previewEvent = this.state.previewEvent;
|
|
275
278
|
let agent = this.getAgentOfPreviewEvent(previewEvent);
|
|
@@ -283,6 +286,7 @@ class ChatButton extends _common.Com {
|
|
|
283
286
|
let attachments = _index.default.get(previewEvent, 'data.message.attachments') || [];
|
|
284
287
|
let quickReplies = _index.default.find(attachments, att => att.type === 'quick_replies');
|
|
285
288
|
quickReplies = _index.default.get(quickReplies, 'quick_replies') || [];
|
|
289
|
+
quickReplies = _index.default.take(quickReplies, 10);
|
|
286
290
|
let imgAtt = _index.default.find(attachments, att => _index.default.includes(att.mimetype, 'image') && att.url);
|
|
287
291
|
let uri = _index.default.get(imgAtt, 'url') || '';
|
|
288
292
|
if (uri && !uri.startsWith('https://') && !uri.startsWith('http://') && !uri.startsWith('content://') && !uri.startsWith('data:')) {
|
|
@@ -291,7 +295,7 @@ class ChatButton extends _common.Com {
|
|
|
291
295
|
return (0, _preact.h)("div", {
|
|
292
296
|
class: `widget-preview-new-wrapper ${this.state.previewExtraCls}`
|
|
293
297
|
}, (0, _preact.h)("div", {
|
|
294
|
-
class: `widget-preview-x-wrapper ${position}`
|
|
298
|
+
class: `widget-preview-x-wrapper ${position} ${this.props.store.isMobile() ? 'mobile' : ''}`
|
|
295
299
|
}, (0, _preact.h)("div", {
|
|
296
300
|
class: "widget-preview--btn-close",
|
|
297
301
|
onClick: e => this.closePreview(e)
|
|
@@ -322,10 +326,11 @@ class ChatButton extends _common.Com {
|
|
|
322
326
|
}, (0, _preact.h)("img", {
|
|
323
327
|
src: uri
|
|
324
328
|
}))), _index.default.size(quickReplies) > 0 && (0, _preact.h)("div", {
|
|
325
|
-
class: `widget-preview-quick-reply-wrapper ${position}`
|
|
329
|
+
class: `widget-preview-quick-reply-wrapper ${position} ${_index.default.size(quickReplies) > 4 ? 'horizontal' : ''}`
|
|
326
330
|
}, _index.default.map(quickReplies, reply => {
|
|
327
331
|
if (!(reply.title || '').trim()) return;
|
|
328
332
|
return (0, _preact.h)("div", {
|
|
333
|
+
title: reply.title,
|
|
329
334
|
class: "widget-preview-quick-reply-item",
|
|
330
335
|
onClick: () => {
|
|
331
336
|
this.props.onSelectQuickReply({
|
|
@@ -25,6 +25,8 @@ class Main extends _common.Com {
|
|
|
25
25
|
let chatbox = found.chatbox;
|
|
26
26
|
let margin_y = _index.default.get(chatbox, 'desktop_button.margin_y');
|
|
27
27
|
chatbox.desktop_widget_max_height = margin_y ? `calc(100% - ${margin_y + 10}px)` : 'calc(100% - 40px)';
|
|
28
|
+
const PREVIEW_MAX_WIDTH = 340;
|
|
29
|
+
chatbox.preview_max_width = Math.min(PREVIEW_MAX_WIDTH, chatbox.width) + 'px';
|
|
28
30
|
var outcss = _index.default.replaceCssVariable(css, chatbox);
|
|
29
31
|
_index.default.setCss(this.props.plugin.id, this.$cssStyleDiv, outcss);
|
|
30
32
|
}
|
|
@@ -521,7 +521,7 @@ class Store {
|
|
|
521
521
|
lastView.screen = 'widget';
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
|
-
if (this.isMobile()) lastView.screen = '
|
|
524
|
+
if (this.isMobile()) lastView.screen = 'preview';
|
|
525
525
|
this.kv.put('lastview', lastView);
|
|
526
526
|
}
|
|
527
527
|
async _initResource(accid, auth, realtimep) {
|
|
@@ -628,6 +628,7 @@ function replaceCssVariable(css, setting) {
|
|
|
628
628
|
tokens = tokenize(tokens, "'@desktop_button.margin_x'");
|
|
629
629
|
tokens = tokenize(tokens, "'@desktop_button.margin_y'");
|
|
630
630
|
tokens = tokenize(tokens, "'@desktop_widget_max_height'");
|
|
631
|
+
tokens = tokenize(tokens, "'@preview_max_width'");
|
|
631
632
|
tokens = tokenize(tokens, "'@mobile_button.width'");
|
|
632
633
|
tokens = tokenize(tokens, "'@mobile_button.height'");
|
|
633
634
|
tokens = tokenize(tokens, "'@mobile_button.background'");
|
package/compiled_src/util/op.js
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.get = get;
|
|
7
7
|
exports.set = set;
|
|
8
|
+
exports.take = take;
|
|
8
9
|
var toStr = Object.prototype.toString;
|
|
9
10
|
var isArray = Array.isArray || function (obj) {
|
|
10
11
|
return toStr.call(obj) === '[object Array]';
|
|
@@ -52,4 +53,12 @@ function set(obj, path, value) {
|
|
|
52
53
|
obj[currentPath] = typeof path[1] === 'number' ? [] : {};
|
|
53
54
|
}
|
|
54
55
|
return set(obj[currentPath], path.slice(1), value);
|
|
56
|
+
}
|
|
57
|
+
function take(arr, n = 1) {
|
|
58
|
+
if (!Array.isArray(arr)) return [];
|
|
59
|
+
let len = arr.length;
|
|
60
|
+
if (typeof len !== 'number' || len <= 0) return [];
|
|
61
|
+
if (n <= 0) return [];
|
|
62
|
+
let end = Math.min(n, len);
|
|
63
|
+
return arr.slice(0, end);
|
|
55
64
|
}
|
package/package.json
CHANGED
|
@@ -49,10 +49,13 @@ export default class ChatButton extends Com {
|
|
|
49
49
|
|
|
50
50
|
if (this.props.store.isMobile()) {
|
|
51
51
|
// dont show greeting fro mobile anymore
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
let mobileDisabled = sb.get(this.props.plugin, 'chatbox.greeting.mobile_disabled')
|
|
53
|
+
if (mobileDisabled) {
|
|
54
|
+
// need setState previewEvent for display 1 unread in mobile
|
|
55
|
+
this.props.store.updateLastview({previewEvent: ev})
|
|
56
|
+
this.forceUpdate()
|
|
57
|
+
return
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
this.props.store.updateLastview({screen: 'preview', previewEvent: ev})
|
|
@@ -212,7 +215,8 @@ export default class ChatButton extends Com {
|
|
|
212
215
|
let text = this.props.t.i18n(sb.get(greeting, 'greeting', {})) || greeting.message
|
|
213
216
|
|
|
214
217
|
let enabled = greeting.enabled
|
|
215
|
-
|
|
218
|
+
let mobileDisabled = this.props.store.isMobile() && greeting.mobile_disabled
|
|
219
|
+
if (!text || !enabled || mobileDisabled) {
|
|
216
220
|
return
|
|
217
221
|
}
|
|
218
222
|
this.ShowGreeting()
|
|
@@ -278,7 +282,7 @@ export default class ChatButton extends Com {
|
|
|
278
282
|
}
|
|
279
283
|
|
|
280
284
|
renderPreview() {
|
|
281
|
-
if (this.props.store.isMobile()) return
|
|
285
|
+
//if (this.props.store.isMobile()) return
|
|
282
286
|
if (!this.state.hasPreviewDom) return
|
|
283
287
|
let previewEvent = this.state.previewEvent
|
|
284
288
|
let agent = this.getAgentOfPreviewEvent(previewEvent)
|
|
@@ -294,6 +298,7 @@ export default class ChatButton extends Com {
|
|
|
294
298
|
let attachments = sb.get(previewEvent, 'data.message.attachments') || []
|
|
295
299
|
let quickReplies = sb.find(attachments, (att) => att.type === 'quick_replies')
|
|
296
300
|
quickReplies = sb.get(quickReplies, 'quick_replies') || []
|
|
301
|
+
quickReplies = sb.take(quickReplies, 10)
|
|
297
302
|
let imgAtt = sb.find(attachments, (att) => sb.includes(att.mimetype, 'image') && att.url)
|
|
298
303
|
let uri = sb.get(imgAtt, 'url') || ''
|
|
299
304
|
if (
|
|
@@ -308,7 +313,7 @@ export default class ChatButton extends Com {
|
|
|
308
313
|
|
|
309
314
|
return (
|
|
310
315
|
<div class={`widget-preview-new-wrapper ${this.state.previewExtraCls}`}>
|
|
311
|
-
<div class={`widget-preview-x-wrapper ${position}`}>
|
|
316
|
+
<div class={`widget-preview-x-wrapper ${position} ${this.props.store.isMobile() ? 'mobile' : ''}`}>
|
|
312
317
|
<div class='widget-preview--btn-close' onClick={(e) => this.closePreview(e)} />
|
|
313
318
|
</div>
|
|
314
319
|
<div class={`widget-preview-text-message ${position}`} onClick={(e) => this.onPreviewClick(e)}>
|
|
@@ -338,11 +343,14 @@ export default class ChatButton extends Com {
|
|
|
338
343
|
</div>
|
|
339
344
|
)}
|
|
340
345
|
{sb.size(quickReplies) > 0 && (
|
|
341
|
-
<div
|
|
346
|
+
<div
|
|
347
|
+
class={`widget-preview-quick-reply-wrapper ${position} ${sb.size(quickReplies) > 4 ? 'horizontal' : ''}`}
|
|
348
|
+
>
|
|
342
349
|
{sb.map(quickReplies, (reply) => {
|
|
343
350
|
if (!(reply.title || '').trim()) return
|
|
344
351
|
return (
|
|
345
352
|
<div
|
|
353
|
+
title={reply.title}
|
|
346
354
|
class='widget-preview-quick-reply-item'
|
|
347
355
|
onClick={() => {
|
|
348
356
|
// copy chooseQuickReply function from Event.js
|
package/src/chatbox/main.js
CHANGED
|
@@ -26,6 +26,8 @@ export default class Main extends Com {
|
|
|
26
26
|
let chatbox = found.chatbox
|
|
27
27
|
let margin_y = sb.get(chatbox, 'desktop_button.margin_y')
|
|
28
28
|
chatbox.desktop_widget_max_height = margin_y ? `calc(100% - ${margin_y + 10}px)` : 'calc(100% - 40px)'
|
|
29
|
+
const PREVIEW_MAX_WIDTH = 340
|
|
30
|
+
chatbox.preview_max_width = Math.min(PREVIEW_MAX_WIDTH, chatbox.width) + 'px'
|
|
29
31
|
var outcss = sb.replaceCssVariable(css, chatbox)
|
|
30
32
|
sb.setCss(this.props.plugin.id, this.$cssStyleDiv, outcss)
|
|
31
33
|
}
|
package/src/store/store.js
CHANGED
package/src/util/common.js
CHANGED
|
@@ -668,6 +668,7 @@ export function replaceCssVariable(css, setting) {
|
|
|
668
668
|
tokens = tokenize(tokens, "'@desktop_button.margin_x'")
|
|
669
669
|
tokens = tokenize(tokens, "'@desktop_button.margin_y'")
|
|
670
670
|
tokens = tokenize(tokens, "'@desktop_widget_max_height'")
|
|
671
|
+
tokens = tokenize(tokens, "'@preview_max_width'")
|
|
671
672
|
tokens = tokenize(tokens, "'@mobile_button.width'")
|
|
672
673
|
tokens = tokenize(tokens, "'@mobile_button.height'")
|
|
673
674
|
tokens = tokenize(tokens, "'@mobile_button.background'")
|
package/src/util/index.js
CHANGED
package/src/util/op.js
CHANGED
|
@@ -9,26 +9,26 @@ var isArray =
|
|
|
9
9
|
return toStr.call(obj) === '[object Array]'
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
function hasOwnProperty
|
|
12
|
+
function hasOwnProperty(obj, prop) {
|
|
13
13
|
if (obj == null) return false
|
|
14
14
|
//to handle objects with null prototypes (too edge case?)
|
|
15
15
|
return Object.prototype.hasOwnProperty.call(obj, prop)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function getKey
|
|
18
|
+
function getKey(key) {
|
|
19
19
|
var intKey = parseInt(key)
|
|
20
20
|
return intKey.toString() === key ? intKey : key
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function hasShallowProperty
|
|
23
|
+
function hasShallowProperty(obj, prop) {
|
|
24
24
|
return (typeof prop === 'number' && isArray(obj)) || hasOwnProperty(obj, prop)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
function getShallowProperty
|
|
27
|
+
function getShallowProperty(obj, prop) {
|
|
28
28
|
if (hasShallowProperty(obj, prop)) return obj[prop]
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export function get
|
|
31
|
+
export function get(obj, path, defaultValue) {
|
|
32
32
|
if (typeof path === 'number') path = [path]
|
|
33
33
|
if (!path || path.length === 0) return obj
|
|
34
34
|
if (obj == null) return defaultValue
|
|
@@ -44,7 +44,7 @@ export function get (obj, path, defaultValue) {
|
|
|
44
44
|
return get(obj[currentPath], path.slice(1), defaultValue)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export function set
|
|
47
|
+
export function set(obj, path, value) {
|
|
48
48
|
if (typeof path === 'number') path = [path]
|
|
49
49
|
if (!path || path.length === 0) return obj
|
|
50
50
|
if (typeof path === 'string') {
|
|
@@ -65,3 +65,15 @@ export function set (obj, path, value) {
|
|
|
65
65
|
|
|
66
66
|
return set(obj[currentPath], path.slice(1), value)
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
export function take(arr, n = 1) {
|
|
70
|
+
if (!Array.isArray(arr)) return []
|
|
71
|
+
|
|
72
|
+
let len = arr.length
|
|
73
|
+
if (typeof len !== 'number' || len <= 0) return []
|
|
74
|
+
|
|
75
|
+
if (n <= 0) return []
|
|
76
|
+
let end = Math.min(n, len)
|
|
77
|
+
|
|
78
|
+
return arr.slice(0, end)
|
|
79
|
+
}
|