实现账号绑定、持久登录与跨设备对局恢复
CI / test (ubuntu-latest, node 22) (push) Failing after 33m10s
CI / test (ubuntu-latest, node 24) (push) Failing after 34m41s
CI / tooling (lint, imports, typecheck) (push) Failing after 36m11s
CI / test (windows-latest, node 22) (push) Canceled after 0s
CI / test (windows-latest, node 24) (push) Canceled after 0s

This commit is contained in:
herryyun committed 2026-10-14 23:22:50 +08:00
1 parent 488db49f11
commit 7c25c89992
62 files changed
+6855 -1005

No files matched your search

+2 -2
View File
@@ -19,7 +19,7 @@ export function bannerVisible(conn, entered, restoring, buildStale = false) {
return true;
}
export function ConnectionBanner() {
export function ConnectionBanner({ continueSession } = {}) {
const conn = useStore((s) => s.connection, shallowEqual);
const entered = useStore((s) => s.session.entered);
const restoring = useStore((s) => s.ui.restoring);
@@ -53,7 +53,7 @@ export function ConnectionBanner() {
: conn.status === 'closed' ? t('连接已关闭')
: rejected ? t(conn.lastError.text) : t('正在连接服务器');
const action = conn.status === 'reconnecting' ? { label: t('立即重连'), run: () => net.retryNow() }
: conn.status === 'closed' ? { label: replaced ? t('在此页面继续') : t('重新连接'), run: () => net.connect() }
: conn.status === 'closed' ? { label: replaced ? t('在此页面继续') : t('重新连接'), run: continueSession || (() => net.connect()) }
: versionMismatch ? { label: t('刷新页面'), run: () => location.reload() }
: rejected ? { label: t('重试'), run: () => net.reconnectNow() } : null;
return html`<div class=${`conn-banner${transient ? ' conn-banner--soft' : ''}`} role="alert">
+5 -3
View File
@@ -6,7 +6,7 @@ import { store } from '../store.js';
import { t } from '../../../shared/i18n.js';
import { toast } from './toasts.js';
export function ResumeMatchButton() {
export function ResumeMatchButton({ beforeEnter } = {}) {
const [items, setItems] = useState(() => identity.recoverable());
const [open, setOpen] = useState(false);
const [busy, setBusy] = useState(false);
@@ -22,13 +22,15 @@ export function ResumeMatchButton() {
if (busy) return;
setBusy(true);
if (await identity.resume(item.id)) {
identity.setEntered(true);
store.patch('session', { entered: true });
// Keep the tentative token in this document until welcome persists it. Reloading here
// would either lose the selection or falsely turn it into an established session claim.
net.close();
net.setName(item.name);
net.connect();
if (!beforeEnter || await beforeEnter()) {
identity.setEntered(true);
store.patch('session', { entered: true });
}
setOpen(false);
setBusy(false);
} else {