Merge remote-tracking branch 'origin/master'
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-01 22:14:49 +08:00
151 changed files with 3952 additions and 1299 deletions

View File

@@ -34,6 +34,7 @@ import {
loginWithPhoneCode,
logoutAllAuthSessions,
logoutAuthUser,
redeemRegistrationInviteCode,
resetPassword,
revokeAuthSession,
sendPhoneLoginCode,
@@ -44,6 +45,7 @@ import { AccountModal } from './AccountModal';
import { AuthUiContext, type PlatformSettingsSection } from './AuthUiContext';
import { BindPhoneScreen } from './BindPhoneScreen';
import { LoginScreen } from './LoginScreen';
import { RegistrationInviteModal } from './RegistrationInviteModal';
type AuthGateProps = {
children: ReactNode;
@@ -91,10 +93,12 @@ export function AuthGate({ children }: AuthGateProps) {
const [bindingPhone, setBindingPhone] = useState(false);
const [wechatLoading, setWechatLoading] = useState(false);
const [showLoginModal, setShowLoginModal] = useState(false);
const [loginInitialMode, setLoginInitialMode] = useState<
'login' | 'register'
>('login');
const [pendingInviteCode, setPendingInviteCode] = useState('');
const [showRegistrationInviteModal, setShowRegistrationInviteModal] =
useState(false);
const [submittingRegistrationInvite, setSubmittingRegistrationInvite] =
useState(false);
const [registrationInviteError, setRegistrationInviteError] = useState('');
const [showSettingsModal, setShowSettingsModal] = useState(false);
const [settingsEntryMode, setSettingsEntryMode] = useState<
'settings' | 'account'
@@ -141,6 +145,7 @@ export function AuthGate({ children }: AuthGateProps) {
setUser(null);
setStatus('unauthenticated');
setShowLoginModal(false);
setShowRegistrationInviteModal(false);
setShowSettingsModal(false);
setSettingsEntryMode('settings');
setInitialSettingsSection(null);
@@ -150,6 +155,8 @@ export function AuthGate({ children }: AuthGateProps) {
setLoginCaptchaChallenge(null);
setBindCaptchaChallenge(null);
setChangePhoneCaptchaChallenge(null);
setPendingInviteCode('');
setRegistrationInviteError('');
setError('');
}, []);
@@ -182,12 +189,16 @@ export function AuthGate({ children }: AuthGateProps) {
const closeLoginModal = useCallback(() => {
pendingProtectedActionRef.current = null;
setShowLoginModal(false);
setLoginInitialMode('login');
setPendingInviteCode('');
setLoginCaptchaChallenge(null);
setError('');
}, []);
const closeRegistrationInviteModal = useCallback(() => {
setShowRegistrationInviteModal(false);
setRegistrationInviteError('');
setPendingInviteCode('');
}, []);
const closeSettingsModal = useCallback(() => {
setShowSettingsModal(false);
setSettingsEntryMode('settings');
@@ -202,8 +213,6 @@ export function AuthGate({ children }: AuthGateProps) {
}
pendingProtectedActionRef.current = postLoginAction ?? null;
setLoginInitialMode('login');
setPendingInviteCode('');
setShowLoginModal(true);
},
[readyUser],
@@ -253,10 +262,7 @@ export function AuthGate({ children }: AuthGateProps) {
return;
}
autoOpenedInviteCodeRef.current = inviteCode;
pendingProtectedActionRef.current = null;
setPendingInviteCode(inviteCode);
setLoginInitialMode('register');
setShowLoginModal(true);
}, [readyUser, showLoginModal, status]);
useEffect(() => {
@@ -736,8 +742,6 @@ export function AuthGate({ children }: AuthGateProps) {
wechatLoading={wechatLoading}
error={error}
captchaChallenge={loginCaptchaChallenge}
initialMode={loginInitialMode}
initialInviteCode={pendingInviteCode}
onClose={closeLoginModal}
onSendCode={async (phone, scene, captcha) => {
setSendingCode(true);
@@ -762,20 +766,15 @@ export function AuthGate({ children }: AuthGateProps) {
setSendingCode(false);
}
}}
onPhoneSubmit={async (phone, code, inviteCode) => {
onPhoneSubmit={async (phone, code) => {
setLoggingIn(true);
setError('');
try {
const response = await loginWithPhoneCode(
phone,
code,
inviteCode,
);
const response = await loginWithPhoneCode(phone, code);
setStoredLastLoginPhone(phone);
setLoginCaptchaChallenge(null);
if (response.referral && !response.referral.ok) {
setError(response.referral.message || '邀请码未绑定');
}
setShowRegistrationInviteModal(response.created);
setRegistrationInviteError('');
activateReadyUser(response.user);
} catch (loginError) {
setError(
@@ -837,6 +836,30 @@ export function AuthGate({ children }: AuthGateProps) {
}
}}
/>
<RegistrationInviteModal
isOpen={showRegistrationInviteModal}
platformTheme={settings.platformTheme}
initialInviteCode={pendingInviteCode}
submitting={submittingRegistrationInvite}
error={registrationInviteError}
onClose={closeRegistrationInviteModal}
onSubmit={async (inviteCode) => {
setSubmittingRegistrationInvite(true);
setRegistrationInviteError('');
try {
await redeemRegistrationInviteCode(inviteCode);
closeRegistrationInviteModal();
} catch (inviteError) {
setRegistrationInviteError(
inviteError instanceof Error
? inviteError.message
: '填写邀请码失败,请稍后再试。',
);
} finally {
setSubmittingRegistrationInvite(false);
}
}}
/>
</div>
{children}
</div>