Web 端本地缓存、首页与会员弹窗体验优化
新增 IndexedDB 与最近文件 L1 缓存、云保存/打开链路;首页支持下载与清空本地缓存;修复清空 storage 后语言初始化报错;优化 design2 背景加载与侧栏标签样式;完善会员激活/支付弹层样式;后端补充文件缩略图字段与 thumb 接口。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -38,4 +38,122 @@
|
||||
var n = String(rel || '').replace(/^\/+/, '');
|
||||
return window.SOON_JS_BASE + n;
|
||||
};
|
||||
|
||||
/** 等 HTMLImage 解码完成后再 toDataURL / setSrc,避免间歇性空白背景 */
|
||||
window.soonFabricImageWhenReady = function (image, cb, skipEmbed) {
|
||||
if (!image) {
|
||||
if (typeof cb === 'function') cb(null);
|
||||
return;
|
||||
}
|
||||
function finalize() {
|
||||
if (skipEmbed) {
|
||||
if (typeof cb === 'function') cb(image);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var dataUrl = image.toDataURL();
|
||||
if (dataUrl && dataUrl.length > 500) {
|
||||
image.setSrc(dataUrl, function (img) {
|
||||
if (typeof cb === 'function') cb(img || image);
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
if (typeof cb === 'function') cb(image);
|
||||
}
|
||||
var el = image.getElement ? image.getElement() : null;
|
||||
if (!el) {
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
if (el.complete && el.naturalWidth > 0) {
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
el.onload = function () { finalize(); };
|
||||
el.onerror = function () {
|
||||
if (typeof cb === 'function') cb(null);
|
||||
};
|
||||
};
|
||||
|
||||
window.soonFabricImageFromAsset = function (assetName, onReady, onFail, retryLeft, skipEmbed) {
|
||||
if (typeof fabric === 'undefined' || !fabric.Image) {
|
||||
if (typeof onFail === 'function') onFail();
|
||||
return;
|
||||
}
|
||||
var retries = retryLeft == null ? 2 : retryLeft;
|
||||
var url = window.soonAsset(assetName);
|
||||
fabric.Image.fromURL(url, function (image) {
|
||||
if (!image || !image.width) {
|
||||
if (retries > 0) {
|
||||
setTimeout(function () {
|
||||
window.soonFabricImageFromAsset(assetName, onReady, onFail, retries - 1, skipEmbed);
|
||||
}, 150);
|
||||
return;
|
||||
}
|
||||
if (typeof onFail === 'function') onFail();
|
||||
return;
|
||||
}
|
||||
function deliver(img) {
|
||||
if (img && typeof onReady === 'function') onReady(img);
|
||||
else if (retries > 0) {
|
||||
setTimeout(function () {
|
||||
window.soonFabricImageFromAsset(assetName, onReady, onFail, retries - 1, skipEmbed);
|
||||
}, 150);
|
||||
} else if (typeof onFail === 'function') onFail();
|
||||
}
|
||||
if (skipEmbed) {
|
||||
window.soonFabricImageWhenReady(image, deliver, true);
|
||||
return;
|
||||
}
|
||||
window.soonFabricImageWhenReady(image, deliver);
|
||||
}, null, { crossOrigin: 'anonymous' });
|
||||
};
|
||||
|
||||
window.soonRunWhenCanvasReady = function (selector, fn) {
|
||||
function tryRun() {
|
||||
var el = typeof selector === 'string' ? document.querySelector(selector) : selector;
|
||||
var w = el ? (el.clientWidth || el.width || 0) : 0;
|
||||
if ((!w || w < 50) && window.SOON_DEPLOY_CONFIG) {
|
||||
requestAnimationFrame(function () {
|
||||
requestAnimationFrame(tryRun);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (typeof fn === 'function') fn(w || 800);
|
||||
}
|
||||
tryRun();
|
||||
};
|
||||
|
||||
var SOON_LOCALE_CODES = { zh: 1, ozh: 1, en: 1 };
|
||||
|
||||
window.soonNormalizeLocaleCode = function (loc) {
|
||||
if (!loc) return 'zh';
|
||||
if (SOON_LOCALE_CODES[loc]) return loc;
|
||||
var s = String(loc);
|
||||
if (s.indexOf('zh') === 0) return s.indexOf('TW') >= 0 ? 'ozh' : 'zh';
|
||||
return 'en';
|
||||
};
|
||||
|
||||
window.soonResolveLocale = function (cb) {
|
||||
if (typeof cb !== 'function') return;
|
||||
var stored;
|
||||
try { stored = localStorage.getItem('lang'); } catch (e) { stored = null; }
|
||||
if (stored && SOON_LOCALE_CODES[stored]) {
|
||||
cb(stored);
|
||||
return;
|
||||
}
|
||||
var bridge = window.platformBridge;
|
||||
if (!bridge || typeof bridge.getLocale !== 'function') {
|
||||
cb('zh');
|
||||
return;
|
||||
}
|
||||
var ret;
|
||||
try { ret = bridge.getLocale(); } catch (e) { cb('zh'); return; }
|
||||
if (ret && typeof ret.then === 'function') {
|
||||
ret.then(function (loc) { cb(window.soonNormalizeLocaleCode(loc)); }).catch(function () { cb('zh'); });
|
||||
return;
|
||||
}
|
||||
cb(window.soonNormalizeLocaleCode(ret));
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user