1
0
forked from test/crm

feat: react on whatsapp message

This commit is contained in:
Shariq Ansari 2024-04-20 23:37:10 +05:30
parent 0b537cb47e
commit 00d9e1d529
3 changed files with 93 additions and 6 deletions

View File

@ -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()),
})

View 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>

View File

@ -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>