fix support issue 2
This commit is contained in:
@@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
import { getNameAvatarInitials } from '@/utils/avatarInitials'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
title: string
|
title: string
|
||||||
@@ -61,10 +62,7 @@ defineEmits<{
|
|||||||
(e: 'toggle-mobile-list'): void
|
(e: 'toggle-mobile-list'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const titleInitial = computed(() => {
|
const titleInitial = computed(() => getNameAvatarInitials(props.title))
|
||||||
const value = String(props.title || '').trim()
|
|
||||||
return value ? value.charAt(0) : '؟'
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@@ -132,6 +130,9 @@ const titleInitial = computed(() => {
|
|||||||
|
|
||||||
.admin-support-header__avatar-text {
|
.admin-support-header__avatar-text {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-support-header__online {
|
.admin-support-header__online {
|
||||||
|
|||||||
@@ -75,9 +75,7 @@
|
|||||||
:class="message.sender === 'admin' ? 'admin-message-row__inner--out' : ''"
|
:class="message.sender === 'admin' ? 'admin-message-row__inner--out' : ''"
|
||||||
>
|
>
|
||||||
<div v-if="message.sender === 'user'" class="admin-message-avatar">
|
<div v-if="message.sender === 'user'" class="admin-message-avatar">
|
||||||
<span class="text-xs font-bold flex items-center justify-center">
|
<span class="admin-message-avatar__text">{{ userAvatarText }}</span>
|
||||||
<BaseIcon icon="vuesax-linear:profile" />
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -231,7 +229,7 @@
|
|||||||
<div v-if="supportTyping" class="admin-message-row admin-message-row--in">
|
<div v-if="supportTyping" class="admin-message-row admin-message-row--in">
|
||||||
<div class="admin-message-row__inner">
|
<div class="admin-message-row__inner">
|
||||||
<div class="admin-message-avatar">
|
<div class="admin-message-avatar">
|
||||||
<span class="text-xs font-bold">U</span>
|
<span class="admin-message-avatar__text">{{ userAvatarText }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="admin-bubble admin-bubble--in">
|
<div class="admin-bubble admin-bubble--in">
|
||||||
@@ -252,6 +250,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, ref, watch, onBeforeUnmount } from 'vue'
|
import { computed, nextTick, ref, watch, onBeforeUnmount } from 'vue'
|
||||||
import type { SupportMessage, SupportMessageSender } from '@/model/support'
|
import type { SupportMessage, SupportMessageSender } from '@/model/support'
|
||||||
|
import { getNameAvatarInitials } from '@/utils/avatarInitials'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
messages: SupportMessage[]
|
messages: SupportMessage[]
|
||||||
@@ -260,6 +259,7 @@ const props = defineProps<{
|
|||||||
loadingOlder?: boolean
|
loadingOlder?: boolean
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
loadingLabel?: string
|
loadingLabel?: string
|
||||||
|
userName?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -268,6 +268,8 @@ const emit = defineEmits<{
|
|||||||
(e: 'bottom-state-change', value: boolean): void
|
(e: 'bottom-state-change', value: boolean): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const userAvatarText = computed(() => getNameAvatarInitials(props.userName || ''))
|
||||||
|
|
||||||
const scrollContainer = ref<HTMLElement | null>(null)
|
const scrollContainer = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
const isAtBottom = ref(true)
|
const isAtBottom = ref(true)
|
||||||
@@ -919,8 +921,11 @@ AdminSupport .admin-bubble__image-wrap {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
padding: 4px 0 8px;
|
/* نوار تمامعرض مات تا تاریخ بلند زیر «امروز/دیروز» از کنار دیده نشود */
|
||||||
margin-bottom: 4px;
|
width: 100%;
|
||||||
|
padding: 8px 0;
|
||||||
|
margin: 0 0 4px;
|
||||||
|
background: var(--admin-bg-subtle, #fafafa);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-day-chip {
|
.admin-day-chip {
|
||||||
@@ -999,11 +1004,18 @@ AdminSupport .admin-bubble__image-wrap {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid #e5e7eb;
|
border: 1px solid #e5e7eb;
|
||||||
background: #fff;
|
background: color-mix(in srgb, var(--admin-gold-light, #2563eb) 14%, #fff);
|
||||||
color: #3f3f46;
|
color: var(--admin-gold-light, #2563eb);
|
||||||
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.06);
|
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin-message-avatar__text {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
.admin-bubble {
|
.admin-bubble {
|
||||||
min-width: 110px;
|
min-width: 110px;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
@@ -1144,26 +1156,35 @@ AdminSupport .admin-bubble__image-wrap {
|
|||||||
min-width: 10rem;
|
min-width: 10rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin-bottom: 9px;
|
margin-bottom: 10px;
|
||||||
padding: 8px 10px;
|
padding: 9px 11px;
|
||||||
border-radius: 14px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-bubble--out .admin-message__reply {
|
.admin-bubble--out .admin-message__reply {
|
||||||
background: rgba(255, 255, 255, 0.14);
|
background: rgba(255, 255, 255, 0.22);
|
||||||
|
border-color: rgba(255, 255, 255, 0.28);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-bubble--in .admin-message__reply {
|
.admin-bubble--in .admin-message__reply {
|
||||||
background: #f4f7ff;
|
background: #f4f4f5;
|
||||||
|
border-color: #e4e4e7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-message__reply-line {
|
.admin-message__reply-line {
|
||||||
width: 3px;
|
width: 3px;
|
||||||
flex: 0 0 3px;
|
flex: 0 0 3px;
|
||||||
|
align-self: stretch;
|
||||||
|
min-height: 28px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: currentColor;
|
background: var(--colorPrimary, #2563eb);
|
||||||
opacity: 0.75;
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-bubble--out .admin-message__reply-line {
|
||||||
|
background: rgba(255, 255, 255, 0.92);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-message__reply-content {
|
.admin-message__reply-content {
|
||||||
@@ -1189,7 +1210,7 @@ AdminSupport .admin-bubble__image-wrap {
|
|||||||
unicode-bidi: plaintext;
|
unicode-bidi: plaintext;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
opacity: 0.86;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-bubble--out .admin-message__reply-title,
|
.admin-bubble--out .admin-message__reply-title,
|
||||||
@@ -1864,6 +1885,10 @@ html.is-dark .admin-messages::-webkit-scrollbar-thumb {
|
|||||||
|
|
||||||
html.is-dark .admin-messages-loading,
|
html.is-dark .admin-messages-loading,
|
||||||
html.is-dark .admin-jump-bottom,
|
html.is-dark .admin-jump-bottom,
|
||||||
|
html.is-dark .admin-day-sticky {
|
||||||
|
background: var(--admin-bg-subtle, #18181b);
|
||||||
|
}
|
||||||
|
|
||||||
html.is-dark .admin-day-chip {
|
html.is-dark .admin-day-chip {
|
||||||
color: var(--admin-text-muted);
|
color: var(--admin-text-muted);
|
||||||
border-color: var(--admin-border);
|
border-color: var(--admin-border);
|
||||||
@@ -1939,6 +1964,15 @@ html.is-dark .admin-reply-swipe-cue {
|
|||||||
html.is-dark .admin-bubble--in .admin-message__reply,
|
html.is-dark .admin-bubble--in .admin-message__reply,
|
||||||
html.is-dark .admin-bubble--out .admin-message__reply {
|
html.is-dark .admin-bubble--out .admin-message__reply {
|
||||||
background: var(--admin-bg-muted) !important;
|
background: var(--admin-bg-muted) !important;
|
||||||
|
border-color: var(--admin-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.is-dark .admin-bubble--in .admin-message__reply-line {
|
||||||
|
background: var(--admin-gold-light, var(--colorPrimary, #2563eb)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.is-dark .admin-bubble--out .admin-message__reply-line {
|
||||||
|
background: rgba(255, 255, 255, 0.85) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.is-dark .admin-bubble--in .admin-message__reply-title {
|
html.is-dark .admin-bubble--in .admin-message__reply-title {
|
||||||
|
|||||||
@@ -140,6 +140,7 @@
|
|||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import type { SupportConversation } from '@/model/support'
|
import type { SupportConversation } from '@/model/support'
|
||||||
import BasicInput from '@/components/BasicInput.vue'
|
import BasicInput from '@/components/BasicInput.vue'
|
||||||
|
import { getNameAvatarInitials } from '@/utils/avatarInitials'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
conversations: SupportConversation[]
|
conversations: SupportConversation[]
|
||||||
@@ -180,10 +181,7 @@ const totalUnread = computed(() => {
|
|||||||
}, 0)
|
}, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getAvatarText = (name: string) => {
|
const getAvatarText = (name: string) => getNameAvatarInitials(name, 'ک')
|
||||||
const value = String(name || 'ک').trim()
|
|
||||||
return value.slice(0, 1)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@@ -483,8 +481,10 @@ const getAvatarText = (name: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.admin-room-card__avatar-text {
|
.admin-room-card__avatar-text {
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
font-weight: 950;
|
font-weight: 950;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-room-card__online {
|
.admin-room-card__online {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
:loading-older="activeLoadingOlder"
|
:loading-older="activeLoadingOlder"
|
||||||
:loading="activeRoomLoading"
|
:loading="activeRoomLoading"
|
||||||
:loading-label="activeLoadingLabel"
|
:loading-label="activeLoadingLabel"
|
||||||
|
:user-name="activeConversation.userName"
|
||||||
@load-older="loadOlderMessages"
|
@load-older="loadOlderMessages"
|
||||||
@reply="handleReplyMessage"
|
@reply="handleReplyMessage"
|
||||||
@bottom-state-change="handleBottomStateChange"
|
@bottom-state-change="handleBottomStateChange"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const support: RouteRecordRaw = {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
hideMenu: false,
|
hideMenu: false,
|
||||||
hideChildren: true,
|
hideChildren: true,
|
||||||
order: 11,
|
order: 7.5,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/** دو حرف از اسم و فامیل برای آواتار (اولِ نام + اولِ نامخانوادگی) */
|
||||||
|
export function getNameAvatarInitials(name: string, fallback = '؟'): string {
|
||||||
|
const parts = String(name || '')
|
||||||
|
.trim()
|
||||||
|
.split(/\s+/)
|
||||||
|
.filter(Boolean)
|
||||||
|
|
||||||
|
if (!parts.length) return fallback
|
||||||
|
|
||||||
|
const firstChars = (word: string) => Array.from(word)
|
||||||
|
|
||||||
|
if (parts.length === 1) {
|
||||||
|
const chars = firstChars(parts[0])
|
||||||
|
if (!chars.length) return fallback
|
||||||
|
return chars.slice(0, 2).join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
const first = firstChars(parts[0])[0] || ''
|
||||||
|
const last = firstChars(parts[parts.length - 1])[0] || ''
|
||||||
|
const initials = `${first}${last}`.trim()
|
||||||
|
return initials || fallback
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user