191 lines
7.8 KiB
HTML
191 lines
7.8 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta
|
|
name="viewport"
|
|
content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content"
|
|
/>
|
|
<meta name="theme-color" content="#ffffff" />
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<meta name="format-detection" content="telephone=no" />
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
<title>编辑笔记 - EdgeEver</title>
|
|
<style>
|
|
#mobile-editor-bootstrap {
|
|
min-height: 100dvh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: #fff;
|
|
color: #0f172a;
|
|
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
padding: 24px;
|
|
}
|
|
.mobile-editor-bootstrap-card {
|
|
width: min(100%, 360px);
|
|
text-align: center;
|
|
}
|
|
.mobile-editor-bootstrap-spinner {
|
|
width: 28px;
|
|
height: 28px;
|
|
margin: 0 auto 16px;
|
|
border: 3px solid #d1fae5;
|
|
border-top-color: #16a06e;
|
|
border-radius: 999px;
|
|
animation: mobile-editor-bootstrap-spin 0.8s linear infinite;
|
|
}
|
|
.mobile-editor-bootstrap-title {
|
|
margin: 0;
|
|
font-size: 17px;
|
|
font-weight: 700;
|
|
}
|
|
.mobile-editor-bootstrap-detail {
|
|
margin: 8px 0 0;
|
|
color: #64748b;
|
|
font-size: 14px;
|
|
line-height: 1.55;
|
|
}
|
|
.mobile-editor-bootstrap-actions {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 10px;
|
|
margin-top: 20px;
|
|
}
|
|
.mobile-editor-bootstrap-action {
|
|
min-height: 40px;
|
|
border: 1px solid #cbd5e1;
|
|
border-radius: 9px;
|
|
background: #fff;
|
|
color: #0f172a;
|
|
font: inherit;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
padding: 8px 16px;
|
|
}
|
|
.mobile-editor-bootstrap-action[data-primary="true"] {
|
|
border-color: #16a06e;
|
|
background: #16a06e;
|
|
color: #fff;
|
|
}
|
|
@keyframes mobile-editor-bootstrap-spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.mobile-editor-bootstrap-spinner { animation: none; }
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
#mobile-editor-bootstrap { background: #19222b; color: #f8fafc; }
|
|
.mobile-editor-bootstrap-detail { color: #94a3b8; }
|
|
.mobile-editor-bootstrap-action { border-color: #475569; background: #1e293b; color: #f8fafc; }
|
|
}
|
|
</style>
|
|
<script>
|
|
(() => {
|
|
const slowLoadDelayMs = 8000;
|
|
const english = navigator.language.toLowerCase().startsWith("en");
|
|
const labels = english
|
|
? {
|
|
loading: "Opening editor…",
|
|
loadingDetail: "Your note is safe. This may take a moment on a slow connection.",
|
|
delayed: "The editor is taking longer than expected to open.",
|
|
failed: "The editor could not start.",
|
|
failedDetail: "Check your connection, then retry or return to the note list.",
|
|
back: "Back",
|
|
retry: "Retry",
|
|
}
|
|
: {
|
|
loading: "正在打开编辑器…",
|
|
loadingDetail: "笔记内容是安全的,网络较慢时可能需要稍等片刻。",
|
|
delayed: "编辑器启动时间较长,请检查网络连接。",
|
|
failed: "编辑器未能启动",
|
|
failedDetail: "请检查网络后重试,或先返回笔记列表。",
|
|
back: "返回",
|
|
retry: "重试",
|
|
};
|
|
let mounted = false;
|
|
let slowLoadTimer = 0;
|
|
|
|
const getElement = (id) => document.getElementById(id);
|
|
const setBootstrapCopy = (title, detail, state) => {
|
|
if (mounted) return;
|
|
const bootstrap = getElement("mobile-editor-bootstrap");
|
|
const titleElement = getElement("mobile-editor-bootstrap-title");
|
|
const detailElement = getElement("mobile-editor-bootstrap-detail");
|
|
const retryButton = getElement("mobile-editor-bootstrap-retry");
|
|
if (!bootstrap || !titleElement || !detailElement || !retryButton) return;
|
|
bootstrap.dataset.state = state;
|
|
titleElement.textContent = title;
|
|
detailElement.textContent = detail;
|
|
retryButton.hidden = state === "loading";
|
|
};
|
|
const showFailure = () => setBootstrapCopy(labels.failed, labels.failedDetail, "error");
|
|
const onWindowError = (event) => {
|
|
const target = event.target;
|
|
const failedCriticalResource = target instanceof HTMLScriptElement
|
|
|| (target instanceof HTMLLinkElement && (target.rel === "stylesheet" || target.rel === "modulepreload"));
|
|
if (target === window || failedCriticalResource) showFailure();
|
|
};
|
|
const onUnhandledRejection = () => showFailure();
|
|
const returnToPreviousPage = () => {
|
|
if (history.length > 1) {
|
|
history.back();
|
|
return;
|
|
}
|
|
const params = new URLSearchParams(location.hash.slice(1));
|
|
const returnTo = params.get("returnTo");
|
|
location.replace(returnTo && returnTo.startsWith("/") ? returnTo : "/");
|
|
};
|
|
const bindBootstrap = () => {
|
|
setBootstrapCopy(labels.loading, labels.loadingDetail, "loading");
|
|
const backButton = getElement("mobile-editor-bootstrap-back");
|
|
const retryButton = getElement("mobile-editor-bootstrap-retry");
|
|
if (backButton) {
|
|
backButton.textContent = labels.back;
|
|
backButton.addEventListener("click", returnToPreviousPage);
|
|
}
|
|
if (retryButton) {
|
|
retryButton.textContent = labels.retry;
|
|
retryButton.addEventListener("click", () => location.reload());
|
|
}
|
|
};
|
|
|
|
window.edgeeverMobileEditorBootstrap = {
|
|
markMounted() {
|
|
mounted = true;
|
|
window.clearTimeout(slowLoadTimer);
|
|
window.removeEventListener("error", onWindowError, true);
|
|
window.removeEventListener("unhandledrejection", onUnhandledRejection);
|
|
},
|
|
showFailure,
|
|
};
|
|
window.addEventListener("error", onWindowError, true);
|
|
window.addEventListener("unhandledrejection", onUnhandledRejection);
|
|
document.addEventListener("DOMContentLoaded", bindBootstrap, { once: true });
|
|
slowLoadTimer = window.setTimeout(() => {
|
|
setBootstrapCopy(labels.delayed, labels.loadingDetail, "delayed");
|
|
}, slowLoadDelayMs);
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="mobile-editor-root">
|
|
<main id="mobile-editor-bootstrap" data-state="loading" role="status" aria-live="polite">
|
|
<section class="mobile-editor-bootstrap-card">
|
|
<div class="mobile-editor-bootstrap-spinner" aria-hidden="true"></div>
|
|
<h1 id="mobile-editor-bootstrap-title" class="mobile-editor-bootstrap-title">正在打开编辑器…</h1>
|
|
<p id="mobile-editor-bootstrap-detail" class="mobile-editor-bootstrap-detail">笔记内容是安全的,网络较慢时可能需要稍等片刻。</p>
|
|
<div class="mobile-editor-bootstrap-actions">
|
|
<button id="mobile-editor-bootstrap-back" class="mobile-editor-bootstrap-action" type="button">返回</button>
|
|
<button id="mobile-editor-bootstrap-retry" class="mobile-editor-bootstrap-action" data-primary="true" type="button" hidden>重试</button>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
<script type="module" src="/src/mobile-edit.tsx"></script>
|
|
</body>
|
|
</html>
|