Add web app install button and step-by-step PWA guide.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { computed, onMounted, ref } from '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()
|
||||
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) {
|
||||
refreshOfferInstall()
|
||||
if (isStandalonePwa() || isTWA()) 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user