Skip to content

Commit 4291235

Browse files
refactor: replace time-based polling with Chatwoot builtin event
Replaced the time-based polling mechanism with a Chatwoot builtin event listener for detecting readiness. Introduced `isReady` and `waitForReady` utility to ensure Chatwoot API calls are made only after initialization This also fixes an occasional bug where `observer.value.observe` fails with `TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'`. The error occurred because `document.querySelector('.woot-widget-holder')` sometimes returned `null`, causing `startObserver` to initialize with an invalid node.
1 parent 044d147 commit 4291235

File tree

1 file changed

+36
-22
lines changed

1 file changed

+36
-22
lines changed

src/runtime/vue/vue.ts

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { App } from 'vue'
22
import defu from 'defu'
3-
import { onBeforeUnmount, onMounted, ref } from 'vue'
3+
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
44

55
declare global {
66
interface Window {
@@ -229,8 +229,7 @@ export function createChatWoot(options: OptionPlugin) {
229229

230230
export function useChatWoot() {
231231
const observer = ref<any>(null)
232-
const start = ref(1)
233-
let timer: ReturnType<typeof setTimeout>
232+
const isReady = ref(false)
234233
const isModalVisible = ref(false)
235234

236235
function observerStart(data: any) {
@@ -256,79 +255,94 @@ export function useChatWoot() {
256255
}
257256
}
258257

258+
function onReady() {
259+
const data = document.querySelector('.woot-widget-holder')
260+
isReady.value = true
261+
observerStart(data)
262+
}
263+
264+
function waitForReady(callback: () => void) {
265+
if (isReady.value) {
266+
callback()
267+
}
268+
else {
269+
const stop = watch(isReady, (value) => {
270+
if (!value)
271+
return
272+
callback()
273+
stop()
274+
})
275+
}
276+
}
277+
259278
onMounted(() => {
260-
timer = setInterval(() => {
261-
start.value += 1
262-
const data = document.querySelector('.woot-widget-holder')
263-
if (data || start.value > 100) {
264-
clearInterval(timer)
265-
observerStart(data)
266-
}
267-
}, 100)
279+
window.addEventListener('chatwoot:ready', onReady, { once: true })
268280
})
269281

270282
onBeforeUnmount(() => {
283+
window.removeEventListener('chatwoot:ready', onReady)
284+
271285
if (observer.value)
272286
observer.value.disconnect()
273287
})
274288

275289
const toggle = (state: Parameters<Chatwoot['toggle']>[0]) => {
276-
isLoadTimer().then(() => window.$chatwoot.toggle(state))
290+
waitForReady(() => window.$chatwoot.toggle(state))
277291
}
278292

279293
const setUser = (
280294
key: Parameters<Chatwoot['setUser']>[0],
281295
args: Parameters<Chatwoot['setUser']>[1],
282296
) => {
283-
isLoadTimer().then(() => window.$chatwoot.setUser(key, args))
297+
waitForReady(() => window.$chatwoot.setUser(key, args))
284298
}
285299

286300
const setCustomAttributes = (
287301
attributes: Parameters<Chatwoot['setCustomAttributes']>[0],
288302
) => {
289-
isLoadTimer().then(() => window.$chatwoot.setCustomAttributes(attributes))
303+
waitForReady(() => window.$chatwoot.setCustomAttributes(attributes))
290304
}
291305

292306
const setConversationCustomAttributes = (
293307
attributes: Parameters<Chatwoot['setConversationCustomAttributes']>[0],
294308
) => {
295-
isLoadTimer().then(() => window.$chatwoot.setConversationCustomAttributes(attributes))
309+
waitForReady(() => window.$chatwoot.setConversationCustomAttributes(attributes))
296310
}
297311

298312
const deleteCustomAttribute = (
299313
attributes: Parameters<Chatwoot['deleteCustomAttribute']>[0],
300314
) => {
301-
isLoadTimer().then(() =>
315+
waitForReady(() =>
302316
window.$chatwoot.deleteCustomAttribute(attributes),
303317
)
304318
}
305319

306320
const setLocale = (local: Parameters<Chatwoot['setLocale']>[0]) => {
307-
isLoadTimer().then(() => window.$chatwoot.setLocale(local))
321+
waitForReady(() => window.$chatwoot.setLocale(local))
308322
}
309323

310324
const setLabel = (label: Parameters<Chatwoot['setLabel']>[0]) => {
311-
isLoadTimer().then(() => window.$chatwoot.setLabel(label))
325+
waitForReady(() => window.$chatwoot.setLabel(label))
312326
}
313327

314328
const removeLabel = (label: Parameters<Chatwoot['removeLabel']>[0]) => {
315-
isLoadTimer().then(() => window.$chatwoot.removeLabel(label))
329+
waitForReady(() => window.$chatwoot.removeLabel(label))
316330
}
317331

318332
const reset = () => {
319-
isLoadTimer().then(() => window.$chatwoot.reset())
333+
waitForReady(() => window.$chatwoot.reset())
320334
}
321335

322336
const toggleBubbleVisibility = (
323337
visibility: Parameters<Chatwoot['toggleBubbleVisibility']>[0],
324338
) => {
325-
isLoadTimer().then(() => {
339+
waitForReady(() => {
326340
window.$chatwoot.toggleBubbleVisibility(visibility)
327341
})
328342
}
329343

330344
const popoutChatWindow = () => {
331-
isLoadTimer().then(() => window.$chatwoot.popoutChatWindow())
345+
waitForReady(() => window.$chatwoot.popoutChatWindow())
332346
}
333347

334348
return {

0 commit comments

Comments
 (0)