Files
ghatreh_user/src/composables/usePwaInstall.ts
T

133 lines
3.3 KiB
TypeScript

import { computed, onMounted, ref } from 'vue'
import type { PwaPlatform } from '@/modules/pwa/pwaInstallGuideSteps'
import {
getDefaultPwaPlatform,
initPwaInstallPromptListener,
isPwaInstallBannerDismissed,
markPwaInstallBannerAsShown,
shouldOfferPwaInstall,
shouldShowPwaInstallPrompt,
triggerNativePwaInstall,
} from '@/modules/pwa/pwaInstall'
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) {
if (!offerInstall.value) return
consumeInstallBanner()
platform.value = nextPlatform ?? getDefaultPwaPlatform()
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) {
if (!offerInstall.value) return false
const installed = await triggerNativePwaInstall()
if (installed) {
offerInstall.value = false
consumeInstallBanner()
return true
}
openGuide(nextPlatform)
return false
}
return {
guideOpen,
bannerVisible,
platform,
canPrompt,
showInstallEntry,
openGuide,
closeGuide,
showBanner,
hideBanner,
dismissBanner,
completeGuide,
tryInstallOrOpenGuide,
}
}