@subiz/widget-v4 4.0.61 → 4.0.66
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/img/caret.svg +1 -0
- package/assets/img/done_green.svg +4 -0
- package/assets/img/empty_1.svg +11 -0
- package/assets/img/ghn.svg +17 -0
- package/assets/img/ghtk.svg +18 -0
- package/assets/img/home.svg +1 -0
- package/assets/img/info.svg +1 -0
- package/assets/img/loader.svg +1 -0
- package/assets/img/map-pin.svg +1 -0
- package/assets/img/not_found_search.png +0 -0
- package/assets/img/package.svg +5 -0
- package/assets/img/package_fade.svg +1 -0
- package/assets/img/phone.svg +1 -0
- package/assets/img/search.svg +1 -0
- package/assets/img/shop.svg +1 -0
- package/assets/img/shop_faded.svg +1 -0
- package/assets/img/user.svg +1 -0
- package/assets/img/x.svg +5 -0
- package/assets/less/chatbox.less +39 -1
- package/assets/less/dropdown_select.less +130 -0
- package/assets/less/form.less +7 -20
- package/assets/less/order.less +489 -0
- package/assets/less/rating.less +3 -8
- package/babel.config.js +2 -4
- package/compiled_src/bot.js +7 -1
- package/compiled_src/chatbox/ChatButton.js +3 -1
- package/compiled_src/chatbox/DropdownSelect.js +248 -0
- package/compiled_src/chatbox/Event.js +5 -2
- package/compiled_src/chatbox/Events.js +1 -0
- package/compiled_src/chatbox/Order.js +285 -0
- package/compiled_src/chatbox/OrderAttachments.js +2 -1
- package/compiled_src/chatbox/ProductAttachments.js +40 -4
- package/compiled_src/chatbox/TextMessage.js +9 -2
- package/compiled_src/chatbox/Typing.js +3 -1
- package/compiled_src/chatbox/Widget.js +44 -3
- package/compiled_src/chatbox/main.js +2 -0
- package/compiled_src/chatbox/spinner.js +1 -1
- package/compiled_src/chatbox/time.js +3 -1
- package/compiled_src/common.js +40 -1
- package/compiled_src/contact/contact.js +1 -3
- package/compiled_src/order/address_picker.js +249 -0
- package/compiled_src/order/icon.js +62 -0
- package/compiled_src/order/index.js +113 -0
- package/compiled_src/order/order.js +1234 -0
- package/compiled_src/plugin.js +9 -42
- package/compiled_src/store/api.js +20 -0
- package/compiled_src/store/store.js +67 -3
- package/compiled_src/util/common.js +36 -2
- package/dist/{74.js → 132.js} +2355 -271
- package/dist/178.js +1 -1
- package/dist/17fdfed03d1.132.js +1 -0
- package/dist/17fdfed03d1.178.js +1 -0
- package/dist/17fdfed03d1.213.js +1 -0
- package/dist/17fdfed03d1.335.js +1 -0
- package/dist/17fdfed03d1.362.js +1 -0
- package/dist/17fdfed03d1.441.js +1 -0
- package/dist/17fdfed03d1.605.js +1 -0
- package/dist/{17db8166252.678.js → 17fdfed03d1.678.js} +0 -0
- package/dist/17fdfed03d1.782.js +1 -0
- package/dist/17fdfed03d1.app.js +1 -0
- package/dist/{17db8166252.index.html → 17fdfed03d1.index.html} +1 -1
- package/dist/{17db8166252.library.html → 17fdfed03d1.library.html} +1 -1
- package/dist/17fdfed03d1.library.js +1 -0
- package/dist/{17db8166252.preview.html → 17fdfed03d1.preview.html} +1 -1
- package/dist/17fdfed03d1.preview.js +1 -0
- package/dist/17fdfed03d1.screenshoot.js +1 -0
- package/dist/213.js +5 -69
- package/dist/335.js +411 -0
- package/dist/362.js +1 -1
- package/dist/441.js +70 -44
- package/dist/605.js +1 -64
- package/dist/782.js +1 -1
- package/dist/HASH +1 -1
- package/dist/assets/img/caret.998eb8f.svg +1 -0
- package/dist/assets/img/done_green.b817fd4.svg +4 -0
- package/dist/assets/img/empty_1.0b98af0.svg +11 -0
- package/dist/assets/img/ghn.070f8e3.svg +17 -0
- package/dist/assets/img/ghtk.326eac1.svg +18 -0
- package/dist/assets/img/info.ebce7ea.svg +1 -0
- package/dist/assets/img/loader.37000a7.svg +1 -0
- package/dist/assets/img/not_found_search.2ddb8d1.png +0 -0
- package/dist/assets/img/package.8d37d0f.svg +5 -0
- package/dist/assets/img/package_fade.763c001.svg +1 -0
- package/dist/assets/img/search.f9705ff.svg +1 -0
- package/dist/assets/img/shop.f7dc7d8.svg +1 -0
- package/dist/assets/img/shop_faded.df7845a.svg +1 -0
- package/dist/assets/img/x.26fdfa3.svg +5 -0
- package/dist/screenshoot.html +1 -1
- package/dist/screenshoot.js +281 -98
- package/order.html +19 -771
- package/package.json +15 -16
- package/src/bot.js +2 -1
- package/src/chatbox/Buttons.js +8 -8
- package/src/chatbox/ChatButton.js +2 -2
- package/src/chatbox/DropdownSelect.js +229 -0
- package/src/chatbox/Event.js +3 -3
- package/src/chatbox/Events.js +43 -42
- package/src/chatbox/Order.js +232 -0
- package/src/chatbox/OrderAttachments.js +2 -1
- package/src/chatbox/ProductAttachments.js +41 -5
- package/src/chatbox/TextMessage.js +21 -12
- package/src/chatbox/Typing.js +5 -1
- package/src/chatbox/Widget.js +34 -4
- package/src/chatbox/main.js +4 -1
- package/src/chatbox/spinner.js +1 -1
- package/src/chatbox/time.js +1 -1
- package/src/common.js +52 -8
- package/src/contact/contact.js +1 -1
- package/src/order/address_picker.js +235 -0
- package/src/order/icon.js +32 -0
- package/src/order/index.js +86 -0
- package/src/order/order.js +1157 -0
- package/src/order/scratch +211 -0
- package/src/plugin.js +7 -52
- package/src/store/api.js +26 -1
- package/src/store/store.js +53 -3
- package/src/util/common.js +48 -2
- package/up +1 -1
- package/webpack.dev.js +2 -0
- package/dist/17db8166252.178.js +0 -1
- package/dist/17db8166252.213.js +0 -1
- package/dist/17db8166252.362.js +0 -1
- package/dist/17db8166252.441.js +0 -1
- package/dist/17db8166252.605.js +0 -1
- package/dist/17db8166252.619.js +0 -1
- package/dist/17db8166252.74.js +0 -1
- package/dist/17db8166252.782.js +0 -1
- package/dist/17db8166252.app.js +0 -1
- package/dist/17db8166252.library.js +0 -1
- package/dist/17db8166252.preview.js +0 -1
- package/dist/17db8166252.screenshoot.js +0 -1
- package/dist/619.js +0 -777
- package/order.js +0 -0
- package/test.js +0 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import sb from '../util/index.js'
|
|
2
|
+
|
|
3
|
+
import ReleaseAnimation from './releaseAnimation.js'
|
|
4
|
+
import Time from './time.js'
|
|
5
|
+
const POPUP_MAX_HEIGHT = 400
|
|
6
|
+
const POPUP_HARD_MAX_HEIGHT = 500
|
|
7
|
+
const POPUP_MIN_HEIGHT = 0
|
|
8
|
+
let defaultAvatar = require('../../assets/img/default_avatar.png')
|
|
9
|
+
import {Com} from '../common.js'
|
|
10
|
+
import {h, createRef} from 'preact'
|
|
11
|
+
import RawOrder from '../order/order.js'
|
|
12
|
+
|
|
13
|
+
export default class Order extends Com {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props)
|
|
16
|
+
this.refRating = createRef()
|
|
17
|
+
this.refHandle = createRef()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
state = {
|
|
21
|
+
hide: true,
|
|
22
|
+
ratingHeight: 0,
|
|
23
|
+
overlayOpacity: 0.3,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
componentDidMount() {
|
|
27
|
+
this.mouseUp = (e) => this.onMouseUp(e)
|
|
28
|
+
this.mouseMove = (e) => this.onMouseMove(e)
|
|
29
|
+
this.mouseDown = (e) => this.onMouseDown(e)
|
|
30
|
+
|
|
31
|
+
var $ratingHandle = this.refHandle.current
|
|
32
|
+
$ratingHandle.addEventListener('mousedown', this.mouseDown, {passive: true})
|
|
33
|
+
$ratingHandle.addEventListener('touchstart', this.mouseDown, {passive: true})
|
|
34
|
+
|
|
35
|
+
window.addEventListener('mouseup', this.mouseUp, {passive: true})
|
|
36
|
+
window.addEventListener('touchend', this.mouseUp, {passive: true})
|
|
37
|
+
window.addEventListener('mousemove', this.mouseMove, {passive: true})
|
|
38
|
+
window.addEventListener('touchmove', this.mouseMove, {passive: true})
|
|
39
|
+
this.animation = new ReleaseAnimation({
|
|
40
|
+
maxY: POPUP_MAX_HEIGHT,
|
|
41
|
+
minY: POPUP_MIN_HEIGHT,
|
|
42
|
+
duration: 150,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
this.close()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
componentWillUnmount() {
|
|
49
|
+
var $ratingHandle = this.refHandle.current
|
|
50
|
+
$ratingHandle.removeEventListener('mousedown', this.mouseDown, 0)
|
|
51
|
+
$ratingHandle.removeEventListener('touchstart', this.mouseDown, 0)
|
|
52
|
+
|
|
53
|
+
window.removeEventListener('mouseup', this.mouseUp, 0)
|
|
54
|
+
window.removeEventListener('touchend', this.mouseUp, 0)
|
|
55
|
+
window.removeEventListener('mousemove', this.mouseMove, 0)
|
|
56
|
+
window.removeEventListener('touchmove', this.mouseMove, 0)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
render() {
|
|
60
|
+
if (this._show != this.props.show) {
|
|
61
|
+
this._show = this.props.show
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
if (!this._show) this.close()
|
|
64
|
+
else this.open()
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let cls = this.state.hide ? 'd-none' : ''
|
|
69
|
+
return (
|
|
70
|
+
<div class={cls}>
|
|
71
|
+
<div class='extension--overlay' style={`opacity: ${this.state.overlayOpacity * 0.5} !important;`}></div>
|
|
72
|
+
<div class='extension' ref={this.refRating} style={`height: ${this.state.ratingHeight}px !important;`}>
|
|
73
|
+
<div class='extension--close-btn' onClick={this.close}>
|
|
74
|
+
{this.props.t('close')}
|
|
75
|
+
</div>
|
|
76
|
+
<div class='extension--handle' ref={this.refHandle}>
|
|
77
|
+
<div class='extension--thumb'></div>
|
|
78
|
+
</div>
|
|
79
|
+
<div style='overflow-x: hidden !important; overflow-y: scroll !important; height: 100% !important;'>
|
|
80
|
+
<RawOrder
|
|
81
|
+
key={this.props.order_id}
|
|
82
|
+
store={this.props.store}
|
|
83
|
+
onResponse={this.onResponse}
|
|
84
|
+
onClose={this.close}
|
|
85
|
+
t={this.props.t}
|
|
86
|
+
order_id={this.props.order_id}
|
|
87
|
+
cid={this.props.cid}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
onResponse = (response) => {
|
|
96
|
+
this.setState({response})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
open() {
|
|
100
|
+
if (!this.state.hide) return
|
|
101
|
+
if (!this.props.order_id) return
|
|
102
|
+
this.setState({hide: false})
|
|
103
|
+
if (!this.refRating.current) return
|
|
104
|
+
var popupStyle = this.refRating.current.currentStyle || window.getComputedStyle(this.refRating.current)
|
|
105
|
+
var h0 = parseFloat(popupStyle.height)
|
|
106
|
+
this.animation.play(-20, h0, (h) => {
|
|
107
|
+
this.setState({
|
|
108
|
+
ratingHeight: h,
|
|
109
|
+
overlayOpacity: Math.min(1, (h - POPUP_MIN_HEIGHT) / (POPUP_HARD_MAX_HEIGHT - POPUP_MIN_HEIGHT)),
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
confirm = () => {
|
|
115
|
+
this.props.store.sendConvoEvent(this.props.cid, 'message_sent', {
|
|
116
|
+
message: {
|
|
117
|
+
format: 'plaintext',
|
|
118
|
+
text: 'confirm',
|
|
119
|
+
attachments: [
|
|
120
|
+
{type: 'postback', postback: {payload: JSON.stringify({type: 'order_confirmation', status: 'confirmed'})}},
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
close = async () => {
|
|
127
|
+
// wait for state to probagate
|
|
128
|
+
await sb.sleep(100)
|
|
129
|
+
if (this.state.response === 'confirmed') {
|
|
130
|
+
this.props.store.sendConvoEvent(this.props.cid, 'message_sent', {
|
|
131
|
+
message: {
|
|
132
|
+
format: 'plaintext',
|
|
133
|
+
text: this.props.t('confirm_order'),
|
|
134
|
+
attachments: [
|
|
135
|
+
{type: 'postback', postback: {payload: JSON.stringify({type: 'order_confirmation', status: 'confirmed'})}},
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
})
|
|
139
|
+
} else if (this.state.response === 'rejected') {
|
|
140
|
+
this.props.store.sendConvoEvent(this.props.cid, 'message_sent', {
|
|
141
|
+
message: {
|
|
142
|
+
format: 'plaintext',
|
|
143
|
+
text: this.props.t('cancel_order'),
|
|
144
|
+
attachments: [
|
|
145
|
+
{type: 'postback', postback: {payload: JSON.stringify({type: 'order_confirmation', status: 'cancelled'})}},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
})
|
|
149
|
+
} else {
|
|
150
|
+
}
|
|
151
|
+
this.setState({response: ''})
|
|
152
|
+
if (this.state.hide) return
|
|
153
|
+
if (!this.refRating.current) return
|
|
154
|
+
|
|
155
|
+
var popupStyle = this.refRating.current.currentStyle || window.getComputedStyle(this.refRating.current)
|
|
156
|
+
var h0 = parseFloat(popupStyle.height)
|
|
157
|
+
this.animation.play(20, h0, (h) => {
|
|
158
|
+
this.setState({
|
|
159
|
+
ratingHeight: h,
|
|
160
|
+
overlayOpacity: Math.min(1, (h - POPUP_MIN_HEIGHT) / (POPUP_HARD_MAX_HEIGHT - POPUP_MIN_HEIGHT)),
|
|
161
|
+
})
|
|
162
|
+
if (h < POPUP_MIN_HEIGHT + 10) {
|
|
163
|
+
if (!this.state.hide) {
|
|
164
|
+
this.setState({hide: true})
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
/*
|
|
169
|
+
this.props.store.sendConvoEvent(this.props.cid, 'message_sent', {
|
|
170
|
+
message: {
|
|
171
|
+
format: 'plaintext',
|
|
172
|
+
text: 'cancel',
|
|
173
|
+
attachments: [
|
|
174
|
+
{type: 'postback', postback: {payload: JSON.stringify({type: 'order_confirmation', status: 'cancelled'})}},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
})*/
|
|
178
|
+
this.props.onClose()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
onMouseDown(e) {
|
|
182
|
+
this.mousePushed = true
|
|
183
|
+
this.animation.stop()
|
|
184
|
+
e.preventDefault()
|
|
185
|
+
if (e.touches && e.touches[0]) e = e.touches[0]
|
|
186
|
+
this.mousePushedDy = e.pageY - window.pageYOffset - this.refRating.current.getBoundingClientRect().y
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
onMouseUp(e) {
|
|
190
|
+
if (!this.mousePushed) return
|
|
191
|
+
if (e.touches && e.touches[0]) e = e.touches[0]
|
|
192
|
+
this.mousePushed = false
|
|
193
|
+
var popupStyle = this.refRating.current.currentStyle || window.getComputedStyle(this.refRating.current)
|
|
194
|
+
var h0 = parseFloat(popupStyle.height)
|
|
195
|
+
this.animation.play(this.mouseVelocity, h0, (h) => {
|
|
196
|
+
this.setState({
|
|
197
|
+
ratingHeight: h,
|
|
198
|
+
overlayOpacity: Math.min(1, (h - POPUP_MIN_HEIGHT) / (POPUP_HARD_MAX_HEIGHT - POPUP_MIN_HEIGHT)),
|
|
199
|
+
})
|
|
200
|
+
if (h < POPUP_MIN_HEIGHT + 10) {
|
|
201
|
+
if (!this.state.hide) {
|
|
202
|
+
this.setState({hide: true})
|
|
203
|
+
this.props.onRate && this.props.onRate({no_rating: true})
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
onMouseMove(e) {
|
|
210
|
+
if (!this.mousePushed) return
|
|
211
|
+
if (e.touches && e.touches[0]) e = e.touches[0]
|
|
212
|
+
var my = e.pageY
|
|
213
|
+
|
|
214
|
+
this.mouseVelocity = my - this.lastMouseY
|
|
215
|
+
this.lastMouseY = my
|
|
216
|
+
my = my - this.mousePushedDy
|
|
217
|
+
var K = 10000
|
|
218
|
+
var height = this.refRating.current.getBoundingClientRect().bottom - my
|
|
219
|
+
|
|
220
|
+
if (height > POPUP_MAX_HEIGHT) {
|
|
221
|
+
//TODO
|
|
222
|
+
var beta = K / (POPUP_HARD_MAX_HEIGHT - POPUP_MAX_HEIGHT) - POPUP_MAX_HEIGHT
|
|
223
|
+
|
|
224
|
+
height = POPUP_HARD_MAX_HEIGHT - K / (height + beta)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.setState({
|
|
228
|
+
ratingHeight: height,
|
|
229
|
+
overlayOpacity: Math.min(1, (height - POPUP_MIN_HEIGHT) / (POPUP_HARD_MAX_HEIGHT - POPUP_MIN_HEIGHT)),
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -37,7 +37,8 @@ export default class ProductAttachments extends Com {
|
|
|
37
37
|
<div class='order_attachment__product'>
|
|
38
38
|
<img
|
|
39
39
|
class='order_attachment__product_img'
|
|
40
|
-
|
|
40
|
+
alt={'' + sb.get(product, 'id')}
|
|
41
|
+
src={sb.get(product, 'images.0', require('../../assets/img/default.jpg'))}
|
|
41
42
|
/>
|
|
42
43
|
<div style='overflow: hidden !important;'>
|
|
43
44
|
<div class='order_attachment__product_name'>{product.name}</div>
|
|
@@ -22,17 +22,53 @@ export default class ProductAttachments extends Com {
|
|
|
22
22
|
let $products = sb.map(products, (att, index) => {
|
|
23
23
|
let product = att.product
|
|
24
24
|
|
|
25
|
-
let $
|
|
25
|
+
let $detailbtns = []
|
|
26
26
|
let url = product.url || product.mobile_url
|
|
27
27
|
if (this.props.store.isMobile()) url = product.mobile_url || product.url
|
|
28
|
-
if (url)
|
|
29
|
-
$
|
|
28
|
+
if (url && sb.size(product.buttons) == 0)
|
|
29
|
+
$detailbtns.push(
|
|
30
30
|
<a class='product_attachment__btn' href={url} target='_blank'>
|
|
31
31
|
{this.props.t('detail')}
|
|
32
32
|
<img src={require('../../assets/img/external-link.svg')} class='product_attachment__btn_external_link' />
|
|
33
|
-
</a
|
|
33
|
+
</a>,
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
+
console.log("P", product)
|
|
37
|
+
|
|
38
|
+
if (sb.size(product.buttons) > 0) {
|
|
39
|
+
$detailbtns = $detailbtns.concat(
|
|
40
|
+
sb.map(product.buttons, (button, index) => {
|
|
41
|
+
if (button.type === 'call_button') {
|
|
42
|
+
return (
|
|
43
|
+
<a class='product_attachment__btn' href={'tel:' + button.phone_number} key={index} title={button.title}>
|
|
44
|
+
{button.title}
|
|
45
|
+
</a>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (button.type === 'url_button') {
|
|
50
|
+
return (
|
|
51
|
+
<a class='product_attachment__btn' href={button.url} target='_blank' key={index} title={button.title}>
|
|
52
|
+
{button.title || this.props.t('detail')}{' '}
|
|
53
|
+
<img
|
|
54
|
+
src={require('../../assets/img/external-link.svg')}
|
|
55
|
+
class='product_attachment__btn_external_link'
|
|
56
|
+
/>
|
|
57
|
+
</a>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (button.type === 'postback_button') {
|
|
62
|
+
return (
|
|
63
|
+
<a class='product_attachment__btn' href='javascript:;' onClick={(_) => this.props.onPostback(button)}>
|
|
64
|
+
{button.title}
|
|
65
|
+
</a>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
36
72
|
let $title = (
|
|
37
73
|
<a href={url} class='product_attachment__title' target='_blank'>
|
|
38
74
|
{product.name}
|
|
@@ -60,7 +96,7 @@ export default class ProductAttachments extends Com {
|
|
|
60
96
|
{$title}
|
|
61
97
|
{$subtitle}
|
|
62
98
|
{$price}
|
|
63
|
-
<div class='product_attachment__btns'>{$
|
|
99
|
+
<div class='product_attachment__btns'>{$detailbtns}</div>
|
|
64
100
|
</div>
|
|
65
101
|
)
|
|
66
102
|
})
|
|
@@ -9,11 +9,11 @@ const loadMarked = () => import(/*webpackChunkName: "marked" */ 'marked')
|
|
|
9
9
|
;(async () => {
|
|
10
10
|
let markedf = (await loadMarked()).marked
|
|
11
11
|
marked = (obj, text) => markedf(text)
|
|
12
|
-
sb.map(mustrerender, obj => obj.forceUpdate())
|
|
12
|
+
sb.map(mustrerender, (obj) => obj.forceUpdate())
|
|
13
13
|
mustrerender = []
|
|
14
14
|
})()
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import {Com} from '../common.js'
|
|
17
17
|
import {h} from 'preact'
|
|
18
18
|
import Emoji from './Emoji.js'
|
|
19
19
|
import ShadowDomRoot from './ShadowDomRoot.js'
|
|
@@ -28,12 +28,21 @@ export default class TextMessage extends Com {
|
|
|
28
28
|
if (sb.size(text) === 0) return null
|
|
29
29
|
|
|
30
30
|
let byType = sb.get(this.props.ev, 'by.type')
|
|
31
|
-
|
|
32
|
-
var tags = sb.extractText(text).map(tag => {
|
|
31
|
+
var tags = sb.extractText(text).map((tag) => {
|
|
33
32
|
if (tag.type === 'emoji') return <Emoji emojiCode={tag.text} byType={byType} />
|
|
34
33
|
if (tag.type === 'link') {
|
|
34
|
+
let url = tag.text || ''
|
|
35
|
+
if (
|
|
36
|
+
!url.startsWith('//') &&
|
|
37
|
+
!url.startsWith('https://') &&
|
|
38
|
+
!url.startsWith('http://') &&
|
|
39
|
+
!url.startsWith('data:')
|
|
40
|
+
) {
|
|
41
|
+
url = '//' + url
|
|
42
|
+
}
|
|
43
|
+
|
|
35
44
|
return (
|
|
36
|
-
<a href={
|
|
45
|
+
<a href={url} target='_blank' onClick={(e) => this.props.onLink(e, url)}>
|
|
37
46
|
{tag.text}
|
|
38
47
|
</a>
|
|
39
48
|
)
|
|
@@ -46,9 +55,9 @@ export default class TextMessage extends Com {
|
|
|
46
55
|
if (sb.size(tags) === 0) return null
|
|
47
56
|
|
|
48
57
|
if (byType === 'agent') {
|
|
49
|
-
return <div class=
|
|
58
|
+
return <div class='message-agent message-text--agent'>{tags}</div>
|
|
50
59
|
}
|
|
51
|
-
return <div class=
|
|
60
|
+
return <div class='message-user message-text--user'>{tags}</div>
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
renderMarkdown() {
|
|
@@ -62,16 +71,16 @@ export default class TextMessage extends Com {
|
|
|
62
71
|
|
|
63
72
|
if (byType === 'agent') {
|
|
64
73
|
return (
|
|
65
|
-
<div class=
|
|
66
|
-
|
|
74
|
+
<div class='markdown-message message-agent message-text--agent'>
|
|
75
|
+
<ShadowDomRoot html={marked(this, text)} />
|
|
67
76
|
</div>
|
|
68
77
|
)
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
return (
|
|
72
|
-
<div class=
|
|
73
|
-
<div class=
|
|
74
|
-
|
|
81
|
+
<div class='d-flex flex-column align-items-end'>
|
|
82
|
+
<div class='markdown-message message-user message-text--user'>
|
|
83
|
+
<ShadowDomRoot html={marked(this, text)} />
|
|
75
84
|
</div>
|
|
76
85
|
</div>
|
|
77
86
|
)
|
package/src/chatbox/Typing.js
CHANGED
|
@@ -30,6 +30,10 @@ export default class Typing extends Com {
|
|
|
30
30
|
return
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// dont show typing of agent, some agent dont like this
|
|
34
|
+
let ag = this.props.store.matchAgent(ev.by.id)
|
|
35
|
+
if (ag.type == 'agent') return
|
|
36
|
+
|
|
33
37
|
if (sb.get(ev, 'type') !== 'conversation_typing') return
|
|
34
38
|
this.setState({ ev: ev, isShow: true })
|
|
35
39
|
if (this.timer) clearTimeout(this.timer)
|
|
@@ -38,7 +42,7 @@ export default class Typing extends Com {
|
|
|
38
42
|
|
|
39
43
|
this.timer = null
|
|
40
44
|
this.setState({ isShow: false })
|
|
41
|
-
},
|
|
45
|
+
}, 5000)
|
|
42
46
|
})
|
|
43
47
|
}
|
|
44
48
|
|
package/src/chatbox/Widget.js
CHANGED
|
@@ -10,6 +10,7 @@ import MessageInput from './MessageInput.js'
|
|
|
10
10
|
import Events from './Events.js'
|
|
11
11
|
import Typing from './Typing.js'
|
|
12
12
|
import Rating from './Rating.js'
|
|
13
|
+
import Order from './Order.js'
|
|
13
14
|
import ListField from './ListField.js'
|
|
14
15
|
|
|
15
16
|
const defaultAvatar = 'https://file-subiz.com/fiqoahedjbgwclpouoml-avatar_default_baa8a1d7.png'
|
|
@@ -28,6 +29,8 @@ export default class Widget extends Com {
|
|
|
28
29
|
creating: false,
|
|
29
30
|
clickedJoin: false,
|
|
30
31
|
formData: {},
|
|
32
|
+
showOrder: false,
|
|
33
|
+
order_id: '',
|
|
31
34
|
})
|
|
32
35
|
|
|
33
36
|
this.props.store.onUpdate(this, (_) => this.forceUpdate())
|
|
@@ -44,6 +47,7 @@ export default class Widget extends Com {
|
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
if (prevProp.cid !== this.props.cid) {
|
|
50
|
+
this.closeOrder()
|
|
47
51
|
this.setState({clickedJoin: false})
|
|
48
52
|
// this.props.store.setLastview('chat', { cid: this.props.cid })
|
|
49
53
|
setTimeout(() => {
|
|
@@ -64,7 +68,6 @@ export default class Widget extends Com {
|
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
render() {
|
|
67
|
-
let formRequired = this.isFormRequired()
|
|
68
71
|
let showform = this.shouldShowForm()
|
|
69
72
|
|
|
70
73
|
let form
|
|
@@ -568,6 +571,7 @@ export default class Widget extends Com {
|
|
|
568
571
|
<div class='widget-body--content' onClick={(e) => this.onContainerClick(e)}>
|
|
569
572
|
<Events
|
|
570
573
|
isShow={this.props.isShow}
|
|
574
|
+
onLink={this.onLink}
|
|
571
575
|
store={this.props.store}
|
|
572
576
|
onFormSubmit={(e) => this.onEventFormSubmit(e)}
|
|
573
577
|
ref={(ref) => (this.events = ref)}
|
|
@@ -587,11 +591,39 @@ export default class Widget extends Com {
|
|
|
587
591
|
cid={this.props.cid}
|
|
588
592
|
t={this.props.t}
|
|
589
593
|
/>
|
|
594
|
+
<Order
|
|
595
|
+
forceView={this.props.view}
|
|
596
|
+
plugin={this.props.plugin}
|
|
597
|
+
show={this.state.showOrder}
|
|
598
|
+
order_id={this.state.order_id}
|
|
599
|
+
store={this.props.store}
|
|
600
|
+
onClose={this.closeOrder}
|
|
601
|
+
cid={this.props.cid}
|
|
602
|
+
t={this.props.t}
|
|
603
|
+
/>
|
|
590
604
|
{$input}
|
|
591
605
|
</div>
|
|
592
606
|
)
|
|
593
607
|
}
|
|
594
608
|
|
|
609
|
+
onLink = (e, url) => {
|
|
610
|
+
if (!url) return e.preventDefault()
|
|
611
|
+
let noschemeurl = url.replace(/(^\w+:|^)\/\//, '')
|
|
612
|
+
if (noschemeurl.startsWith('widget.subiz.com.vn/orders/')) {
|
|
613
|
+
let orderid = noschemeurl.substr('widget.subiz.com.vn/orders/'.length)
|
|
614
|
+
orderid = orderid.split('/')[0]
|
|
615
|
+
this.setState({showOrder: true, order_id: orderid})
|
|
616
|
+
// display order instead
|
|
617
|
+
e.preventDefault()
|
|
618
|
+
return
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
closeOrder = (e) => {
|
|
623
|
+
this.setState({showOrder: false, order_id: ''})
|
|
624
|
+
this.focusInput()
|
|
625
|
+
}
|
|
626
|
+
|
|
595
627
|
// end or visit unsent convo which require form
|
|
596
628
|
async onStartConvoClick() {
|
|
597
629
|
var convo = this.props.store.matchConvo(this.props.cid) || {}
|
|
@@ -866,7 +898,5 @@ class FormMounter extends Com {
|
|
|
866
898
|
}
|
|
867
899
|
|
|
868
900
|
function encode(key) {
|
|
869
|
-
return
|
|
870
|
-
.split('=')
|
|
871
|
-
.join('')
|
|
901
|
+
return encodeURIComponent(key)
|
|
872
902
|
}
|
package/src/chatbox/main.js
CHANGED
|
@@ -160,12 +160,15 @@ export default class Main extends Com {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
function restoreViewport() {
|
|
163
|
-
//
|
|
163
|
+
// restore scroll attribute for background document
|
|
164
|
+
if (document.body && document.body.classList) document.body.classList.remove('sbz_no_scroll')
|
|
164
165
|
let metatag = document.getElementById('subiz-meta-viewport')
|
|
165
166
|
if (metatag) metatag.remove()
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
function modifyViewport() {
|
|
170
|
+
// dont allow to scroll background document
|
|
171
|
+
if (document.body && document.body.classList) document.body.classList.add('sbz_no_scroll')
|
|
169
172
|
let metatag = document.createElement('meta')
|
|
170
173
|
metatag.httpEquiv = 'X-UA-Compatible'
|
|
171
174
|
metatag.name = 'viewport'
|
package/src/chatbox/spinner.js
CHANGED
|
@@ -17,7 +17,7 @@ export default class Spinner extends Com {
|
|
|
17
17
|
border-left-color: ${borderColor} !important;border-top-color: ${borderColor} !important;
|
|
18
18
|
border-bottom-color: ${borderColor} !important;border-right-color: ${mainColor} !important;`
|
|
19
19
|
if (this.props.static) {
|
|
20
|
-
let style = `width: ${size}px;height: ${size}px;`
|
|
20
|
+
let style = `width: ${size}px !important;height: ${size}px !important;`
|
|
21
21
|
if (size < 40) return <LoaderIcon size={size + ''} style={`stroke:${mainColor}`} />
|
|
22
22
|
if (this.props.center) {
|
|
23
23
|
return (
|
package/src/chatbox/time.js
CHANGED
package/src/common.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {h, Component} from 'preact'
|
|
2
2
|
import sb from './util/index.js'
|
|
3
3
|
|
|
4
4
|
export class Com extends Component {
|
|
5
|
-
constructor
|
|
5
|
+
constructor(props) {
|
|
6
6
|
super(props)
|
|
7
7
|
this._isMounted = true
|
|
8
8
|
setTimeout(() => {
|
|
@@ -18,31 +18,75 @@ export class Com extends Component {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export class Clickaway extends Com {
|
|
21
|
-
constructor
|
|
21
|
+
constructor(props) {
|
|
22
22
|
super(props)
|
|
23
23
|
this.setWrapperRef = this.setWrapperRef.bind(this)
|
|
24
24
|
this.onClick = this.onClick.bind(this)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
componentDidMount
|
|
27
|
+
componentDidMount() {
|
|
28
28
|
document.addEventListener('mousedown', this.onClick)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
componentWillUnmount
|
|
31
|
+
componentWillUnmount() {
|
|
32
32
|
document.removeEventListener('mousedown', this.onClick)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
setWrapperRef
|
|
35
|
+
setWrapperRef(node) {
|
|
36
36
|
this.wrapperRef = node
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
onClick
|
|
39
|
+
onClick(event) {
|
|
40
40
|
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
|
|
41
41
|
this.props.onClickaway && this.props.onClickaway()
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
render
|
|
45
|
+
render() {
|
|
46
46
|
return <div ref={this.setWrapperRef}>{this.props.children}</div>
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
export const getLocale = (plugin, loc) => {
|
|
51
|
+
if (!loc) loc = ''
|
|
52
|
+
let found = sb.find(plugin.locales, (l) => l.toLowerCase().trim() === loc.toLowerCase().trim())
|
|
53
|
+
if (found) return found
|
|
54
|
+
|
|
55
|
+
found = sb.find(plugin.locales, (l) => {
|
|
56
|
+
l = l
|
|
57
|
+
.replace('-', '_')
|
|
58
|
+
.split('_')[0]
|
|
59
|
+
.trim()
|
|
60
|
+
.toLowerCase()
|
|
61
|
+
let compareloc = loc
|
|
62
|
+
.replace('-', '_')
|
|
63
|
+
.split('_')[0]
|
|
64
|
+
.trim()
|
|
65
|
+
.toLowerCase()
|
|
66
|
+
return l == compareloc
|
|
67
|
+
})
|
|
68
|
+
if (found) return found
|
|
69
|
+
return plugin.locale || 'en-US'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export let langMessages = {}
|
|
73
|
+
let downloadLock = false
|
|
74
|
+
|
|
75
|
+
export function downloadLanguage(store, locale, force) {
|
|
76
|
+
if (downloadLock)
|
|
77
|
+
return new Promise((resolve) => setTimeout(() => downloadLanguage(store, locale, force).then(resolve), 100))
|
|
78
|
+
|
|
79
|
+
downloadLock = true
|
|
80
|
+
// let locale = getLocale()
|
|
81
|
+
let messages
|
|
82
|
+
if (locale === 'debug' || (langMessages[locale] && !force)) {
|
|
83
|
+
downloadLock = false
|
|
84
|
+
return Promise.resolve()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return store.getLocaleContent(locale).then((res) => {
|
|
88
|
+
downloadLock = false
|
|
89
|
+
messages = sb.get(res, 'body.messages', [])
|
|
90
|
+
langMessages[locale] = messages
|
|
91
|
+
})
|
|
92
|
+
}
|
package/src/contact/contact.js
CHANGED
|
@@ -2,7 +2,7 @@ import sb from '../util/index.js'
|
|
|
2
2
|
import {render, h, createRef} from 'preact'
|
|
3
3
|
import {Com} from '../common.js'
|
|
4
4
|
// var Color = require('color')
|
|
5
|
-
import {Loader} from '@googlemaps/js-api-loader'
|
|
5
|
+
// import {Loader} from '@googlemaps/js-api-loader'
|
|
6
6
|
|
|
7
7
|
let CSS = (() => import(/*webpackChunkName: "contact-css" */ './css.js'))()
|
|
8
8
|
|