Files
boursecu_user/src/composables/usePwaInstall.ts
T
safavimohadeseh78andCursor 5920866a95 fix(ui): repair PWA install, credit footer, and boursecu copy
Make install guide and BasicButton clicks reliable, align montzar credit bar, remove calculator quick action, and use مس in about-software default text.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 13:53:10 -04:00

152 lines
4.0 KiB
TypeScript

import { computed, onMounted, ref } from 'vue'
import { message } from 'ant-design-vue'
import type { PwaPlatform } from '@/modules/pwa/pwaInstallGuideSteps'
import {
getDefaultPwaPlatform,
initPwaInstallPromptListener,
isPwaInstallBannerDismissed,
isStandalonePwa,
markPwaInstallBannerAsShown,
shouldOfferPwaInstall,
shouldShowPwaInstallPrompt,
triggerNativePwaInstall,
} from '@/modules/pwa/pwaInstall'
import { isTWA } from '@/utils/config'
const guideOpen = ref(false)
const bannerVisible = ref(false)
const platform = ref<PwaPlatform>(getDefaultPwaPlatform())
const installBannerConsumed = ref(isPwaInstallBannerDismissed())
/** false وقتی اپ به‌صورت PWA/TWA باز شده یا همین الان نصب شده */
const offerInstall = ref(shouldOfferPwaInstall())
let listenerReady = false
let offerListenersBound = false
function refreshOfferInstall() {
offerInstall.value = shouldOfferPwaInstall()
}
function bindOfferInstallListeners() {
if (offerListenersBound || typeof window === 'undefined') return
offerListenersBound = true
refreshOfferInstall()
const onInstalled = () => {
offerInstall.value = false
}
window.addEventListener('appinstalled', onInstalled)
const modes = ['standalone', 'fullscreen', 'minimal-ui', 'window-controls-overlay'] as const
const mediaLists = modes.map((mode) => window.matchMedia(`(display-mode: ${mode})`))
const onDisplayModeChange = () => refreshOfferInstall()
for (const mql of mediaLists) {
mql.addEventListener('change', onDisplayModeChange)
}
}
function ensureListener() {
if (listenerReady) return
listenerReady = true
initPwaInstallPromptListener()
bindOfferInstallListeners()
}
export function usePwaInstall() {
ensureListener()
onMounted(() => {
refreshOfferInstall()
})
const canPrompt = computed(() => {
if (installBannerConsumed.value) return false
return shouldShowPwaInstallPrompt()
})
const showInstallEntry = computed(() => offerInstall.value)
function consumeInstallBanner() {
if (installBannerConsumed.value) return
markPwaInstallBannerAsShown()
installBannerConsumed.value = true
bannerVisible.value = false
}
function openGuide(nextPlatform?: PwaPlatform) {
refreshOfferInstall()
// فقط وقتی واقعاً داخل PWA/TWA هستیم راهنما را نشان نده
if (isStandalonePwa() || isTWA()) return
consumeInstallBanner()
const next = nextPlatform === 'ios' || nextPlatform === 'android'
? nextPlatform
: getDefaultPwaPlatform()
platform.value = next
guideOpen.value = true
}
function closeGuide() {
guideOpen.value = false
}
function showBanner() {
if (!canPrompt.value) return
bannerVisible.value = true
markPwaInstallBannerAsShown()
installBannerConsumed.value = true
}
function hideBanner() {
bannerVisible.value = false
}
function dismissBanner() {
consumeInstallBanner()
}
async function completeGuide() {
await triggerNativePwaInstall()
consumeInstallBanner()
closeGuide()
}
/** نصب مستقیم مرورگر؛ اگر ممکن نبود مدال آموزش. */
async function tryInstallOrOpenGuide(nextPlatform?: PwaPlatform) {
ensureListener()
refreshOfferInstall()
if (isStandalonePwa() || isTWA()) {
message.info('نسخه وب‌اپ از قبل نصب شده است')
offerInstall.value = false
return false
}
const installed = await triggerNativePwaInstall()
if (installed) {
offerInstall.value = false
consumeInstallBanner()
message.success('نصب وب‌اپ آغاز شد')
return true
}
// Chrome روی HTTP/IP یا Safari معمولاً prompt بومی ندارد — راهنما را باز کن
openGuide(nextPlatform)
return false
}
return {
guideOpen,
bannerVisible,
platform,
canPrompt,
showInstallEntry,
openGuide,
closeGuide,
showBanner,
hideBanner,
dismissBanner,
completeGuide,
tryInstallOrOpenGuide,
}
}