feat(web): ask for a display name when creating an account [CI]
This commit is contained in:
1 parent
915992776d
commit
059a29a8d5
2 files changed
+10
-6
No files matched your search
@@ -25,6 +25,7 @@ export function AccountPanel({ variant = 'default' }: { variant?: 'default' | 'a
|
||||
const refreshShares = useShares((s) => s.refresh);
|
||||
const [register, setRegister] = useState(true);
|
||||
const [username, setUsername] = useState('');
|
||||
const [displayName, setDisplayName] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [confirm, setConfirm] = useState('');
|
||||
const [message, setMessage] = useState('');
|
||||
@@ -63,8 +64,8 @@ export function AccountPanel({ variant = 'default' }: { variant?: 'default' | 'a
|
||||
if (creating && password !== confirm) { setMessage('两次输入的密码不一致'); return; }
|
||||
setMessage('');
|
||||
try {
|
||||
if (unlockUsername) await unlockPasskey(password, remember); else await login(username, password, register, remember);
|
||||
setPassword(''); setConfirm('');
|
||||
if (unlockUsername) await unlockPasskey(password, remember); else await login(username, password, register, remember, displayName);
|
||||
setPassword(''); setConfirm(''); setDisplayName('');
|
||||
await Promise.all([refreshChannels(), refreshShares()]);
|
||||
setMessage(register ? '账号已创建,资源保险库已同步。' : '已登录,资源保险库已同步。');
|
||||
const pending = useChannels.getState().pendingLink;
|
||||
@@ -90,13 +91,14 @@ export function AccountPanel({ variant = 'default' }: { variant?: 'default' | 'a
|
||||
</div> : null}
|
||||
{unlockUsername ? <p className={styles.note}>已用Passkey确认账号,请输入账号密码解锁资源。</p> : null}
|
||||
<label>账号 ID<input name="username" autoComplete="username" minLength={3} maxLength={32} value={unlockUsername ?? username} disabled={Boolean(unlockUsername)} onChange={(event) => { edited.current = true; setUsername(event.target.value); }} required /></label>
|
||||
{creating ? <label>个人名称(可选)<input name="display-name" autoComplete="nickname" maxLength={48} value={displayName} placeholder={username || '显示给其他成员看的名字'} onChange={(event) => { edited.current = true; setDisplayName(event.target.value); }} /></label> : null}
|
||||
<label>密码<input name="password" autoComplete={register ? 'new-password' : 'current-password'} type="password" minLength={register ? 12 : undefined} value={password} onChange={(event) => { edited.current = true; setPassword(event.target.value); }} required /></label>
|
||||
{creating ? <label>确认密码<input name="confirm-password" autoComplete="new-password" type="password" minLength={12} value={confirm} aria-invalid={mismatch} onChange={(event) => { edited.current = true; setConfirm(event.target.value); }} required />
|
||||
</label> : null}
|
||||
{creating ? <ul className={styles.rules} aria-label="注册要求">
|
||||
{rules.map((rule) => <li key={rule.text} data-met={rule.met}><span aria-hidden="true">{rule.met ? '✓' : '○'}</span>{rule.text}<span className={styles.srOnly}>{rule.met ? ',已满足' : ',未满足'}</span></li>)}
|
||||
</ul> : null}
|
||||
{creating ? <p className={styles.note}>账号 ID 是登录用的唯一标识,不是显示名称;显示名称可在登录后的个人资料里设置。密码用于在本机加密你的资源保险库,<strong>忘记后无法找回</strong>,请妥善保管。</p> : null}
|
||||
{creating ? <p className={styles.note}>账号 ID 是登录用的唯一标识,注册后不能改;个人名称是其他成员看到的名字,留空就显示账号 ID,之后可在个人资料里修改。密码用于在本机加密你的资源保险库,<strong>忘记后无法找回</strong>,请妥善保管。</p> : null}
|
||||
<label className={styles.remember}><input type="checkbox" checked={remember} onChange={(event) => setRemember(event.target.checked)} />记住账号和密码(本机)</label>
|
||||
<div className={styles.actions}>
|
||||
<Button type="submit" variant="primary" disabled={busy || !channelsReady || !sharesReady || unmet}>{busy ? '处理中…' : !channelsReady || !sharesReady ? '正在读取本机资源…' : unlockUsername ? '解锁资源' : register ? '创建账号' : '登录并同步'}</Button>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { loginWithPasskey, passkeyApi } from '@/core-bridge/passkeys';
|
||||
interface AccountState extends AccountStatus {
|
||||
busy: boolean;
|
||||
hydrated: boolean;
|
||||
login: (username: string, password: string, create: boolean, remember?: boolean) => Promise<void>;
|
||||
login: (username: string, password: string, create: boolean, remember?: boolean, displayName?: string) => Promise<void>;
|
||||
passkeyLogin: (username: string, remember: boolean) => Promise<void>;
|
||||
unlockPasskey: (password: string, remember: boolean) => Promise<void>;
|
||||
cancelPasskey: () => Promise<void>;
|
||||
@@ -46,10 +46,12 @@ export const useAccount = create<AccountState>()((set, get) => ({
|
||||
catch (error) { set({ busy: false, unlockUsername: undefined, error: error instanceof Error ? error.message : '账号解锁失败' }); throw error; }
|
||||
},
|
||||
cancelPasskey: async () => { await passkeyApi.cancel(); set({ unlockUsername: undefined, error: undefined }); },
|
||||
login: async (username, password, create, remember = true) => {
|
||||
login: async (username, password, create, remember = true, displayName = '') => {
|
||||
set({ busy: true, error: undefined });
|
||||
try {
|
||||
const status = create ? await accountApi.register(username, password, remember) : await accountApi.login(username, password, remember);
|
||||
let status = create ? await accountApi.register(username, password, remember) : await accountApi.login(username, password, remember);
|
||||
// 注册时填的个人名称:账号已经建好,这一步失败不算注册失败,之后可在个人资料里补
|
||||
if (create && displayName.trim()) status = await accountApi.updatePersonal(displayName.trim()).catch(() => status);
|
||||
clearViews(); await refreshResources();
|
||||
set({ ...status, busy: false, hydrated: true });
|
||||
} catch (error) {
|
||||
|
||||
Reference in new issue
Block a user