@defra/flood-webchat 0.0.1-alpha.9 → 0.0.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +1 -83
  2. package/dist/client.js +445 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/server.js +362 -0
  5. package/dist/server.js.map +1 -0
  6. package/docs/development-guide.md +1 -2
  7. package/jest.config.mjs +29 -0
  8. package/main.scss +5 -741
  9. package/package.json +18 -13
  10. package/src/client/components/availability/availability.jsx +101 -0
  11. package/src/client/components/availability/availability.scss +89 -0
  12. package/src/client/index.jsx +16 -0
  13. package/src/client/lib/check-availability.js +7 -0
  14. package/src/client/lib/classnames.js +1 -0
  15. package/src/client/lib/external-stores.js +4 -0
  16. package/src/client/lib/external-sync-store.js +42 -0
  17. package/src/server/index.js +11 -6
  18. package/src/server/{client.js → lib/client.js} +32 -12
  19. package/src/server/{utils.js → lib/utils.js} +8 -13
  20. package/webpack.config.mjs +32 -0
  21. package/assets/audio/notification.mp3 +0 -0
  22. package/babel.config.cjs +0 -3
  23. package/dist/templates.js +0 -554
  24. package/src/client/index.js +0 -14
  25. package/src/client/lib/availability.js +0 -75
  26. package/src/client/lib/config.js +0 -17
  27. package/src/client/lib/keyboard.js +0 -149
  28. package/src/client/lib/notification.js +0 -59
  29. package/src/client/lib/nunjucks.js +0 -3
  30. package/src/client/lib/panel.js +0 -293
  31. package/src/client/lib/provider.js +0 -11
  32. package/src/client/lib/skiplink.js +0 -27
  33. package/src/client/lib/state.js +0 -82
  34. package/src/client/lib/transcript.js +0 -34
  35. package/src/client/lib/utils.js +0 -190
  36. package/src/client/lib/webchat.js +0 -1075
  37. package/src/style/_mixins.scss +0 -13
