Port modular price, product, and PWA fixes into boursecu
Sync live quote handling, SSE product images, store hours, file URL normalization, PWA icon cache, TV monitor, about software, SuperAdmin menu gates, price alerts, and related UX from modular while preserving boursecu branding and config constraints. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+103
-20
@@ -2,6 +2,65 @@
|
||||
<html lang="fa" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
var icon = ''
|
||||
try {
|
||||
icon = localStorage.getItem('PWA_INSTALL_ICON_URL') || ''
|
||||
} catch (e) {}
|
||||
var title = ''
|
||||
try {
|
||||
var raw = localStorage.getItem('PWA_MANIFEST_CACHE_V5')
|
||||
if (raw) {
|
||||
var payload = JSON.parse(raw)
|
||||
var manifest = payload && payload.manifest
|
||||
if (manifest) {
|
||||
title = manifest.short_name || manifest.name || ''
|
||||
if (!icon && manifest.icons && manifest.icons.length) {
|
||||
var icons = manifest.icons
|
||||
var pick = function (size) {
|
||||
var target = size + 'x' + size
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
if (String(icons[i].sizes || '').indexOf(target) !== -1 && icons[i].src) {
|
||||
return icons[i].src
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
icon = pick(180) || pick(192) || pick(512) || (icons[0] && icons[0].src) || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
if (title) {
|
||||
document.title = title
|
||||
var appleTitle = document.createElement('meta')
|
||||
appleTitle.name = 'apple-mobile-web-app-title'
|
||||
appleTitle.content = title
|
||||
document.head.appendChild(appleTitle)
|
||||
}
|
||||
if (icon) {
|
||||
var sized = document.createElement('link')
|
||||
sized.rel = 'apple-touch-icon'
|
||||
sized.setAttribute('data-dynamic-pwa', 'true')
|
||||
sized.setAttribute('data-pwa-icon-src', icon)
|
||||
sized.setAttribute('sizes', '180x180')
|
||||
sized.href = icon
|
||||
document.head.appendChild(sized)
|
||||
var primary = document.createElement('link')
|
||||
primary.rel = 'apple-touch-icon'
|
||||
primary.setAttribute('data-dynamic-pwa', 'true')
|
||||
primary.setAttribute('data-pwa-icon-src', icon)
|
||||
primary.href = icon
|
||||
document.head.appendChild(primary)
|
||||
var img = new Image()
|
||||
img.decoding = 'async'
|
||||
img.src = icon
|
||||
}
|
||||
} catch (e) {}
|
||||
})()
|
||||
</script>
|
||||
<meta name="enamad" content="44889195" />
|
||||
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
@@ -343,30 +402,49 @@
|
||||
return window.location.protocol === 'https:' ? 'https:' : 'http:'
|
||||
}
|
||||
|
||||
function getVersionUrls() {
|
||||
var protocol = getProtocol()
|
||||
function resolveTenantDomain() {
|
||||
var host = String(window.location.hostname || '').trim()
|
||||
if (!host || host === 'localhost' || host === '127.0.0.1') {
|
||||
return 'k.montzar.ir'
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
function getSuperAdminBases() {
|
||||
return [
|
||||
'https://nerkh.gold/get_version',
|
||||
'https://tablo.talasevin.ir/get_version',
|
||||
'https://abshode-service.montgit.ir/server/get_version',
|
||||
protocol + '//212.23.201.173:8381/get_version',
|
||||
protocol + '//91.212.174.137:4040/server/get_version'
|
||||
'https://adm.montzar.ir',
|
||||
'https://adm.montech.ir',
|
||||
'https://adm.montest.ir'
|
||||
]
|
||||
}
|
||||
|
||||
function getVersionUrls() {
|
||||
var domain = encodeURIComponent(resolveTenantDomain())
|
||||
return getSuperAdminBases().map(function (base) {
|
||||
return base + '/get_version?domain=' + domain
|
||||
})
|
||||
}
|
||||
|
||||
function getConfigUrls() {
|
||||
var protocol = getProtocol()
|
||||
|
||||
return [
|
||||
protocol + '//nerkh.gold/get_user',
|
||||
protocol + '//tablo.talasevin.ir/get_user',
|
||||
protocol + '//abshode-service.montgit.ir/server/get_user',
|
||||
protocol + '//212.23.201.173:8381/get_user',
|
||||
protocol + '//91.212.174.137:4040/server/get_user'
|
||||
]
|
||||
var domain = encodeURIComponent(resolveTenantDomain())
|
||||
return getSuperAdminBases().map(function (base) {
|
||||
return base + '/get_user?domain=' + domain
|
||||
})
|
||||
}
|
||||
|
||||
// پاککردن URL موفقیت قدیمی رجیستری (مثل nerkh.gold)
|
||||
;(function clearLegacyConfigSuccess() {
|
||||
var last = localStorage.getItem(CONFIG_SUCCESS_URL_KEY)
|
||||
if (!last) return
|
||||
var ok = getSuperAdminBases().some(function (base) {
|
||||
return last.indexOf(base) === 0
|
||||
})
|
||||
if (!ok) {
|
||||
localStorage.removeItem(CONFIG_SUCCESS_URL_KEY)
|
||||
document.cookie = CONFIG_COOKIE_NAME + '=; Path=/; Max-Age=0; SameSite=Lax'
|
||||
}
|
||||
})()
|
||||
|
||||
function sortVersionUrls(urls) {
|
||||
var lastSuccessUrl = localStorage.getItem(VERSION_SUCCESS_URL_KEY)
|
||||
|
||||
@@ -382,6 +460,11 @@
|
||||
function sortByLastSuccess(urls) {
|
||||
var lastSuccessUrl = localStorage.getItem(CONFIG_SUCCESS_URL_KEY)
|
||||
|
||||
if (lastSuccessUrl && urls.indexOf(lastSuccessUrl) === -1) {
|
||||
localStorage.removeItem(CONFIG_SUCCESS_URL_KEY)
|
||||
lastSuccessUrl = null
|
||||
}
|
||||
|
||||
return urls.slice().sort(function (a, b) {
|
||||
if (a === lastSuccessUrl) return -1
|
||||
if (b === lastSuccessUrl) return 1
|
||||
@@ -665,10 +748,10 @@
|
||||
'<div style="font-size: 42px; margin-bottom: 12px;">⚠️</div>' +
|
||||
'<h2 style="margin: 0 0 12px; font-size: 20px;">خطا در بارگذاری برنامه</h2>' +
|
||||
'<p style="margin: 0 0 20px; color: var(--boot-muted); line-height: 2; font-size: 14px;">' +
|
||||
'ارتباط با سرور برقرار نشد یا فایلهای برنامه بهدرستی دریافت نشدند.' +
|
||||
'برقراری ارتباط با سرور امکانپذیر نیست. لطفاً اتصال اینترنت خود را بررسی کرده و صفحه را تازهسازی نمایید.' +
|
||||
'</p>' +
|
||||
'<button onclick="window.__APP_BOOT_SIMPLE_RETRY__()" style="padding: 11px 22px; border: 0; border-radius: 12px; background: var(--boot-accent); color: white; cursor: pointer; font-weight: 700;">' +
|
||||
'تلاش مجدد' +
|
||||
'تازهسازی صفحه' +
|
||||
'</button>' +
|
||||
'<button onclick="window.__APP_BOOT_CLEAN_RELOAD__()" style="margin-right: 8px; padding: 11px 18px; border: 1px solid var(--boot-border); border-radius: 12px; background: transparent; color: var(--boot-text); cursor: pointer; font-weight: 700;">' +
|
||||
'پاکسازی و تلاش مجدد' +
|
||||
@@ -680,8 +763,8 @@
|
||||
async function cleanFetchAndReload() {
|
||||
renderRecovering('در حال دریافت تنظیمات جدید برنامه...')
|
||||
|
||||
var version = await loadRemoteVersion(5)
|
||||
var freshConfigResult = await fetchFreshConfig(5)
|
||||
var version = await loadRemoteVersion(3)
|
||||
var freshConfigResult = await fetchFreshConfig(3)
|
||||
|
||||
clearReadableCookies()
|
||||
// clearLocalStorageExceptToken()
|
||||
|
||||
Reference in New Issue
Block a user