240 lines
6.3 KiB
JavaScript
240 lines
6.3 KiB
JavaScript
/**
|
||
* SDF1 App Shell
|
||
* — 启动 → 闪屏 → 加载 WebView → 错误重试
|
||
*/
|
||
|
||
(function () {
|
||
'use strict';
|
||
|
||
var MAIN_URL = 'https://caoyuan.ypshidifu.cn/plugin/player.php';
|
||
var SPLASH_MIN_DURATION = 2800; // 闪屏最少展示 2.8 秒
|
||
|
||
var splash = document.getElementById('splash');
|
||
var errorPage = document.getElementById('error-page');
|
||
var retryBtn = document.getElementById('retry-btn');
|
||
var webview = document.getElementById('main-webview');
|
||
var bottomBar = document.getElementById('bottom-bar');
|
||
|
||
var appReady = false;
|
||
var startTime = Date.now();
|
||
|
||
/* -------------------------------------------
|
||
1. 检测网络
|
||
------------------------------------------- */
|
||
function checkNetwork(callback) {
|
||
if (navigator.connection) {
|
||
var conn = navigator.connection;
|
||
if (conn.type === 'none' || conn.effectiveType === 'none') {
|
||
return callback(false);
|
||
}
|
||
}
|
||
// 简易 fetch 探测
|
||
fetch(MAIN_URL, { method: 'HEAD', mode: 'no-cors', cache: 'no-store' })
|
||
.then(function () { callback(true); })
|
||
.catch(function () { callback(false); });
|
||
}
|
||
|
||
/* -------------------------------------------
|
||
2. 初始化 WebView(HTML5+ 环境)
|
||
------------------------------------------- */
|
||
function initPlusWebView() {
|
||
if (typeof plus === 'undefined') {
|
||
// 浏览器调试模式:用 iframe 代替
|
||
var iframe = document.createElement('iframe');
|
||
iframe.src = MAIN_URL;
|
||
iframe.style.cssText = 'width:100%;height:100%;border:none;';
|
||
iframe.onload = onContentLoad;
|
||
iframe.onerror = function () { showError(); };
|
||
webview.innerHTML = '';
|
||
webview.appendChild(iframe);
|
||
return;
|
||
}
|
||
|
||
// ---- Plus 真机环境 ----
|
||
var wv = plus.webview.create(MAIN_URL, 'main', {
|
||
top: 0,
|
||
bottom: 0,
|
||
bounce: 'none',
|
||
progress: { color: '#c9a44a', height: '2px' },
|
||
useragent: { value: 'SDF1App/1.0', concat: true }
|
||
});
|
||
|
||
wv.addEventListener('loaded', onContentLoad);
|
||
wv.addEventListener('loadError', function (e) {
|
||
console.error('WebView load error:', e);
|
||
showError();
|
||
});
|
||
|
||
webview.appendChild(wv);
|
||
|
||
// 保持页面不被系统回收
|
||
plus.globalEvent.addEventListener('pause', function () {});
|
||
}
|
||
|
||
/* -------------------------------------------
|
||
3. 内容加载完成 → 隐藏闪屏
|
||
------------------------------------------- */
|
||
function onContentLoad() {
|
||
appReady = true;
|
||
var elapsed = Date.now() - startTime;
|
||
var remaining = Math.max(0, SPLASH_MIN_DURATION - elapsed);
|
||
|
||
setTimeout(function () {
|
||
splash.classList.add('fade-out');
|
||
errorPage.classList.add('hidden');
|
||
bottomBar.classList.remove('hidden');
|
||
|
||
setTimeout(function () {
|
||
splash.style.display = 'none';
|
||
}, 600);
|
||
}, remaining);
|
||
}
|
||
|
||
/* -------------------------------------------
|
||
4. 错误处理
|
||
------------------------------------------- */
|
||
function showError() {
|
||
splash.classList.add('fade-out');
|
||
setTimeout(function () {
|
||
splash.style.display = 'none';
|
||
}, 500);
|
||
errorPage.classList.remove('hidden');
|
||
bottomBar.classList.add('hidden');
|
||
}
|
||
|
||
function hideError() {
|
||
errorPage.classList.add('hidden');
|
||
}
|
||
|
||
/* -------------------------------------------
|
||
5. 底部导航事件
|
||
------------------------------------------- */
|
||
function setupBottomBar() {
|
||
var btns = bottomBar.querySelectorAll('.bar-btn');
|
||
btns.forEach(function (btn) {
|
||
btn.addEventListener('click', function () {
|
||
var action = btn.getAttribute('data-action');
|
||
|
||
// 切换 active 状态
|
||
btns.forEach(function (b) { b.classList.remove('active'); });
|
||
btn.classList.add('active');
|
||
|
||
if (action === 'refresh') {
|
||
reloadWebView();
|
||
} else if (action === 'back') {
|
||
goBack();
|
||
} else if (action === 'home') {
|
||
goHome();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function reloadWebView() {
|
||
if (typeof plus !== 'undefined') {
|
||
var wv = webview.children[0];
|
||
if (wv && wv.reload) {
|
||
wv.reload();
|
||
}
|
||
} else {
|
||
var iframe = webview.querySelector('iframe');
|
||
if (iframe) iframe.src = MAIN_URL;
|
||
}
|
||
}
|
||
|
||
function goBack() {
|
||
if (typeof plus !== 'undefined') {
|
||
var wv = webview.children[0];
|
||
if (wv && wv.canBack) {
|
||
wv.canBack(function (e) {
|
||
if (e.canBack) {
|
||
wv.back();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
function goHome() {
|
||
if (typeof plus !== 'undefined') {
|
||
var wv = webview.children[0];
|
||
if (wv) {
|
||
wv.loadURL(MAIN_URL);
|
||
}
|
||
} else {
|
||
var iframe = webview.querySelector('iframe');
|
||
if (iframe) iframe.src = MAIN_URL;
|
||
}
|
||
}
|
||
|
||
/* -------------------------------------------
|
||
6. 物理返回键拦截(Android)
|
||
------------------------------------------- */
|
||
function setupBackButton() {
|
||
if (typeof plus === 'undefined') return;
|
||
|
||
plus.key.addEventListener('backbutton', function () {
|
||
var wv = webview.children[0];
|
||
if (wv && wv.canBack) {
|
||
wv.canBack(function (e) {
|
||
if (e.canBack) {
|
||
wv.back();
|
||
} else {
|
||
// 已在首页,按两次退出
|
||
confirmExit();
|
||
}
|
||
});
|
||
} else {
|
||
confirmExit();
|
||
}
|
||
});
|
||
}
|
||
|
||
function confirmExit() {
|
||
if (typeof plus === 'undefined') return;
|
||
plus.nativeUI.confirm(
|
||
'确定要退出应用吗?',
|
||
function (e) {
|
||
if (e.index === 0) {
|
||
plus.runtime.quit();
|
||
}
|
||
},
|
||
'退出提示',
|
||
['确定', '取消']
|
||
);
|
||
}
|
||
|
||
/* -------------------------------------------
|
||
7. 启动流程
|
||
------------------------------------------- */
|
||
function boot() {
|
||
checkNetwork(function (online) {
|
||
if (!online) {
|
||
showError();
|
||
return;
|
||
}
|
||
initPlusWebView();
|
||
});
|
||
|
||
setupBottomBar();
|
||
setupBackButton();
|
||
|
||
retryBtn.addEventListener('click', function () {
|
||
hideError();
|
||
splash.style.display = '';
|
||
splash.classList.remove('fade-out');
|
||
startTime = Date.now();
|
||
boot();
|
||
});
|
||
}
|
||
|
||
// ---- 入口 ----
|
||
if (typeof plus !== 'undefined') {
|
||
// HTML5+ ready
|
||
plus.ready(function () { boot(); });
|
||
} else if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', boot);
|
||
} else {
|
||
boot();
|
||
}
|
||
})(); |