@@ -1,190 +0,0 @@
1
- import Config from './config.js'
2
- import nunjucks from './nunjucks.js'
3
-
4
- const env = nunjucks
5
-
6
- class Utils {
7
- static addOrUpdateParameter (uri, key, value) {
8
- // Temporariliy remove fragment
9
- const i = uri.indexOf('#')
10
- const hash = i === -1 ? '' : uri.substr(i)
11
- uri = i === -1 ? uri : uri.substr(0, i)
12
- const re = new RegExp('([?&])' + key + '=[^&#]*', 'i')
13
- // Delete parameter and value
14
- if (!value || value === '') {
15
- uri = uri.replace(re, '')
16
- } else if (re.test(uri)) {
17
- // Replace parameter value
18
- uri = uri.replace(re, '$1' + key + '=' + value)
19
- // Add parameter and value
20
- } else {
21
- const separator = /\?/.test(uri) ? '&' : '?'
22
- uri = uri + separator + key + '=' + value
23
- }
24
- return uri + hash
25
- }
26
-
27
- static getParameterByName (name) {
28
- const v = window.location.search.match(new RegExp('(?:[?&]' + name + '=)([^&]+)'))
29
- return v ? v[1] : null
30
- }
31
-
32
- static listenForDevice (device, callback) {
33
- const mQ = window.matchMedia(`(max-width: ${Config.getBreakpoint(device)})`)
34
- if (window.matchMedia.addEventListener) {
35
- mQ.addEventListener('change', e => { callback(e.matches) })
36
- } else {
37
- mQ.addListener(e => { callback(e.matches) })
38
- }
39
- callback(mQ.matches)
40
- }
41
-
42
- static formatDate (value) {
43
- const now = new Date().getTime()
44
- const startOfDay = now - (now % 86400000)
45
- const isToday = value.getTime() >= startOfDay
46
- let hours = value.getHours()
47
- let minutes = value.getMinutes()
48
- minutes = `${minutes < 10 ? '0' : ''}${minutes}`
49
- const ampm = hours >= 12 ? 'pm' : 'am'
50
- hours %= 12
51
- hours = hours || 12
52
- const time = `${hours}:${minutes}${ampm}`
53
- const date = value.toLocaleString('en-GB', { day: 'numeric', month: 'short' })
54
- return isToday ? time : `${time}, ${date}`
55
- }
56
-
57
- static parseMessage (input) {
58
- let text = input
59
-
60
- // Convert line breaks
61
- text = text.trim().replace(/(\r\n|\r|\n){2,}/g, '$1\n').replace(/\r\n|\r|\n/g, '<br>')
62
-
63
- // Convert links
64
- const linksFound = text.match(/(?:www|https?)[^\s]+/g)
65
- const aLink = []
66
- if (linksFound != null) {
67
- for (let i = 0; i < linksFound.length; i++) {
68
- const href = linksFound[i]
69
- const anchor = linksFound[i].replace(/#webchat|https?:\/\//gi, '')
70
- aLink.push(`<a href="${href}">${anchor}</a>`)
71
- text = text.split(linksFound[i]).join(aLink[i])
72
- }
73
- }
74
-
75
- return text
76
- }
77
-
78
- static sortMessages (messages) {
79
- return messages.sort((a, b) => {
80
- return a.createdAt - b.createdAt
81
- })
82
- }
83
-
84
- static addMessagesHtml (messages) {
85
- const m = messages
86
- for (let i = 0; i < m.length; i++) {
87
- const isGroupStart = i === 0 || (i > 0 && m[i].direction !== m[i - 1].direction)
88
- const isGroupEnd = (i === m.length - 1) || (i < (m.length - 1) && m[i].direction !== m[i + 1].direction)
89
- m[i].isGroupStart = isGroupStart
90
- m[i].isGroupEnd = isGroupEnd
91
- const html = env.render('message.html', { model: m[i] })
92
- m[i].html = html
93
- }
94
- return m
95
- }
96
-
97
- static setCountdown (element, callback) {
98
- let second = Config.countdown
99
- const interval = setInterval(() => {
100
- second--
101
- if (element) {
102
- element.innerHTML = `${second} seconds`
103
- }
104
- if (second <= 0) {
105
- clearInterval(interval)
106
- callback()
107
- }
108
- }, 1000)
109
- return interval
110
- }
111
-
112
- static toggleLabel (label, key, textbox) {
113
- const chars = /^[a-zA-Z0-9- !'^+%&/()=?_\-~`;#$½{[\]}\\|<>@,]+$/i // /^[a-z\d -]+$/i
114
- const hasValue = textbox.value.length > 0
115
- const isValidChar = key && key.length === 1 && chars.test(key)
116
- const isHidden = hasValue || (!hasValue && isValidChar)
117
- label.classList.toggle('wc-message__label--hidden', isHidden)
118
- }
119
-
120
- static submit (e, textbox) {
121
- const form = textbox.closest('form')
122
- const isEnterSubmit = textbox.hasAttribute('data-wc-enter-submit')
123
- if (e.key !== 'Enter' || !isEnterSubmit || e.altKey || e.shiftKey) {
124
- return
125
- }
126
- form.dispatchEvent(new Event('submit'))
127
- }
128
-
129
- static suppressEnter (e, textbox) {
130
- const isEnterSubmit = textbox.hasAttribute('data-wc-enter-submit')
131
- const hasValue = textbox.value.length > 0
132
- if (e.key === 'Enter' && (!hasValue || (isEnterSubmit && !e.altKey && !e.shiftKey))) {
133
- e.preventDefault()
134
- }
135
- }
136
-
137
- static autosize (textbox) {
138
- const offset = textbox.offsetHeight - textbox.clientHeight
139
- textbox.addEventListener('input', e => {
140
- e.target.style.height = 'auto'
141
- e.target.style.height = e.target.scrollHeight + offset + 'px'
142
- })
143
- }
144
-
145
- static async poll ({ fn, validate, interval, maxAttempts }) {
146
- let attempts = 0
147
-
148
- const executePoll = async (resolve, reject) => {
149
- const result = await fn()
150
- attempts++
151
-
152
- if (interval <= 0) {
153
- return
154
- }
155
-
156
- if (validate && validate(result)) {
157
- return resolve(result)
158
- } else if (maxAttempts && attempts === maxAttempts) {
159
- return reject(new Error('Exceeded max attempts'))
160
- } else {
161
- setTimeout(executePoll, interval, resolve, reject)
162
- }
163
- }
164
-
165
- return new Promise(executePoll)
166
- }
167
-
168
- static async getAvailability (endpoint) {
169
- try {
170
- const response = await fetch(endpoint)
171
- const data = await response.json()
172
- return data.availability
173
- } catch (err) {
174
- console.log('getAvailability', err)
175
- return 'UNAVAILABLE'
176
- }
177
- }
178
-
179
- static getDuration (seconds) {
180
- let duration = seconds
181
- if (seconds <= 60) {
182
- duration = `${seconds} seconds`
183
- } else {
184
- duration = `${Math.floor(seconds / 60)} minutes`
185
- }
186
- return duration
187
- }
188
- }
189
-
190
- export default Utils