fix some bugs 2
This commit is contained in:
@@ -7,7 +7,7 @@ function getProtocol() {
|
|||||||
return window.location.protocol === 'https:' ? 'https:' : 'http:'
|
return window.location.protocol === 'https:' ? 'https:' : 'http:'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConfigUrls() {
|
export function getConfigUrls() {
|
||||||
const protocol = getProtocol()
|
const protocol = getProtocol()
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -19,7 +19,7 @@ function getConfigUrls() {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortConfigUrls(urls: string[]) {
|
export function sortConfigUrls(urls: string[]) {
|
||||||
const lastSuccessUrl = localStorage.getItem(CONFIG_SUCCESS_URL_KEY)
|
const lastSuccessUrl = localStorage.getItem(CONFIG_SUCCESS_URL_KEY)
|
||||||
|
|
||||||
return [...urls].sort((a, b) => {
|
return [...urls].sort((a, b) => {
|
||||||
|
|||||||
+39
-31
@@ -1,5 +1,6 @@
|
|||||||
import type { AppConfig } from '@/config/types'
|
import type { AppConfig } from '@/config/types'
|
||||||
import { getConfig, getRawAppConfig } from '@/config/app-config'
|
import { getConfig, getRawAppConfig } from '@/config/app-config'
|
||||||
|
import { getConfigUrls, sortConfigUrls } from '@/config/load-config'
|
||||||
import {
|
import {
|
||||||
clearCachedPwaManifest,
|
clearCachedPwaManifest,
|
||||||
readCachedPwaManifest,
|
readCachedPwaManifest,
|
||||||
@@ -15,7 +16,6 @@ export const PWA_MANIFEST_READY_EVENT = 'pwa-manifest-ready'
|
|||||||
const CONFIG_SUCCESS_URL_KEY = 'CONFIG_Success_URL'
|
const CONFIG_SUCCESS_URL_KEY = 'CONFIG_Success_URL'
|
||||||
let pendingBeforeInstallPrompt: Event | null = null
|
let pendingBeforeInstallPrompt: Event | null = null
|
||||||
let installCaptureInitialized = false
|
let installCaptureInitialized = false
|
||||||
const MANIFEST_RETRY_COUNT = 5
|
|
||||||
const MANIFEST_RETRY_DELAY_MS = 500
|
const MANIFEST_RETRY_DELAY_MS = 500
|
||||||
|
|
||||||
function sleep(ms: number) {
|
function sleep(ms: number) {
|
||||||
@@ -33,22 +33,21 @@ export function getConfigBaseFromStorage() {
|
|||||||
return normalizeBaseUrl(lastSuccess)
|
return normalizeBaseUrl(lastSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** یک URL — فقط monifist همان tenant/user؛ بدون fallback عمومی */
|
function configUrlToManifestUrl(configUrl: string) {
|
||||||
export function resolveManifestUrl(config?: AppConfig | null) {
|
return `${configUrl.replace(/\/+$/, '')}/manifest.json`
|
||||||
const raw = config ?? getRawAppConfig()
|
}
|
||||||
const userId = raw?.user?.id
|
|
||||||
const base = getConfigBaseFromStorage()
|
|
||||||
|
|
||||||
if (!base) return ''
|
|
||||||
|
|
||||||
|
/** همان ۵ URL پایهٔ get_user — اولویت با CONFIG_Success_URL */
|
||||||
|
export function resolveManifestUrls(config?: AppConfig | null): string[] {
|
||||||
const explicit = getConfig<string>('manifest_url')
|
const explicit = getConfig<string>('manifest_url')
|
||||||
if (explicit) return explicit
|
if (explicit) return [explicit]
|
||||||
|
|
||||||
/* if (userId != null && userId !== '') {
|
return sortConfigUrls(getConfigUrls()).map(configUrlToManifestUrl)
|
||||||
return `${base}/get_user/${userId}/manifest.json`
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
return `${base}/get_user/manifest.json`
|
/** اولین کاندید — برای سازگاری */
|
||||||
|
export function resolveManifestUrl(config?: AppConfig | null) {
|
||||||
|
return resolveManifestUrls(config)[0] ?? ''
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidManifest(payload: unknown): payload is PwaManifest {
|
function isValidManifest(payload: unknown): payload is PwaManifest {
|
||||||
@@ -91,28 +90,33 @@ async function fetchManifestOnce(url: string, timeout = 6000): Promise<PwaManife
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** retry فقط روی همان URL — بدون درخواست دوم */
|
/** هر URL یک بار — مثل لوپ get_user */
|
||||||
async function fetchManifestWithRetry(url: string): Promise<PwaManifest> {
|
async function fetchManifestTryingUrls(
|
||||||
if (!url) {
|
urls: string[]
|
||||||
throw new Error('No manifest URL (config base or user id missing)')
|
): Promise<{ manifest: PwaManifest; manifestUrl: string }> {
|
||||||
|
if (!urls.length) {
|
||||||
|
throw new Error('No manifest URL candidates')
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastError: unknown = null
|
let lastError: unknown = null
|
||||||
|
|
||||||
for (let attempt = 1; attempt <= MANIFEST_RETRY_COUNT; attempt++) {
|
for (let index = 0; index < urls.length; index++) {
|
||||||
|
const url = urls[index]
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await fetchManifestOnce(url)
|
const manifest = await fetchManifestOnce(url)
|
||||||
|
return { manifest, manifestUrl: url }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
lastError = error
|
lastError = error
|
||||||
console.warn(`PWA manifest failed (${url}), attempt ${attempt}/${MANIFEST_RETRY_COUNT}`, error)
|
console.warn(`PWA manifest failed (${url}), candidate ${index + 1}/${urls.length}`, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attempt < MANIFEST_RETRY_COUNT) {
|
if (index < urls.length - 1) {
|
||||||
await sleep(MANIFEST_RETRY_DELAY_MS * attempt)
|
await sleep(MANIFEST_RETRY_DELAY_MS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw lastError ?? new Error('PWA manifest could not be loaded')
|
throw lastError ?? new Error('PWA manifest could not be loaded from any server')
|
||||||
}
|
}
|
||||||
|
|
||||||
let manifestBlobUrl: string | null = null
|
let manifestBlobUrl: string | null = null
|
||||||
@@ -229,6 +233,8 @@ function resolveInstallIcons(manifest: PwaManifest) {
|
|||||||
return mapped
|
return mapped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function prepareManifestForInstall(manifest: PwaManifest) {
|
function prepareManifestForInstall(manifest: PwaManifest) {
|
||||||
const scopeUrl = toSameOriginManifestUrl(manifest.scope ?? manifest.start_url, '/')
|
const scopeUrl = toSameOriginManifestUrl(manifest.scope ?? manifest.start_url, '/')
|
||||||
const startUrl = toSameOriginManifestUrl(manifest.start_url, '/')
|
const startUrl = toSameOriginManifestUrl(manifest.start_url, '/')
|
||||||
@@ -482,31 +488,30 @@ async function applyCachedManifestEntry(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* بعد از loadAppConfig / setAppConfig صدا بزن.
|
* بعد از loadAppConfig / setAppConfig صدا بزن.
|
||||||
* get_user دوباره fetch نمیشود — فقط monifist.json از base کششده.
|
* get_user دوباره fetch نمیشود — manifest از همان ۵ URL پایهٔ get_user امتحان میشود.
|
||||||
*/
|
*/
|
||||||
export async function setupPwaManifest(config?: AppConfig | null): Promise<boolean> {
|
export async function setupPwaManifest(config?: AppConfig | null): Promise<boolean> {
|
||||||
const raw = config ?? getRawAppConfig()
|
const raw = config ?? getRawAppConfig()
|
||||||
const userId = raw?.user?.id
|
const userId = raw?.user?.id
|
||||||
const configBase = getConfigBaseFromStorage()
|
const configBase = getConfigBaseFromStorage()
|
||||||
|
const manifestUrls = resolveManifestUrls(raw)
|
||||||
|
|
||||||
if (!configBase) {
|
if (!manifestUrls.length) {
|
||||||
console.warn('PWA manifest skipped: CONFIG_Success_URL not set yet')
|
console.warn('PWA manifest skipped: no manifest URL candidates')
|
||||||
removeDynamicManifestLinks()
|
removeDynamicManifestLinks()
|
||||||
setPwaManifestReady(false)
|
setPwaManifestReady(false)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const cached = readCachedPwaManifest(userId, configBase)
|
const cached = configBase ? readCachedPwaManifest(userId, configBase) : null
|
||||||
|
|
||||||
if (cached && (await applyCachedManifestEntry(cached))) {
|
if (cached && (await applyCachedManifestEntry(cached))) {
|
||||||
console.info('PWA manifest applied from cache:', cached.manifest_url)
|
console.info('PWA manifest applied from cache:', cached.manifest_url)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const manifestUrl = resolveManifestUrl(raw)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const manifest = await fetchManifestWithRetry(manifestUrl)
|
const { manifest, manifestUrl } = await fetchManifestTryingUrls(manifestUrls)
|
||||||
|
|
||||||
const prepared = prepareManifestForInstall(manifest)
|
const prepared = prepareManifestForInstall(manifest)
|
||||||
|
|
||||||
@@ -514,10 +519,13 @@ export async function setupPwaManifest(config?: AppConfig | null): Promise<boole
|
|||||||
setPwaManifestReady(true)
|
setPwaManifestReady(true)
|
||||||
|
|
||||||
if (userId != null && userId !== '') {
|
if (userId != null && userId !== '') {
|
||||||
|
const effectiveConfigBase =
|
||||||
|
configBase || normalizeBaseUrl(manifestUrl.replace(/\/manifest\.json$/i, ''))
|
||||||
|
|
||||||
writeCachedPwaManifest({
|
writeCachedPwaManifest({
|
||||||
cached_at: Date.now(),
|
cached_at: Date.now(),
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
config_base: configBase,
|
config_base: effectiveConfigBase,
|
||||||
manifest_url: manifestUrl,
|
manifest_url: manifestUrl,
|
||||||
manifest: prepared
|
manifest: prepared
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user