0af38cf50c
Signed-off-by: Sebastian <krupinski01@gmail.com>
190 lines
4.8 KiB
Vue
190 lines
4.8 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import type { MessageAddressInterface } from '@MailManager/types/message'
|
|
import { useMailUiStore } from '@/stores/mailUiStore'
|
|
import { ComposerMode } from '@/types/composer'
|
|
|
|
interface Props {
|
|
address?: MessageAddressInterface | null
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
// Emits
|
|
const emit = defineEmits<{
|
|
clicked: []
|
|
}>()
|
|
|
|
const mailUiStore = useMailUiStore()
|
|
|
|
const recipientLabel = computed(() => props.address?.label?.trim() || '')
|
|
const recipientAddress = computed(() => props.address?.address?.trim() || '')
|
|
const displayLabel = computed(() => recipientLabel.value || recipientAddress.value || 'Unknown Sender')
|
|
const formattedAddress = computed(() => {
|
|
if (recipientLabel.value && recipientAddress.value && recipientLabel.value !== recipientAddress.value) {
|
|
return `${recipientLabel.value} <${recipientAddress.value}>`
|
|
}
|
|
|
|
return recipientAddress.value || recipientLabel.value
|
|
})
|
|
const hasEmail = computed(() => recipientAddress.value.length > 0)
|
|
|
|
const showCopyResult = (message: string, color: 'success' | 'error') => {
|
|
mailUiStore.notify(message, color)
|
|
}
|
|
|
|
const copy = async (value: string, label: string) => {
|
|
if (!value) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(value)
|
|
showCopyResult(`${label} copied`, 'success')
|
|
} catch (error) {
|
|
console.error('[Mail][RecipientDetails] Failed to copy text:', error)
|
|
showCopyResult(`Unable to copy ${label.toLowerCase()}`, 'error')
|
|
}
|
|
}
|
|
|
|
const handleCompose = () => {
|
|
if (!props.address) {
|
|
return
|
|
}
|
|
|
|
mailUiStore.openComposer(props.address, ComposerMode.Fresh)
|
|
}
|
|
|
|
const handleClick = () => {
|
|
emit('clicked')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<v-menu
|
|
:open-on-hover="true"
|
|
:open-on-click="false"
|
|
:open-delay="1000"
|
|
location="bottom start"
|
|
transition="slide-y-transition"
|
|
>
|
|
<template #activator="{ props: activatorProps }">
|
|
<span
|
|
v-bind="activatorProps"
|
|
class="address-activator"
|
|
@click="handleClick"
|
|
>
|
|
<slot
|
|
:label="displayLabel"
|
|
:name="recipientLabel"
|
|
:email="recipientAddress"
|
|
>
|
|
{{ displayLabel }}
|
|
</slot>
|
|
</span>
|
|
</template>
|
|
|
|
<v-card class="address-card" elevation="8" rounded="lg">
|
|
<div class="address-card-header">
|
|
<v-avatar size="40" color="primary">
|
|
<span class="text-white text-subtitle-2">
|
|
{{ displayLabel[0]?.toUpperCase() || 'U' }}
|
|
</span>
|
|
</v-avatar>
|
|
|
|
<div class="address-card-meta">
|
|
<div class="text-subtitle-2 font-weight-medium">{{ displayLabel }}</div>
|
|
<div v-if="recipientAddress" class="text-body-2 text-medium-emphasis">{{ recipientAddress }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<v-divider class="my-3" />
|
|
|
|
<div class="address-card-actions">
|
|
<v-btn
|
|
class="address-action-button"
|
|
size="small"
|
|
variant="tonal"
|
|
prepend-icon="mdi-pencil"
|
|
:disabled="!hasEmail"
|
|
@click="handleCompose"
|
|
>
|
|
Send Email
|
|
</v-btn>
|
|
<v-btn
|
|
class="address-action-button"
|
|
size="small"
|
|
variant="text"
|
|
:disabled="!hasEmail"
|
|
@click="copy(recipientAddress, 'Email address')"
|
|
>
|
|
<v-icon>mdi-content-copy</v-icon>
|
|
<v-tooltip activator="parent" location="bottom">Copy Email</v-tooltip>
|
|
</v-btn>
|
|
<v-btn
|
|
class="address-action-button"
|
|
size="small"
|
|
variant="text"
|
|
:disabled="!formattedAddress"
|
|
@click="copy(formattedAddress, 'Address')"
|
|
>
|
|
<v-icon>mdi-card-account-details-outline</v-icon>
|
|
<v-tooltip activator="parent" location="bottom">Copy Address</v-tooltip>
|
|
</v-btn>
|
|
<v-btn
|
|
v-if="recipientLabel"
|
|
class="address-action-button"
|
|
size="small"
|
|
variant="text"
|
|
@click="copy(recipientLabel, 'Name')"
|
|
>
|
|
<v-icon>mdi-account-outline</v-icon>
|
|
<v-tooltip activator="parent" location="bottom">Copy Name</v-tooltip>
|
|
</v-btn>
|
|
</div>
|
|
</v-card>
|
|
</v-menu>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.address-activator {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.address-card {
|
|
width: min(320px, calc(100vw - 32px));
|
|
padding: 16px;
|
|
}
|
|
|
|
.address-card-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.address-card-meta {
|
|
min-width: 0;
|
|
}
|
|
|
|
.address-card-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.address-card-actions :deep(.address-action-button) {
|
|
height: 36px;
|
|
min-height: 36px;
|
|
width: 36px;
|
|
min-width: 36px;
|
|
padding: 0;
|
|
}
|
|
|
|
.address-card-actions :deep(.address-action-button:first-child) {
|
|
width: auto;
|
|
min-width: 0;
|
|
padding-inline: 12px;
|
|
}
|
|
</style> |