added chat 2

This commit is contained in:
2026-07-30 18:33:08 +03:30
parent 106b0ebbdf
commit 5b0bb45e52
21 changed files with 5243 additions and 25 deletions
+34 -3
View File
@@ -38,10 +38,10 @@
>
<Icon icon="vuesax-linear:menu" size="18" />
<span
v-if="notificationEnabled && unreadCount > 0"
v-if="menuBadgeCount > 0"
class="mhome-header-menu__badge"
>
{{ unreadCount > 99 ? '99+' : unreadCount }}
{{ menuBadgeCount > 99 ? '99+' : menuBadgeCount }}
</span>
</button>
@@ -73,6 +73,22 @@
<span>{{ canNativeInstall ? 'نصب اپلیکیشن' : 'آموزش نصب' }}</span>
</button>
<button
v-if="chatEnabled"
type="button"
class="mhome-header-menu__item"
role="menuitem"
@click="goSupportChat"
>
<span class="mhome-header-btn__icon-wrap">
<Icon icon="vuesax-linear:messages-2" size="16" />
<span v-if="chatUnreadCount > 0" class="mhome-header-btn__badge">
{{ chatUnreadCount > 99 ? '99+' : chatUnreadCount }}
</span>
</span>
<span>چت پشتیبانی</span>
</button>
<button
type="button"
class="mhome-header-menu__item mhome-header-menu__item--danger"
@@ -90,9 +106,10 @@
</template>
<script setup lang="ts">
import { nextTick, onActivated, onMounted, onUnmounted, ref, watch } from 'vue'
import { nextTick, onActivated, onMounted, onUnmounted, ref, watch, computed } from 'vue'
import { useRoute } from 'vue-router'
import { useUserStore } from '@/store/userStore'
import { useSettingsStore } from '@/store/settingsStore'
import { useAppNotificationBadge } from '@/composables/useAppNotificationBadge'
import { usePwaInstall } from '@/composables/usePwaInstall'
import { PWA_MANIFEST_READY_EVENT } from '@/modules/pwa/manifest'
@@ -106,6 +123,7 @@ import {
} from '@/utils/browserNotification'
import router from '@/router'
import Icon from '@/components/BasicPacks/BasicIcon.vue'
import { unreadSupportCount, isUserSupportChatEnabled } from '@/utils/chat'
const emit = defineEmits<{
logout: []
@@ -119,11 +137,19 @@ const canNativeInstall = ref(false)
const route = useRoute()
const userStore = useUserStore()
const settingsStore = useSettingsStore()
const chatEnabled = computed(() => isUserSupportChatEnabled())
const chatUnreadCount = computed(() => unreadSupportCount.value)
const {
enabled: notificationEnabled,
unreadCount,
clearUnreadLocally,
} = useAppNotificationBadge()
const menuBadgeCount = computed(() => {
const notifications = notificationEnabled.value ? Number(unreadCount.value) || 0 : 0
const chat = chatEnabled.value ? Number(chatUnreadCount.value) || 0 : 0
return notifications + chat
})
const { tryInstallOrOpenGuide, showInstallEntry } = usePwaInstall()
function refreshCanInstall() {
@@ -143,6 +169,11 @@ async function goNotifications() {
void router.push({ name: 'appNotifications' })
}
function goSupportChat() {
closeMenu()
void router.push({ name: 'support' })
}
async function onInstall() {
closeMenu()
await tryInstallOrOpenGuide()
@@ -15,6 +15,8 @@ import { useUserStore } from '@/store/userStore'
import { useWalletStore } from '@/store/walletStore'
import { useTrackingSystemsFeature } from '@/composables/useTrackingSystemsFeature'
import { useSettingsStore } from '@/store/settingsStore'
import { useSupportMessenger } from '@/composables/useSupportMessenger'
import { isUserSupportChatEnabled, unreadSupportCount } from '@/utils/chat'
export interface UserMenuAction {
id: string
@@ -22,6 +24,7 @@ export interface UserMenuAction {
icon: string
onClick: () => void
visible?: boolean
badge?: number
}
export interface UserPageContext {
@@ -70,6 +73,7 @@ export function useUserPage() {
const showLogoutConfirm = ref(false)
const { trackingSystemsEnabled } = useTrackingSystemsFeature()
const settingsStore = useSettingsStore()
const { openSupportMessenger } = useSupportMessenger()
const isLegal = computed(() => {
const result = { title: '', color: '', icon: '' }
@@ -114,6 +118,16 @@ export function useUserPage() {
onClick: () => router.push({ name: 'about' }),
visible: true,
},
{
id: 'support',
label: 'پشتیبانی',
icon: 'vuesax-linear:messages-2',
onClick: () => {
void openSupportMessenger()
},
visible: isUserSupportChatEnabled(),
badge: unreadSupportCount.value > 0 ? unreadSupportCount.value : undefined,
},
{
id: 'recoverySites',
label: 'سایت‌های ری‌گیری',
@@ -73,6 +73,12 @@
>
<span class="duser-actions__icon">
<BasicIcon :icon="action.icon" size="18" />
<span
v-if="action.badge && action.badge > 0"
class="duser-actions__badge"
>
{{ action.badge > 99 ? '99+' : action.badge }}
</span>
</span>
<span class="duser-actions__label">{{ action.label }}</span>
<BasicIcon class="duser-actions__chevron" icon="vuesax-linear:arrow-left" size="16" />
@@ -231,6 +231,7 @@
}
&__icon {
position: relative;
display: flex;
align-items: center;
justify-content: center;
@@ -248,6 +249,23 @@
}
}
&__badge {
position: absolute;
top: -6px;
left: -6px;
z-index: 1;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 999px;
background: #dc2626;
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 16px;
text-align: center;
}
&__icon-image {
width: 18px;
height: 18px;