@subiz/widget-v4 4.1.117 → 4.1.119
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/base.less +1 -0
- package/assets/less/chatbox.less +2 -0
- package/assets/less/message.less +42 -22
- package/assets/less/message_input.less +2 -0
- package/assets/less/order.less +1 -1
- package/assets/less/widget.less +33 -16
- package/assets/less/widget_header.less +35 -36
- package/compiled_src/chatbox/AgentsAvatar.js +1 -1
- package/compiled_src/chatbox/Event.js +70 -15
- package/compiled_src/chatbox/Events.js +108 -19
- package/compiled_src/chatbox/Header.js +5 -4
- package/compiled_src/chatbox/InfoMessage.js +2 -13
- package/compiled_src/chatbox/MessageInput.js +19 -9
- package/compiled_src/chatbox/TextMessage.js +11 -2
- package/compiled_src/chatbox/Widget.js +22 -21
- package/compiled_src/chatbox/time.js +1 -0
- package/compiled_src/util/common.js +89 -0
- package/dist/185.js +19 -19
- package/dist/19641cfa41e.278.js +1 -0
- package/dist/19641cfa41e.app.js +1 -0
- package/dist/{195ec5442e3.index.html → 19641cfa41e.index.html} +1 -1
- package/dist/{195ec5442e3.library.html → 19641cfa41e.library.html} +1 -1
- package/dist/19641cfa41e.library.js +1 -0
- package/dist/{195ec5442e3.preview.html → 19641cfa41e.preview.html} +1 -1
- package/dist/19641cfa41e.preview.js +1 -0
- package/dist/19641cfa41e.webview.js +1 -0
- package/dist/278.js +1 -1
- package/dist/HASH +1 -1
- package/dist/screenshoot.js +562 -185
- package/package.json +2 -2
- package/src/chatbox/AgentsAvatar.js +1 -1
- package/src/chatbox/Event.js +76 -15
- package/src/chatbox/Events.js +95 -14
- package/src/chatbox/Header.js +3 -2
- package/src/chatbox/InfoMessage.js +0 -14
- package/src/chatbox/MessageInput.js +18 -7
- package/src/chatbox/TextMessage.js +13 -0
- package/src/chatbox/Widget.js +13 -16
- package/src/chatbox/time.js +12 -8
- package/src/util/common.js +121 -0
- package/up +33 -21
- package/compiled_src/chatbox/Typing.js +0 -77
- package/dist/195ec5442e3.278.js +0 -1
- package/dist/195ec5442e3.app.js +0 -1
- package/dist/195ec5442e3.library.js +0 -1
- package/dist/195ec5442e3.preview.js +0 -1
- package/dist/195ec5442e3.webview.js +0 -1
- package/src/chatbox/Typing.js +0 -72
- /package/dist/{195ec5442e3.127.js → 19641cfa41e.127.js} +0 -0
- /package/dist/{195ec5442e3.132.js → 19641cfa41e.132.js} +0 -0
- /package/dist/{195ec5442e3.185.js → 19641cfa41e.185.js} +0 -0
- /package/dist/{195ec5442e3.27.js → 19641cfa41e.27.js} +0 -0
- /package/dist/{195ec5442e3.459.js → 19641cfa41e.459.js} +0 -0
- /package/dist/{195ec5442e3.490.js → 19641cfa41e.490.js} +0 -0
- /package/dist/{195ec5442e3.74.js → 19641cfa41e.74.js} +0 -0
- /package/dist/{195ec5442e3.997.js → 19641cfa41e.997.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subiz/widget-v4",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.119",
|
|
4
4
|
"main": "./compiled_src/lib.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "npx webpack serve --config webpack.dev.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"core-js": "^3.41.0",
|
|
18
18
|
"css-loader": "5.2.7",
|
|
19
19
|
"file-loader": "^6.2.0",
|
|
20
|
-
"less": "^4.
|
|
20
|
+
"less": "^4.3.0",
|
|
21
21
|
"less-loader": "^12.2.0",
|
|
22
22
|
"preact": "10.19.3"
|
|
23
23
|
},
|
|
@@ -38,7 +38,7 @@ export default function AgentsAvatar(props) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
agents = sb.filter(agents, (ag) => !!ag)
|
|
41
|
-
if (agents.length === 0) {
|
|
41
|
+
if (agents.length === 0 || props.agent_ids === undefined || sb.size(props.agent_ids) === 0) {
|
|
42
42
|
// use account avatar
|
|
43
43
|
return (
|
|
44
44
|
<div class={`group-avatar group-avatar--${mode}`}>
|
package/src/chatbox/Event.js
CHANGED
|
@@ -33,10 +33,13 @@ export default class Event extends Com {
|
|
|
33
33
|
render() {
|
|
34
34
|
var ev = sb.get(this.props.event, 'ev', {})
|
|
35
35
|
switch (ev.type) {
|
|
36
|
+
case 'conversation_typing':
|
|
37
|
+
return this.renderTyping()
|
|
36
38
|
case 'conversation_joined':
|
|
37
39
|
// return this.renderMessageChatJoin()
|
|
38
40
|
break
|
|
39
41
|
case 'message_sent':
|
|
42
|
+
if (this.props.event.is_typing) return this.renderTyping()
|
|
40
43
|
return this.renderMessageSent()
|
|
41
44
|
case 'conversation_state_updated':
|
|
42
45
|
case 'conversation_rating_requested':
|
|
@@ -149,19 +152,74 @@ export default class Event extends Com {
|
|
|
149
152
|
})
|
|
150
153
|
}
|
|
151
154
|
|
|
155
|
+
renderTyping() {
|
|
156
|
+
let innercls = 'agent-convo-event-inner'
|
|
157
|
+
var html = `
|
|
158
|
+
<html>
|
|
159
|
+
<head>
|
|
160
|
+
<style>
|
|
161
|
+
.typing-container {
|
|
162
|
+
width: 100vw;
|
|
163
|
+
height: 100vh;
|
|
164
|
+
display: flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
gap: 4px;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
}
|
|
169
|
+
.typing-dot {
|
|
170
|
+
display: inline-block;
|
|
171
|
+
vertical-align: middle;
|
|
172
|
+
width: 8px;
|
|
173
|
+
height: 8px;
|
|
174
|
+
background: black;
|
|
175
|
+
border-radius: 50%;
|
|
176
|
+
animation: typing 0.5s infinite alternate;
|
|
177
|
+
}
|
|
178
|
+
.typing-dot:nth-of-type(2) {
|
|
179
|
+
animation-delay: 0.2s;
|
|
180
|
+
}
|
|
181
|
+
.typing-dot:nth-of-type(3) {
|
|
182
|
+
animation-delay: 0.6s;
|
|
183
|
+
}
|
|
184
|
+
@keyframes typing {
|
|
185
|
+
0% {
|
|
186
|
+
opacity: 0.9;
|
|
187
|
+
}
|
|
188
|
+
100% {
|
|
189
|
+
opacity: 0.4;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
</style>
|
|
193
|
+
</head>
|
|
194
|
+
<body style="padding: 0; margin: 0">
|
|
195
|
+
<div class="typing-container">
|
|
196
|
+
<span class="typing-dot"></span>
|
|
197
|
+
<span class="typing-dot"></span>
|
|
198
|
+
<span class="typing-dot"></span>
|
|
199
|
+
</div>
|
|
200
|
+
</body>
|
|
201
|
+
</html>
|
|
202
|
+
`
|
|
203
|
+
let src = 'data:text/html,' + encodeURIComponent(html)
|
|
204
|
+
return (
|
|
205
|
+
<div class='convo-event agent-message'>
|
|
206
|
+
<div class='agent-convo-event-wrapper'>
|
|
207
|
+
<div class={innercls}>
|
|
208
|
+
<div class='message-agent message-text--agent' style='opacity: 0.6 !important'>
|
|
209
|
+
<iframe
|
|
210
|
+
src={src}
|
|
211
|
+
style='width: 35px !important; height: 20px !important; display: block !important; overflow: hidden !important; padding: 0 !important '
|
|
212
|
+
></iframe>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
|
|
152
220
|
renderMessageSent() {
|
|
153
221
|
let ev = this.props.event.ev
|
|
154
222
|
this.tryLoadOrder(ev)
|
|
155
|
-
var $time = null
|
|
156
|
-
if (this.props.event.show_time) {
|
|
157
|
-
$time = (
|
|
158
|
-
<div class='convo-event-time'>
|
|
159
|
-
<Time time={ev.created} t={this.props.t} />
|
|
160
|
-
</div>
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
if (this.props.store.isAIDevMode()) $time = null
|
|
164
|
-
|
|
165
223
|
let t = new sb.Date(ev.created).toLocaleString()
|
|
166
224
|
// message of agent
|
|
167
225
|
if (sb.get(ev, 'by.type') !== 'user') {
|
|
@@ -171,11 +229,16 @@ export default class Event extends Com {
|
|
|
171
229
|
if (this.props.isLast) innercls += ' last'
|
|
172
230
|
return (
|
|
173
231
|
<div class='convo-event agent-message'>
|
|
174
|
-
{$time}
|
|
175
232
|
{$sender}
|
|
176
233
|
<div class='agent-convo-event-wrapper'>
|
|
177
234
|
<div class={innercls}>
|
|
178
|
-
<TextMessage
|
|
235
|
+
<TextMessage
|
|
236
|
+
showTime={this.props.event.show_time}
|
|
237
|
+
isLast={this.props.isLast}
|
|
238
|
+
store={this.props.store}
|
|
239
|
+
ev={ev}
|
|
240
|
+
onLink={this.props.onLink}
|
|
241
|
+
/>
|
|
179
242
|
<ImageAttachments store={this.props.store} ev={ev} />
|
|
180
243
|
<AudioAttachments store={this.props.store} ev={ev} />
|
|
181
244
|
<VideoAttachments store={this.props.store} ev={ev} />
|
|
@@ -223,7 +286,7 @@ export default class Event extends Com {
|
|
|
223
286
|
}
|
|
224
287
|
|
|
225
288
|
let $sender = null
|
|
226
|
-
if (this.props.event.mode === 'lead') $sender = <div class='pt-3'></div>
|
|
289
|
+
// if (this.props.event.mode === 'lead') $sender = <div class='pt-3'></div>
|
|
227
290
|
|
|
228
291
|
let $error = null
|
|
229
292
|
if (ev._error && ev.type === 'message_sent') {
|
|
@@ -239,7 +302,6 @@ export default class Event extends Com {
|
|
|
239
302
|
|
|
240
303
|
return (
|
|
241
304
|
<div class='convo-event user-message'>
|
|
242
|
-
{$time}
|
|
243
305
|
{$sender}
|
|
244
306
|
<div class='message-user__container'>
|
|
245
307
|
{$dot}
|
|
@@ -307,7 +369,6 @@ export default class Event extends Com {
|
|
|
307
369
|
|
|
308
370
|
renderReactions() {
|
|
309
371
|
if (this.props.store.isAIDevMode()) return null
|
|
310
|
-
|
|
311
372
|
let ev = sb.get(this.props.event, 'ev') || {}
|
|
312
373
|
let pongs = sb.get(ev, 'data.message.pongs') || []
|
|
313
374
|
let hasLike = this.hasLike()
|
package/src/chatbox/Events.js
CHANGED
|
@@ -29,10 +29,66 @@ export default class Events extends Com {
|
|
|
29
29
|
this.checkAndSeen()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
componentDidMount() {
|
|
33
|
+
this.setState({
|
|
34
|
+
isShowTyping: false,
|
|
35
|
+
typing_event: {},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
this.props.store.onConvoEvent(this, (ev) => {
|
|
39
|
+
if (sb.convoOfEv(ev) !== this.props.cid) return
|
|
40
|
+
// if (sb.get(ev, 'by.id') === user.id) return
|
|
41
|
+
// fixwidget in dashboard show typing of user
|
|
42
|
+
if (sb.get(ev, 'by.type') === 'user') return
|
|
43
|
+
|
|
44
|
+
let oldby = sb.get(this.state.typing_event, 'by.id')
|
|
45
|
+
if (oldby && sb.get(ev, 'by.id') !== oldby) return
|
|
46
|
+
|
|
47
|
+
if (sb.get(ev, 'type') === 'message_sent') {
|
|
48
|
+
// stop the typing
|
|
49
|
+
if (this.timer) sb.clearTimeout(this.timer)
|
|
50
|
+
this.timer = null
|
|
51
|
+
this.setState({isShowTyping: false})
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
if (sb.get(ev, 'type') !== 'conversation_typing') return
|
|
55
|
+
|
|
56
|
+
// dont show typing of agent, some agent dont like this
|
|
57
|
+
let ag = this.props.store.matchAgent(sb.get(ev, 'by.id')) || {}
|
|
58
|
+
if (ag.type == 'agent' && !sb.get(this.props.plugin, 'chatbox.show_agent_typing')) return
|
|
59
|
+
this.setState({typing_event: ev, isShowTyping: true})
|
|
60
|
+
if (this.timer) sb.clearTimeout(this.timer)
|
|
61
|
+
this.timer = sb.setTimeout(() => {
|
|
62
|
+
if (sb.convoOfEv(ev) !== this.props.cid) return
|
|
63
|
+
this.timer = null
|
|
64
|
+
this.setState({isShowTyping: false})
|
|
65
|
+
}, 5000)
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
32
69
|
componentDidUpdate(prevProps) {
|
|
33
70
|
if (prevProps.cid !== this.props.cid) this.loadConvo()
|
|
34
71
|
}
|
|
35
72
|
|
|
73
|
+
ShowTyping() {
|
|
74
|
+
this.setState({
|
|
75
|
+
isShowTyping: true,
|
|
76
|
+
typing_event: {
|
|
77
|
+
id: 'evzz' + sb.Date.now(),
|
|
78
|
+
created: sb.Date.now(),
|
|
79
|
+
by: {
|
|
80
|
+
type: 'agent',
|
|
81
|
+
},
|
|
82
|
+
type: 'conversation_typing',
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
if (this.timer) sb.clearTimeout(this.timer)
|
|
86
|
+
this.timer = sb.setTimeout(() => {
|
|
87
|
+
this.timer = null
|
|
88
|
+
this.setState({isShowTyping: false})
|
|
89
|
+
}, 5000)
|
|
90
|
+
}
|
|
91
|
+
|
|
36
92
|
render() {
|
|
37
93
|
if (this.state.error) return this.renderError()
|
|
38
94
|
let events = sb.map(this.props.store.listEvents(this.props.cid))
|
|
@@ -53,20 +109,29 @@ export default class Events extends Com {
|
|
|
53
109
|
|
|
54
110
|
let convo = this.props.store.matchConvo(this.props.cid)
|
|
55
111
|
events = sb.map(events, (ev) => ({ev: ev}))
|
|
56
|
-
processEvents(convo, events)
|
|
57
112
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
let ev = sb.
|
|
61
|
-
let
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
113
|
+
// console.log('-----------', this.state.isShowTyping, this.state.typing_event)
|
|
114
|
+
if (this.state.isShowTyping) {
|
|
115
|
+
let ev = this.state.typing_event || {id: 'evzz' + sb.Date.now(), created: sb.Date.now(), by: {type: 'agent'}}
|
|
116
|
+
let fakeev = {
|
|
117
|
+
is_typing: true,
|
|
118
|
+
id: ev.id,
|
|
119
|
+
ev: {
|
|
120
|
+
id: ev.id,
|
|
121
|
+
created: ev.created,
|
|
122
|
+
by: ev.by,
|
|
123
|
+
type: 'message_sent',
|
|
124
|
+
data: {message: {text: '...', conversation_id: this.props.cid}},
|
|
125
|
+
},
|
|
65
126
|
}
|
|
127
|
+
console.log('FA', fakeev)
|
|
128
|
+
events.push(fakeev)
|
|
66
129
|
}
|
|
67
130
|
|
|
131
|
+
processEvents(convo, events)
|
|
132
|
+
|
|
68
133
|
let $events = sb.map(events, (ev) => {
|
|
69
|
-
let isLast = ev.ev.id ===
|
|
134
|
+
let isLast = ev.ev.id === sb.get(convo, 'last_message_sent.id')
|
|
70
135
|
return (
|
|
71
136
|
<Event
|
|
72
137
|
isLast={isLast}
|
|
@@ -85,11 +150,18 @@ export default class Events extends Com {
|
|
|
85
150
|
|
|
86
151
|
let $loading = null
|
|
87
152
|
let style = 'opacity: 1 !important'
|
|
88
|
-
if (this.
|
|
153
|
+
if (this.props.creating) {
|
|
89
154
|
$loading = <Spinner static mode={sb.get(this.props.chatbox, 'primary_color', 'dark')} size='120' center />
|
|
90
155
|
style = 'opacity: 0 !important'
|
|
91
156
|
}
|
|
92
157
|
|
|
158
|
+
if (this.state.loading) {
|
|
159
|
+
if (sb.Date.now() - this.state.loading > 500) {
|
|
160
|
+
$loading = <Spinner static mode={sb.get(this.props.chatbox, 'primary_color', 'dark')} size='120' center />
|
|
161
|
+
style = 'opacity: 0 !important'
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
93
165
|
return (
|
|
94
166
|
<Fragment>
|
|
95
167
|
{$loading}
|
|
@@ -171,9 +243,13 @@ export default class Events extends Com {
|
|
|
171
243
|
if (!this.props.cid) return
|
|
172
244
|
// load msg
|
|
173
245
|
this.lastContentOffsetY = 0
|
|
174
|
-
this.setState({loading:
|
|
246
|
+
this.setState({loading: false})
|
|
175
247
|
let events = this.props.store.listEvents(this.props.cid)
|
|
176
248
|
if (sb.size(events) === 0) {
|
|
249
|
+
this.setState({loading: sb.Date.now()})
|
|
250
|
+
sb.setTimeout(() => {
|
|
251
|
+
this.forceUpdate()
|
|
252
|
+
}, 800)
|
|
177
253
|
let cid = this.props.cid
|
|
178
254
|
|
|
179
255
|
let {error} = await this.props.store.fetchMoreEvents(cid)
|
|
@@ -184,11 +260,10 @@ export default class Events extends Com {
|
|
|
184
260
|
return
|
|
185
261
|
}
|
|
186
262
|
}
|
|
187
|
-
this.setState({loading: true})
|
|
188
263
|
this.props.store.fetchMoreEvents(this.props.cid)
|
|
189
264
|
this.setState({error: false})
|
|
190
265
|
this.scrollToBottom()
|
|
191
|
-
sb.setTimeout(() => this.setState({loading: false}), 50)
|
|
266
|
+
// sb.setTimeout(() => this.setState({loading: false}), 50)
|
|
192
267
|
}
|
|
193
268
|
|
|
194
269
|
isBottom() {
|
|
@@ -205,7 +280,7 @@ export default class Events extends Com {
|
|
|
205
280
|
sb.setTimeout(() => {
|
|
206
281
|
const $div = this.refBody
|
|
207
282
|
if ($div) $div.scrollTop = $div.scrollHeight
|
|
208
|
-
},
|
|
283
|
+
}, 100)
|
|
209
284
|
|
|
210
285
|
if (this.props.isShow) {
|
|
211
286
|
if (this.props.store.browserVisibility === 'visible' && document.hasFocus()) {
|
|
@@ -224,9 +299,13 @@ function processEvents(convo, events) {
|
|
|
224
299
|
|
|
225
300
|
// show time for the first msg sent
|
|
226
301
|
// insert time
|
|
302
|
+
var lastAgentEvent
|
|
227
303
|
for (var i = 1; i < events.length; i++) {
|
|
228
304
|
let curEvent = events[i]
|
|
229
305
|
let lastEvent = events[i - 1]
|
|
306
|
+
if (sb.get(curEvent, 'ev.by.type') != 'user' && !curEvent.is_typing) {
|
|
307
|
+
lastAgentEvent = curEvent
|
|
308
|
+
}
|
|
230
309
|
|
|
231
310
|
if (visibleEvent(curEvent.ev)) {
|
|
232
311
|
let elapsedSec = sb.unixSec(curEvent.ev.created) - sb.unixSec(lastEvent.ev.created)
|
|
@@ -234,6 +313,8 @@ function processEvents(convo, events) {
|
|
|
234
313
|
}
|
|
235
314
|
}
|
|
236
315
|
|
|
316
|
+
if (lastAgentEvent) lastAgentEvent.show_time = true
|
|
317
|
+
|
|
237
318
|
for (var i = 0; i < events.length; i++) {
|
|
238
319
|
let curEvent = events[i]
|
|
239
320
|
if (sb.get(curEvent, 'ev.type') === 'message_sent') {
|
package/src/chatbox/Header.js
CHANGED
|
@@ -54,7 +54,8 @@ export default class Header extends Com {
|
|
|
54
54
|
return (
|
|
55
55
|
<div class={cls} style={style}>
|
|
56
56
|
{$back}
|
|
57
|
-
<
|
|
57
|
+
<div class="mr-2"></div>
|
|
58
|
+
<AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='secondary' />
|
|
58
59
|
<div class='widget-header--title-container'>
|
|
59
60
|
<div class='widget-header--title'>{this.getTitle()}</div>
|
|
60
61
|
<div class='widget-header--description' title={desc}>
|
|
@@ -201,7 +202,7 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
|
|
|
201
202
|
if (accSetting.hide_close_button) return null
|
|
202
203
|
return (
|
|
203
204
|
<div
|
|
204
|
-
class='widget-header--button
|
|
205
|
+
class='widget-header--button-close'
|
|
205
206
|
data-tooltip={this.props.t('close')}
|
|
206
207
|
data-tooltip-position='bottom'
|
|
207
208
|
onClick={(e) => this.onCloseClick(e)}
|
|
@@ -7,24 +7,12 @@ function getRateLang(rating) {
|
|
|
7
7
|
return 'great'
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
import Time from './time.js'
|
|
11
10
|
import {Com} from '../common.js'
|
|
12
11
|
import {h} from 'preact'
|
|
13
12
|
// [ 'ev'],
|
|
14
13
|
export default class InfoMessage extends Com {
|
|
15
14
|
render() {
|
|
16
15
|
let ev = this.props.ev.ev
|
|
17
|
-
var $time = null
|
|
18
|
-
|
|
19
|
-
if (this.props.ev.show_time) {
|
|
20
|
-
$time = (
|
|
21
|
-
<div class='convo-event-time'>
|
|
22
|
-
<Time time={ev.created} t={this.props.t} />
|
|
23
|
-
</div>
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (this.props.store.isAIDevMode()) $time = null
|
|
28
16
|
|
|
29
17
|
// if (this.ev.type === 'conversation_rating_requested') return <div class="info-message"></div>
|
|
30
18
|
if (ev.type === 'conversation_rated') {
|
|
@@ -32,7 +20,6 @@ export default class InfoMessage extends Com {
|
|
|
32
20
|
if (rating.no_rating) return null
|
|
33
21
|
return (
|
|
34
22
|
<div class='convo-event'>
|
|
35
|
-
{$time}
|
|
36
23
|
<div class='info-message'>
|
|
37
24
|
{this.props.t('rated_as') + ' ' + this.props.t(getRateLang(rating.rating)).toLowerCase()}
|
|
38
25
|
</div>
|
|
@@ -42,7 +29,6 @@ export default class InfoMessage extends Com {
|
|
|
42
29
|
if (ev.type === 'conversation_state_updated' && sb.get(ev, 'data.conversation.state') === 'ended') {
|
|
43
30
|
return (
|
|
44
31
|
<div class='convo-event'>
|
|
45
|
-
{$time}
|
|
46
32
|
<div class='info-message'>{this.props.t('conversation_ended')}</div>
|
|
47
33
|
</div>
|
|
48
34
|
)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import sb from '../util/index.js'
|
|
2
2
|
import {Com} from '../common.js'
|
|
3
3
|
import {h, createRef} from 'preact'
|
|
4
|
+
import Spinner from './spinner.js'
|
|
4
5
|
import Emoji from './Emoji.js'
|
|
5
|
-
// props: ['disabled', 'cid'],
|
|
6
|
+
// props: ['disabled', 'cid', 'is_loading'],
|
|
6
7
|
export default class MessageInput extends Com {
|
|
7
8
|
constructor(props) {
|
|
8
9
|
super(props)
|
|
@@ -37,7 +38,7 @@ export default class MessageInput extends Com {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
render() {
|
|
40
|
-
var buttons = (
|
|
41
|
+
var $buttons = (
|
|
41
42
|
<div class='d-flex flex-row align-self-end'>
|
|
42
43
|
{this.renderEmoji()}
|
|
43
44
|
<div
|
|
@@ -49,7 +50,7 @@ export default class MessageInput extends Com {
|
|
|
49
50
|
)
|
|
50
51
|
var msg = sb.trim(this.state.msgValue)
|
|
51
52
|
if (msg.length > 0) {
|
|
52
|
-
buttons = (
|
|
53
|
+
$buttons = (
|
|
53
54
|
<div class='d-flex flex-row align-self-end'>
|
|
54
55
|
{this.renderEmoji()}
|
|
55
56
|
<div
|
|
@@ -61,9 +62,17 @@ export default class MessageInput extends Com {
|
|
|
61
62
|
)
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
if (this.props.is_loading) {
|
|
66
|
+
$buttons = (
|
|
67
|
+
<div class='d-flex flex-row align-self-end'>
|
|
68
|
+
<Spinner size='32' />
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
64
73
|
var containercls = ''
|
|
65
74
|
var disabled = this.hasUnfinishRequiredFormOrLock() || this.props.disabled
|
|
66
|
-
if (disabled) containercls = 'message-input--disabled'
|
|
75
|
+
if (disabled || this.props.is_loading) containercls = 'message-input--disabled'
|
|
67
76
|
|
|
68
77
|
return (
|
|
69
78
|
<div
|
|
@@ -77,7 +86,7 @@ export default class MessageInput extends Com {
|
|
|
77
86
|
disabled={disabled}
|
|
78
87
|
class='message-input--input'
|
|
79
88
|
maxlength='1024'
|
|
80
|
-
placeholder={this.props.t('message_input_help')}
|
|
89
|
+
placeholder={this.props.t('message_input_help').substr(0, 25)}
|
|
81
90
|
ref={this.refMessageInput}
|
|
82
91
|
rows='1'
|
|
83
92
|
value={this.state.msgValue}
|
|
@@ -86,7 +95,7 @@ export default class MessageInput extends Com {
|
|
|
86
95
|
data-emojiable='true'
|
|
87
96
|
onKeydown={(e) => this.onKeydown(e)}
|
|
88
97
|
/>
|
|
89
|
-
{buttons}
|
|
98
|
+
{$buttons}
|
|
90
99
|
</div>
|
|
91
100
|
)
|
|
92
101
|
}
|
|
@@ -324,9 +333,11 @@ export default class MessageInput extends Com {
|
|
|
324
333
|
msg = msg || sb.trim(this.state.msgValue) || ''
|
|
325
334
|
if (!msg) return
|
|
326
335
|
if (this.props.disabled) return
|
|
336
|
+
if (this.props.onSend) {
|
|
337
|
+
await this.props.onSend({text: msg, format: 'plaintext'})
|
|
338
|
+
}
|
|
327
339
|
this.setState({openEmoji: false, msgValue: ''})
|
|
328
340
|
this.resizeInput()
|
|
329
|
-
this.props.onSend && this.props.onSend({text: msg, format: 'plaintext'})
|
|
330
341
|
}
|
|
331
342
|
|
|
332
343
|
sendTyping() {
|
|
@@ -3,8 +3,19 @@ import Block from './block.js'
|
|
|
3
3
|
import {Com} from '../common.js'
|
|
4
4
|
import {h} from 'preact'
|
|
5
5
|
import Emoji from './Emoji.js'
|
|
6
|
+
import Time from './time.js'
|
|
6
7
|
|
|
7
8
|
export default class TextMessage extends Com {
|
|
9
|
+
renderTime() {
|
|
10
|
+
if (!this.props.showTime && !this.props.isLast && !this.props.isFirst) return null
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div>
|
|
14
|
+
<Time class='inline-time' time={sb.get(this.props.ev, 'created', sb.Date.now())} t={this.props.t} />
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
render() {
|
|
9
20
|
var format = sb.get(this.props.ev, 'data.message.format', 'plaintext')
|
|
10
21
|
let block = sb.get(this.props.ev, 'data.message.block')
|
|
@@ -48,6 +59,7 @@ export default class TextMessage extends Com {
|
|
|
48
59
|
return (
|
|
49
60
|
<div class='message-agent message-text--agent' title={t}>
|
|
50
61
|
{tags}
|
|
62
|
+
{this.renderTime()}
|
|
51
63
|
</div>
|
|
52
64
|
)
|
|
53
65
|
return (
|
|
@@ -66,6 +78,7 @@ export default class TextMessage extends Com {
|
|
|
66
78
|
return (
|
|
67
79
|
<div class='message-agent message-text--agent' title={t}>
|
|
68
80
|
<Block block={block} onLink={this.props.onLink} />
|
|
81
|
+
{this.renderTime()}
|
|
69
82
|
</div>
|
|
70
83
|
)
|
|
71
84
|
}
|
package/src/chatbox/Widget.js
CHANGED
|
@@ -8,7 +8,7 @@ var checkedimg = require('../../assets/img/done_gray.svg')
|
|
|
8
8
|
var empty = require('../../assets/img/empty.svg')
|
|
9
9
|
import MessageInput from './MessageInput.js'
|
|
10
10
|
import Events from './Events.js'
|
|
11
|
-
import Typing from './Typing.js'
|
|
11
|
+
// import Typing from './Typing.js'
|
|
12
12
|
import Rating from './Rating.js'
|
|
13
13
|
// import Order from './Order.js'
|
|
14
14
|
let Order = false
|
|
@@ -17,7 +17,6 @@ import ListField from './ListField.js'
|
|
|
17
17
|
|
|
18
18
|
const defaultAvatar = 'https://vcdn.subiz-cdn.com/file/fiqoahedjbgwclpouoml-avatar_default_baa8a1d7.png'
|
|
19
19
|
|
|
20
|
-
import Spinner from './spinner.js'
|
|
21
20
|
import Time from './time.js'
|
|
22
21
|
import {Com} from '../common.js'
|
|
23
22
|
import {h, createRef} from 'preact'
|
|
@@ -68,7 +67,7 @@ export default class Widget extends Com {
|
|
|
68
67
|
// focus Events then focus MessageInput
|
|
69
68
|
// if there is any pending form, MessageInput will be disabled
|
|
70
69
|
// and dont steal focus from Events
|
|
71
|
-
this
|
|
70
|
+
this.$events && this.$events.focus()
|
|
72
71
|
if (!this.props.store.isMobile()) this.focusInput()
|
|
73
72
|
}, 100)
|
|
74
73
|
this.updateFormDataFields()
|
|
@@ -77,7 +76,7 @@ export default class Widget extends Com {
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
ShowTyping() {
|
|
80
|
-
this
|
|
79
|
+
this.$events && this.$events.ShowTyping()
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
shouldShowForm() {
|
|
@@ -776,17 +775,21 @@ export default class Widget extends Com {
|
|
|
776
775
|
})
|
|
777
776
|
if (_creating != this._creating) return // outdated
|
|
778
777
|
if (error) {
|
|
778
|
+
this.setState({creating: false})
|
|
779
|
+
return
|
|
779
780
|
// show error and try again
|
|
780
781
|
}
|
|
781
782
|
await this.props.store.sendConvoEvent(convo.id, 'message_sent', {message})
|
|
782
783
|
if (_creating != this._creating) return // outdated
|
|
783
|
-
this.setState({creating: false})
|
|
784
|
-
|
|
785
784
|
this.props.onGo({view: 'chat', cid: convo.id})
|
|
785
|
+
this.setState({creating: false})
|
|
786
786
|
return
|
|
787
787
|
}
|
|
788
|
-
|
|
789
|
-
|
|
788
|
+
// dont let text-input wait, since we want to clear out the message as soon as posible
|
|
789
|
+
sb.setTimeout(async () => {
|
|
790
|
+
await this.props.store.sendConvoEvent(this.props.cid, 'message_sent', {message})
|
|
791
|
+
this.setState({creating: false})
|
|
792
|
+
}, 1)
|
|
790
793
|
}
|
|
791
794
|
|
|
792
795
|
createPostback(postback) {
|
|
@@ -804,6 +807,7 @@ export default class Widget extends Com {
|
|
|
804
807
|
ref={this.msgInput}
|
|
805
808
|
cid={this.props.cid}
|
|
806
809
|
onChange={this.onChangeMessageInput}
|
|
810
|
+
is_loading={this.state.creating}
|
|
807
811
|
onSend={this.sendMessage}
|
|
808
812
|
t={this.props.t}
|
|
809
813
|
/>
|
|
@@ -818,7 +822,6 @@ export default class Widget extends Com {
|
|
|
818
822
|
</div>
|
|
819
823
|
)
|
|
820
824
|
}
|
|
821
|
-
|
|
822
825
|
return (
|
|
823
826
|
<div class='widget-body'>
|
|
824
827
|
<div class='widget-body--content' onClick={(e) => this.onContainerClick(e)}>
|
|
@@ -828,19 +831,13 @@ export default class Widget extends Com {
|
|
|
828
831
|
store={this.props.store}
|
|
829
832
|
chatbox={this.props.plugin.chatbox || {}}
|
|
830
833
|
onFormSubmit={(e) => this.onEventFormSubmit(e)}
|
|
831
|
-
ref={(ref) => (this
|
|
834
|
+
ref={(ref) => (this.$events = ref)}
|
|
832
835
|
cid={this.props.cid}
|
|
833
836
|
creating={this.creating}
|
|
834
837
|
onSend={(e) => this.sendMessage(e)}
|
|
835
838
|
onPostback={(e) => this.createPostback(e)}
|
|
836
839
|
t={this.props.t}
|
|
837
|
-
/>
|
|
838
|
-
<Typing
|
|
839
|
-
store={this.props.store}
|
|
840
|
-
cid={this.props.cid}
|
|
841
|
-
t={this.props.t}
|
|
842
840
|
plugin={this.props.plugin}
|
|
843
|
-
ref={this.refTyping}
|
|
844
841
|
/>
|
|
845
842
|
</div>
|
|
846
843
|
<Rating
|
package/src/chatbox/time.js
CHANGED
|
@@ -28,13 +28,13 @@ export default class Time extends Com {
|
|
|
28
28
|
if (this.props.short) {
|
|
29
29
|
// more than 10 days
|
|
30
30
|
//if (Math.abs(this.props.time - new sb.Date().getTime()) > 86400000 * 10) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
//let tim = new sb.Date(this.props.time)
|
|
32
|
+
//let tzyear = tim.getFullYear()
|
|
33
|
+
//let locale = sb.get(navigator, 'languages.0', 'en-US')
|
|
34
|
+
//if (forceLocale) locale = forceLocale
|
|
35
|
+
//let tzmonthname = tim.toLocaleDateString(locale, {month: 'short'})
|
|
36
|
+
//let tzdate = tim.getDate()
|
|
37
|
+
//t = tzdate + ' ' + tzmonthname + ' ' + tzyear
|
|
38
38
|
//}
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -61,7 +61,11 @@ export default class Time extends Com {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
let title = new Date(this.props.time).toLocaleString(locale)
|
|
64
|
-
return
|
|
64
|
+
return (
|
|
65
|
+
<span class={this.props.class} style={this.props.style} title={title}>
|
|
66
|
+
{this.state.t}
|
|
67
|
+
</span>
|
|
68
|
+
)
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
|