|
| 1 | +<script setup lang="ts"> |
| 2 | +import { useScriptIntercom } from '../registry/intercom' |
| 3 | +import { useElementScriptTrigger } from '../composables/useElementScriptTrigger' |
| 4 | +import { ref, onMounted } from '#imports' |
| 5 | +import type { ElementScriptTrigger } from '#nuxt-scripts' |
| 6 | +
|
| 7 | +const props = withDefaults(defineProps<{ |
| 8 | + appId: string |
| 9 | + apiBase?: string |
| 10 | + name?: string |
| 11 | + email?: string |
| 12 | + userId?: string |
| 13 | + // customizing the messenger |
| 14 | + alignment?: 'left' | 'right' |
| 15 | + horizontalPadding?: number |
| 16 | + verticalPadding?: number |
| 17 | + /** |
| 18 | + * Defines the trigger event to load the script. |
| 19 | + */ |
| 20 | + trigger?: ElementScriptTrigger |
| 21 | +}>(), { |
| 22 | + trigger: 'click', |
| 23 | +}) |
| 24 | +
|
| 25 | +const emits = defineEmits<{ |
| 26 | + // our emit |
| 27 | + ready: [e: ReturnType<typeof useScriptIntercom>] |
| 28 | +}>() |
| 29 | +
|
| 30 | +const rootEl = ref(null) |
| 31 | +const trigger = useElementScriptTrigger({ trigger: props.trigger, el: rootEl }) |
| 32 | +
|
| 33 | +const isReady = ref(false) |
| 34 | +const intercom = useScriptIntercom({ |
| 35 | + app_id: props.appId, |
| 36 | + // @ts-expect-error untyped |
| 37 | + app_base: props.apiBase, |
| 38 | + name: props.name, |
| 39 | + email: props.email, |
| 40 | + user_id: props.userId, |
| 41 | + alignment: props.alignment, |
| 42 | + horizontal_padding: props.horizontalPadding, |
| 43 | + vertical_padding: props.verticalPadding, |
| 44 | + scriptOptions: { |
| 45 | + trigger, |
| 46 | + }, |
| 47 | +}) |
| 48 | +if (props.trigger === 'click') |
| 49 | + intercom.Intercom('show') |
| 50 | +const { $script } = intercom |
| 51 | +
|
| 52 | +defineExpose({ |
| 53 | + intercom, |
| 54 | +}) |
| 55 | +
|
| 56 | +// add a listener to detect when the dom element #crisp-chatbox is added |
| 57 | +onMounted(() => { |
| 58 | + const observer = new MutationObserver(() => { |
| 59 | + if (document.getElementById('crisp-chatbox')) { |
| 60 | + isReady.value = true |
| 61 | + emits('ready', intercom) |
| 62 | + observer.disconnect() |
| 63 | + } |
| 64 | + }) |
| 65 | + observer.observe(document.body, { childList: true, subtree: true }) |
| 66 | +}) |
| 67 | +</script> |
| 68 | + |
| 69 | +<template> |
| 70 | + <div |
| 71 | + ref="rootEl" |
| 72 | + style="display: block; position: absolute; bottom: 20px; right: 20px; z-index: 100000; " |
| 73 | + > |
| 74 | + <slot :ready="isReady" /> |
| 75 | + <slot v-if="$script.status.value === 'awaitingLoad'" name="awaitingLoad" /> |
| 76 | + <slot v-else-if="$script.status.value === 'loading' || !isReady" name="loading" /> |
| 77 | + </div> |
| 78 | +</template> |
0 commit comments