@subiz/widget-v4 4.1.113 → 4.1.115
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/message.less +148 -9
- package/compiled_src/chatbox/Event.js +131 -2
- package/compiled_src/chatbox/Events.js +24 -11
- package/compiled_src/chatbox/ImageAttachments.js +1 -1
- package/compiled_src/chatbox/InfoMessage.js +1 -0
- package/compiled_src/chatbox/PoweredBy.js +1 -0
- package/compiled_src/chatbox/Widget.js +16 -11
- package/compiled_src/lib.js +3 -0
- package/compiled_src/store/store.js +25 -1
- package/dist/195ec5442e3.278.js +1 -0
- package/dist/{19565267fde.app.js → 195ec5442e3.app.js} +1 -1
- package/dist/{19565267fde.index.html → 195ec5442e3.index.html} +1 -1
- package/dist/{19565267fde.library.html → 195ec5442e3.library.html} +1 -1
- package/dist/{19565267fde.library.js → 195ec5442e3.library.js} +1 -1
- package/dist/{19565267fde.preview.html → 195ec5442e3.preview.html} +1 -1
- package/dist/{19565267fde.preview.js → 195ec5442e3.preview.js} +1 -1
- package/dist/{19565267fde.webview.js → 195ec5442e3.webview.js} +1 -1
- package/dist/278.js +1 -1
- package/dist/HASH +1 -1
- package/package.json +3 -3
- package/src/chatbox/Event.js +151 -28
- package/src/chatbox/Events.js +27 -13
- package/src/chatbox/ImageAttachments.js +1 -1
- package/src/chatbox/InfoMessage.js +3 -0
- package/src/chatbox/PoweredBy.js +2 -0
- package/src/chatbox/Widget.js +10 -3
- package/src/lib.js +4 -0
- package/src/store/store.js +29 -1
- package/dist/19565267fde.278.js +0 -1
- /package/dist/{19565267fde.127.js → 195ec5442e3.127.js} +0 -0
- /package/dist/{19565267fde.132.js → 195ec5442e3.132.js} +0 -0
- /package/dist/{19565267fde.185.js → 195ec5442e3.185.js} +0 -0
- /package/dist/{19565267fde.27.js → 195ec5442e3.27.js} +0 -0
- /package/dist/{19565267fde.459.js → 195ec5442e3.459.js} +0 -0
- /package/dist/{19565267fde.490.js → 195ec5442e3.490.js} +0 -0
- /package/dist/{19565267fde.74.js → 195ec5442e3.74.js} +0 -0
- /package/dist/{19565267fde.997.js → 195ec5442e3.997.js} +0 -0
package/src/chatbox/Event.js
CHANGED
|
@@ -25,7 +25,9 @@ import {h, createRef} from 'preact'
|
|
|
25
25
|
export default class Event extends Com {
|
|
26
26
|
constructor(props) {
|
|
27
27
|
super(props)
|
|
28
|
+
this.props.store.onConvoEvent(this, (ev) => this.onEvent(ev))
|
|
28
29
|
this.refForm = createRef()
|
|
30
|
+
this.state = {pongs: sb.get(this.props.event, 'ev.data.message.pongs') || []}
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
render() {
|
|
@@ -49,6 +51,21 @@ export default class Event extends Com {
|
|
|
49
51
|
this.refForm.current && this.refForm.current.focus()
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
onEvent(ev) {
|
|
55
|
+
if (ev.id !== sb.get(this.props.event, 'ev.id')) return
|
|
56
|
+
this.setState({pongs: sb.get(ev, 'data.message.pongs') || []})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
hasLike() {
|
|
60
|
+
let {pongs} = this.state
|
|
61
|
+
return !!sb.find(pongs, (pong) => pong.type === 'like')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
hasDislike() {
|
|
65
|
+
let {pongs} = this.state
|
|
66
|
+
return !!sb.find(pongs, (pong) => pong.type === 'dislike')
|
|
67
|
+
}
|
|
68
|
+
|
|
52
69
|
chooseQuickReply(reply) {
|
|
53
70
|
let ev = sb.get(this.props.event, 'ev', {})
|
|
54
71
|
let message = {text: reply.title, format: 'plaintext'}
|
|
@@ -143,44 +160,53 @@ export default class Event extends Com {
|
|
|
143
160
|
</div>
|
|
144
161
|
)
|
|
145
162
|
}
|
|
163
|
+
if (this.props.store.isAIDevMode()) $time = null
|
|
146
164
|
|
|
147
165
|
let t = new sb.Date(ev.created).toLocaleString()
|
|
148
166
|
// message of agent
|
|
149
167
|
if (sb.get(ev, 'by.type') !== 'user') {
|
|
150
168
|
let $sender = null
|
|
151
169
|
if (this.props.event.mode === 'lead') $sender = this.renderAgentAvatar(ev)
|
|
170
|
+
let innercls = 'agent-convo-event-inner'
|
|
171
|
+
if (this.props.isLast) innercls += ' last'
|
|
152
172
|
return (
|
|
153
173
|
<div class='convo-event agent-message' title={t}>
|
|
154
174
|
{$time}
|
|
155
175
|
{$sender}
|
|
156
|
-
<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
<div class='agent-convo-event-wrapper'>
|
|
177
|
+
<div class={innercls}>
|
|
178
|
+
<TextMessage store={this.props.store} ev={ev} onLink={this.props.onLink} />
|
|
179
|
+
<ImageAttachments store={this.props.store} ev={ev} />
|
|
180
|
+
<AudioAttachments store={this.props.store} ev={ev} />
|
|
181
|
+
<VideoAttachments store={this.props.store} ev={ev} />
|
|
182
|
+
<FileAttachments store={this.props.store} ev={ev} />
|
|
183
|
+
<ButtonAttachments store={this.props.store} ev={ev} t={this.props.t} />
|
|
184
|
+
<FormAttachments
|
|
185
|
+
store={this.props.store}
|
|
186
|
+
onSubmit={this.props.onFormSubmit}
|
|
187
|
+
ref={this.refForm}
|
|
188
|
+
ev={ev}
|
|
189
|
+
t={this.props.t}
|
|
190
|
+
/>
|
|
191
|
+
<FormSubmitAttachments store={this.props.store} ev={ev} t={this.props.t} />
|
|
192
|
+
<GenericTemplateAttachments
|
|
193
|
+
store={this.props.store}
|
|
194
|
+
ev={ev}
|
|
195
|
+
onSelect={(e) => this.choosePostbackBtn(e)}
|
|
196
|
+
t={this.props.t}
|
|
197
|
+
/>
|
|
198
|
+
<ProductAttachments
|
|
199
|
+
t={this.props.t}
|
|
200
|
+
onPostback={(e) => this.choosePostbackBtn(e)}
|
|
201
|
+
store={this.props.store}
|
|
202
|
+
ev={ev}
|
|
203
|
+
/>
|
|
204
|
+
<OrderAttachments t={this.props.t} store={this.props.store} ev={ev} />
|
|
205
|
+
<QuickReplies store={this.props.store} ev={ev} onSelect={(e) => this.chooseQuickReply(e)} />
|
|
206
|
+
{this.renderReactions()}
|
|
207
|
+
{this.renderAIDevNote()}
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
184
210
|
</div>
|
|
185
211
|
)
|
|
186
212
|
}
|
|
@@ -232,6 +258,103 @@ export default class Event extends Com {
|
|
|
232
258
|
)
|
|
233
259
|
}
|
|
234
260
|
|
|
261
|
+
async onSendReaction(action) {
|
|
262
|
+
if (this._reacting) return
|
|
263
|
+
let ev = this.props.event.ev
|
|
264
|
+
let cid = sb.get(ev, 'data.message.conversation_id')
|
|
265
|
+
ev = {
|
|
266
|
+
type: 'message_pong',
|
|
267
|
+
data: {
|
|
268
|
+
message: {
|
|
269
|
+
id: ev.id,
|
|
270
|
+
pongs: [
|
|
271
|
+
{
|
|
272
|
+
type: action,
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
conversion_id: cid,
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
}
|
|
279
|
+
if (action == 'dislike' && this.props.store.isAIDevMode()) {
|
|
280
|
+
this.props.store.emitConvoEvent({
|
|
281
|
+
type: 'bad_feedbacked',
|
|
282
|
+
data: {
|
|
283
|
+
event: ev,
|
|
284
|
+
id: ev.id,
|
|
285
|
+
conversion_id: cid,
|
|
286
|
+
},
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
let {pongs} = this.state
|
|
291
|
+
if (action === 'like') {
|
|
292
|
+
pongs = pongs.filter((pong) => pong.type !== 'dislike')
|
|
293
|
+
pongs.push({type: 'like'})
|
|
294
|
+
} else if (action === 'dislike') {
|
|
295
|
+
pongs = pongs.filter((pong) => pong.type !== 'like')
|
|
296
|
+
pongs.push({type: 'dislike'})
|
|
297
|
+
} else if (action === 'remove_like') {
|
|
298
|
+
pongs = pongs.filter((pong) => pong.type !== 'like')
|
|
299
|
+
} else if (action === 'remove_dislike') {
|
|
300
|
+
pongs = pongs.filter((pong) => pong.type !== 'dislike')
|
|
301
|
+
}
|
|
302
|
+
this.setState({pongs})
|
|
303
|
+
this._reacting = true
|
|
304
|
+
let res = await this.props.store.sendReaction(cid, ev)
|
|
305
|
+
this._reacting = false
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
renderReactions() {
|
|
309
|
+
if (this.props.store.isAIDevMode()) return null
|
|
310
|
+
|
|
311
|
+
let ev = sb.get(this.props.event, 'ev') || {}
|
|
312
|
+
let pongs = sb.get(ev, 'data.message.pongs') || []
|
|
313
|
+
let hasLike = this.hasLike()
|
|
314
|
+
let hasDislike = this.hasDislike()
|
|
315
|
+
|
|
316
|
+
let likecls = 'message-event-action-btn'
|
|
317
|
+
if (hasLike) likecls += ' active'
|
|
318
|
+
let dislikecls = 'message-event-action-btn'
|
|
319
|
+
if (hasDislike) dislikecls += ' active'
|
|
320
|
+
return (
|
|
321
|
+
<div class='message-event-actions'>
|
|
322
|
+
<div class={likecls} onClick={() => this.onSendReaction(hasLike ? 'remove_like' : 'like')}>
|
|
323
|
+
<div class='message-event-action-btn-svg like' />
|
|
324
|
+
</div>
|
|
325
|
+
<div class={dislikecls} onClick={() => this.onSendReaction(hasDislike ? 'remove_dislike' : 'dislike')}>
|
|
326
|
+
<div class='message-event-action-btn-svg dislike' />
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
renderAIDevNote() {
|
|
333
|
+
if (!this.props.isLast) return null
|
|
334
|
+
if (!this.props.store.isAIDevMode()) return null
|
|
335
|
+
|
|
336
|
+
let ev = sb.get(this.props.event, 'ev') || {}
|
|
337
|
+
let pongs = sb.get(ev, 'data.message.pongs') || []
|
|
338
|
+
let hasLike = this.hasLike()
|
|
339
|
+
let hasDislike = this.hasDislike()
|
|
340
|
+
|
|
341
|
+
let likecls = 'message-event-action-btn message-event-action-btn__dev message-event-action-btn_like'
|
|
342
|
+
if (hasLike) likecls += ' active'
|
|
343
|
+
let dislikecls = 'message-event-action-btn message-event-action-btn__dev message-event-action-btn_dislike'
|
|
344
|
+
if (hasDislike) dislikecls += ' active'
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<div class='message-event-actions'>
|
|
348
|
+
<div class={likecls} onClick={() => this.onSendReaction(hasLike ? 'remove_like' : 'like')}>
|
|
349
|
+
<div class='message-event-action-btn-svg like' /> Good
|
|
350
|
+
</div>
|
|
351
|
+
<div class={dislikecls} onClick={() => this.onSendReaction(hasDislike ? 'remove_dislike' : 'dislike')}>
|
|
352
|
+
<div class='message-event-action-btn-svg dislike' /> Bad
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
|
|
235
358
|
renderUpdateConvo(ev) {
|
|
236
359
|
var state = sb.get(ev, 'data.conversation.state')
|
|
237
360
|
if (state === 'active') return null
|
package/src/chatbox/Events.js
CHANGED
|
@@ -55,19 +55,33 @@ export default class Events extends Com {
|
|
|
55
55
|
events = sb.map(events, (ev) => ({ev: ev}))
|
|
56
56
|
processEvents(convo, events)
|
|
57
57
|
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
let lastAgentMessageSentId = ''
|
|
59
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
60
|
+
let ev = sb.get(events, [i, 'ev']) || {}
|
|
61
|
+
let bytype = sb.get(ev, 'by.type')
|
|
62
|
+
if (bytype !== 'user' && ev.type === 'message_sent') {
|
|
63
|
+
lastAgentMessageSentId = ev.id
|
|
64
|
+
break
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let $events = sb.map(events, (ev) => {
|
|
69
|
+
let isLast = ev.ev.id === lastAgentMessageSentId
|
|
70
|
+
return (
|
|
71
|
+
<Event
|
|
72
|
+
isLast={isLast}
|
|
73
|
+
chatbox={this.props.chatbox}
|
|
74
|
+
onLink={this.props.onLink}
|
|
75
|
+
store={this.props.store}
|
|
76
|
+
onFormSubmit={this.props.onFormSubmit}
|
|
77
|
+
onSend={this.props.onSend}
|
|
78
|
+
onPostback={this.props.onPostback}
|
|
79
|
+
event={ev}
|
|
80
|
+
t={this.props.t}
|
|
81
|
+
key={ev.ev.id}
|
|
82
|
+
/>
|
|
83
|
+
)
|
|
84
|
+
})
|
|
71
85
|
|
|
72
86
|
let $loading = null
|
|
73
87
|
let style = 'opacity: 1 !important'
|
|
@@ -21,7 +21,7 @@ export default class ImageAttachment extends Com {
|
|
|
21
21
|
const DEFAULT_MAX_WIDTH = 267
|
|
22
22
|
|
|
23
23
|
let $container = this.containerRef.current
|
|
24
|
-
this.frameWidth = $container ? $container.offsetWidth : DEFAULT_MAX_WIDTH
|
|
24
|
+
this.frameWidth = $container ? $container.parentNode.parentNode.offsetWidth : DEFAULT_MAX_WIDTH
|
|
25
25
|
this.frameHeight = MAX_HEIGHT
|
|
26
26
|
this.setState({
|
|
27
27
|
ready: true,
|
|
@@ -15,6 +15,7 @@ export default class InfoMessage extends Com {
|
|
|
15
15
|
render() {
|
|
16
16
|
let ev = this.props.ev.ev
|
|
17
17
|
var $time = null
|
|
18
|
+
|
|
18
19
|
if (this.props.ev.show_time) {
|
|
19
20
|
$time = (
|
|
20
21
|
<div class='convo-event-time'>
|
|
@@ -23,6 +24,8 @@ export default class InfoMessage extends Com {
|
|
|
23
24
|
)
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
if (this.props.store.isAIDevMode()) $time = null
|
|
28
|
+
|
|
26
29
|
// if (this.ev.type === 'conversation_rating_requested') return <div class="info-message"></div>
|
|
27
30
|
if (ev.type === 'conversation_rated') {
|
|
28
31
|
var rating = sb.get(ev, 'data.conversation.ratings.0', {no_rating: true, rating: 0})
|
package/src/chatbox/PoweredBy.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
var logo = require('../../assets/img/subiz-mono.svg')
|
|
2
2
|
import {h} from 'preact'
|
|
3
|
+
|
|
3
4
|
export default function PoweredBy(props) {
|
|
4
5
|
// dont render on mobile
|
|
5
6
|
if (props.store.isMobile()) return null
|
|
7
|
+
if (props.store.isAIDevMode()) return null
|
|
6
8
|
let user = props.store.matchUser() || {}
|
|
7
9
|
var link = `https://subiz.com.vn/?utm_source=${
|
|
8
10
|
window.location.host || `id-${user.account_id}`
|
package/src/chatbox/Widget.js
CHANGED
|
@@ -130,11 +130,13 @@ export default class Widget extends Com {
|
|
|
130
130
|
let position = sb.get(accountSetting, 'desktop_button.position') || 'right'
|
|
131
131
|
if (this.props.store.isMobile()) position = sb.get(accountSetting, 'mobile_button.position', position)
|
|
132
132
|
let cls = 'widget-container widget-container--' + position
|
|
133
|
-
if (!this.props.store.isMobile() && sb.get(accountSetting, 'window_mode') === 'full')
|
|
133
|
+
if ( !this.props.store.isMobile() && sb.get(accountSetting, 'window_mode') === 'full')
|
|
134
134
|
cls += ' widget-container--full'
|
|
135
135
|
if (!this.props.isShow) cls += ' widget-container--hide'
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
let hideheader = sb.get(accountSetting, 'header.hidden', false)
|
|
137
|
+
var $header
|
|
138
|
+
if (!hideheader) {
|
|
139
|
+
$header = (
|
|
138
140
|
<Header
|
|
139
141
|
t={this.props.t}
|
|
140
142
|
plugin={this.props.plugin}
|
|
@@ -144,6 +146,11 @@ export default class Widget extends Com {
|
|
|
144
146
|
onClose={this.props.onClose}
|
|
145
147
|
onGotoList={() => this.props.onGo({view: 'list'})}
|
|
146
148
|
/>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
return (
|
|
152
|
+
<div class={cls}>
|
|
153
|
+
{$header}
|
|
147
154
|
{$body}
|
|
148
155
|
</div>
|
|
149
156
|
)
|
package/src/lib.js
CHANGED
package/src/store/store.js
CHANGED
|
@@ -210,6 +210,18 @@ export default class Store {
|
|
|
210
210
|
this.pubsub.publish('highlight', pluginid, ref)
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
emitConvoEvent(ev) {
|
|
214
|
+
this.pubsub.publish('events', ev)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
setAIDevMode(mode) {
|
|
218
|
+
this.ai_dev_mode = mode
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
isAIDevMode() {
|
|
222
|
+
return this.ai_dev_mode
|
|
223
|
+
}
|
|
224
|
+
|
|
213
225
|
overrideDeviceType(type) {
|
|
214
226
|
this.forceDevice = type
|
|
215
227
|
this.pubsub.publish('account')
|
|
@@ -858,7 +870,17 @@ export default class Store {
|
|
|
858
870
|
|
|
859
871
|
if (!sb.get(oldev, 'data.message')) return
|
|
860
872
|
var pongs = sb.get(oldev, 'data.message.pongs', [])
|
|
861
|
-
|
|
873
|
+
let newpongs = sb.get(ev, 'data.message.pongs', []) || []
|
|
874
|
+
pongs = pongs.concat(newpongs)
|
|
875
|
+
if (newpongs.length === 1) {
|
|
876
|
+
let pongtype = newpongs[0].type
|
|
877
|
+
if (pongtype === 'like' || pongtype === 'remove_dislike') {
|
|
878
|
+
pongs = pongs.filter((pong) => pong.type !== 'dislike')
|
|
879
|
+
}
|
|
880
|
+
if (pongtype === 'dislike' || pongtype === 'remove_like') {
|
|
881
|
+
pongs = pongs.filter((pong) => pong.type !== 'like')
|
|
882
|
+
}
|
|
883
|
+
}
|
|
862
884
|
oldev.data.message.pongs = pongs
|
|
863
885
|
sb.map(pongs, (pong) => {
|
|
864
886
|
if (pong.member_id == user.id && pong.type === 'seen') {
|
|
@@ -867,6 +889,7 @@ export default class Store {
|
|
|
867
889
|
}
|
|
868
890
|
})
|
|
869
891
|
this.chain.put(cid, oldev.id, sb.getMs(oldev.created), oldev)
|
|
892
|
+
this.pubsub.publish('events', oldev)
|
|
870
893
|
}
|
|
871
894
|
|
|
872
895
|
if (ev.type === 'message_sent') {
|
|
@@ -901,6 +924,7 @@ export default class Store {
|
|
|
901
924
|
_typing = sb.throttle((convoid) => this.api.sendTyping(convoid), 3000, {trailing: false})
|
|
902
925
|
|
|
903
926
|
async startConvo(req) {
|
|
927
|
+
if (!req) req = {}
|
|
904
928
|
await this.readyGate.entry()
|
|
905
929
|
this.convoGate.close()
|
|
906
930
|
|
|
@@ -925,6 +949,10 @@ export default class Store {
|
|
|
925
949
|
return this.api.createPostback(cid, postback)
|
|
926
950
|
}
|
|
927
951
|
|
|
952
|
+
sendReaction(cid, ev) {
|
|
953
|
+
return this.api.sendConvoEvent(cid, ev)
|
|
954
|
+
}
|
|
955
|
+
|
|
928
956
|
async sendConvoEvent(cid, type, data) {
|
|
929
957
|
await this.readyGate.entry()
|
|
930
958
|
var idempotency = sb.randomString(36)
|