feat: react on whatsapp message
This commit is contained in:
parent
0b537cb47e
commit
00d9e1d529
@ -110,7 +110,11 @@
|
||||
v-else-if="title == 'WhatsApp' && whatsappMessages.data?.length"
|
||||
class="activities flex-1 overflow-y-auto"
|
||||
>
|
||||
<WhatsAppArea class="px-10" :messages="whatsappMessages.data" />
|
||||
<WhatsAppArea
|
||||
class="px-10"
|
||||
v-model="whatsappMessages"
|
||||
:messages="whatsappMessages.data"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="activities?.length" class="activities flex-1 overflow-y-auto">
|
||||
<div
|
||||
@ -930,6 +934,8 @@ const whatsappMessages = createListResource({
|
||||
'attach',
|
||||
'template',
|
||||
'use_template',
|
||||
'message_id',
|
||||
'reply_to_message_id',
|
||||
'creation',
|
||||
'message',
|
||||
'status',
|
||||
@ -942,7 +948,23 @@ const whatsappMessages = createListResource({
|
||||
orderBy: 'modified desc',
|
||||
pageLength: 99999,
|
||||
auto: true,
|
||||
transform: (data) => sortByCreation(data),
|
||||
transform: (data) => {
|
||||
data = sortByCreation(data)
|
||||
// loop on filtered data where message.content_type == 'reaction'
|
||||
data
|
||||
.filter((message) => message.content_type == 'reaction')
|
||||
.forEach((message) => {
|
||||
// find the message that this reaction is reacting to
|
||||
const reactedMessage = data.find(
|
||||
(m) => m.message_id == message.reply_to_message_id
|
||||
)
|
||||
// if the reacted message is found, add the reaction to it
|
||||
if (reactedMessage) {
|
||||
reactedMessage.reaction = message.message
|
||||
}
|
||||
})
|
||||
return data.filter((message) => message.content_type != 'reaction')
|
||||
},
|
||||
onSuccess: () => nextTick(() => scroll()),
|
||||
})
|
||||
|
||||
|
||||
17
frontend/src/components/Icons/ReactIcon.vue
Normal file
17
frontend/src/components/Icons/ReactIcon.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<svg
|
||||
viewBox="0 0 15 15"
|
||||
width="15"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
class=""
|
||||
fill="none"
|
||||
>
|
||||
<title>react</title>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M0 7.5C0 11.6305 3.36946 15 7.5 15C11.6527 15 15 11.6305 15 7.5C15 3.36946 11.6305 0 7.5 0C3.36946 0 0 3.36946 0 7.5ZM10.995 8.69333C11.1128 8.67863 11.2219 8.66503 11.3211 8.65309C11.61 8.63028 11.8076 8.91918 11.6784 9.13965C10.8573 10.6374 9.29116 11.793 7.50455 11.793C5.71794 11.793 4.15181 10.6602 3.33072 9.16246C3.18628 8.91918 3.37634 8.63028 3.66524 8.65309C3.79123 8.66749 3.93521 8.68511 4.09426 8.70457C4.94292 8.80842 6.22074 8.96479 7.48174 8.96479C8.81855 8.96479 10.1378 8.80025 10.995 8.69333ZM5.41405 7.37207C6.05761 7.37207 6.60923 6.72851 6.60923 6.02978C6.60923 5.30348 6.05761 4.6875 5.41405 4.6875C4.77048 4.6875 4.21886 5.33106 4.21886 6.02978C4.20967 6.75609 4.77048 7.37207 5.41405 7.37207ZM10.7807 6.05619C10.7807 6.74114 10.24 7.37201 9.60912 7.37201C8.97825 7.37201 8.4375 6.76818 8.4375 6.05619C8.4375 5.37124 8.97825 4.74037 9.60912 4.74037C10.24 4.74037 10.7807 5.34421 10.7807 6.05619Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
@ -3,13 +3,22 @@
|
||||
<div
|
||||
v-for="whatsapp in messages"
|
||||
:key="whatsapp.name"
|
||||
class="activity flex"
|
||||
:class="{ 'justify-end': whatsapp.type == 'Outgoing' }"
|
||||
class="activity group mb-3 flex gap-2"
|
||||
:class="[whatsapp.type == 'Outgoing' ? 'flex-row-reverse' : '']"
|
||||
>
|
||||
<div
|
||||
:id="whatsapp.name"
|
||||
class="mb-3 inline-flex max-w-[90%] gap-2 rounded-md bg-gray-50 p-1.5 pl-2 text-base shadow-sm"
|
||||
:class="[whatsapp.reaction ? 'mb-4' : '']"
|
||||
class="relative inline-flex max-w-[90%] gap-2 rounded-md bg-gray-50 p-1.5 pl-2 text-base shadow-sm"
|
||||
>
|
||||
<div
|
||||
class="absolute -bottom-5 flex gap-1 rounded-full border bg-white p-1 pb-[3px] shadow-sm"
|
||||
v-if="whatsapp.reaction"
|
||||
>
|
||||
<div class="flex size-4 items-center justify-center">
|
||||
{{ whatsapp.reaction }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="whatsapp.content_type == 'text'"
|
||||
v-html="formatWhatsAppMessage(whatsapp.message)"
|
||||
@ -76,21 +85,43 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-center opacity-0 transition-all ease-in group-hover:opacity-100"
|
||||
>
|
||||
<IconPicker
|
||||
v-model="emoji"
|
||||
v-model:reaction="reaction"
|
||||
v-slot="{ togglePopover }"
|
||||
@update:modelValue="() => reactOnMessage(whatsapp.name, emoji)"
|
||||
>
|
||||
<Button
|
||||
@click="() => (reaction = true) && togglePopover()"
|
||||
class="rounded-full"
|
||||
>
|
||||
<ReactIcon class="text-gray-400" />
|
||||
</Button>
|
||||
</IconPicker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import IconPicker from '@/components/IconPicker.vue'
|
||||
import CheckIcon from '@/components/Icons/CheckIcon.vue'
|
||||
import DoubleCheckIcon from '@/components/Icons/DoubleCheckIcon.vue'
|
||||
import DocumentIcon from '@/components/Icons/DocumentIcon.vue'
|
||||
import { Tooltip } from 'frappe-ui'
|
||||
import ReactIcon from '@/components/Icons/ReactIcon.vue'
|
||||
import { dateFormat } from '@/utils'
|
||||
import { Tooltip, createResource } from 'frappe-ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
messages: Array,
|
||||
})
|
||||
|
||||
const list = defineModel()
|
||||
|
||||
function openFileInAnotherTab(url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
@ -117,4 +148,21 @@ function formatWhatsAppMessage(message) {
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
const emoji = ref('')
|
||||
const reaction = ref(true)
|
||||
|
||||
function reactOnMessage(name, emoji) {
|
||||
createResource({
|
||||
url: 'crm.api.whatsapp.react_on_whatsapp_message',
|
||||
params: {
|
||||
emoji,
|
||||
reply_to_name: name,
|
||||
},
|
||||
auto: true,
|
||||
onSuccess() {
|
||||
list.value.reload()
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user