// 首次启动引导(11F):欢迎 → 权限 → 登录 → 试一试。 // 规格见 doc/frontend-design.html 4.3;完成 / 关窗后置 onboarding_done。 import { useEffect, useState } from 'react'; import { createRoot } from 'react-dom/client'; import '@dudu/design/styles.css'; import { Button } from '@dudu/design/components/core/Button'; import { Badge } from '@dudu/design/components/core/Badge'; import { HotkeyCombo } from '@dudu/design/components/core/Kbd'; import { invoke } from '../shared/tauri'; import { setThemePref } from '../shared/theme'; const isMac = navigator.platform.toUpperCase().includes('MAC'); const STEPS = ['welcome', 'perms', 'login', 'try']; function Dots({ step }) { return (
{STEPS.map((s, i) => ( ))}
); } function Title({ children }) { return
{children}
; } function Desc({ children }) { return
{children}
; } // 权限检测卡片:状态徽标 + 去开启按钮 function PermCard({ icon, title, desc, granted, onGrant }) { return (
{icon} {title} {desc} {granted ? 已开启 : }
); } const MicIcon = ( ); const KeyIcon = ( ); function OnboardingApp() { const [step, setStep] = useState(0); const [micOk, setMicOk] = useState(false); const [axOk, setAxOk] = useState(!isMac); const [me, setMe] = useState(null); useEffect(() => { invoke('get_settings').then((s) => s && setThemePref(s.theme)); }, []); // 权限步:辅助功能状态轮询(用户去系统设置开启后自动变绿) useEffect(() => { if (STEPS[step] !== 'perms' || !isMac) return undefined; let live = true; const tick = () => invoke('check_accessibility').then((ok) => live && setAxOk(!!ok)); tick(); const t = setInterval(tick, 1000); return () => { live = false; clearInterval(t); }; }, [step]); // 登录步:轮询账号,扫码成功后自动亮起 useEffect(() => { if (STEPS[step] !== 'login') return undefined; let live = true; const tick = () => invoke('fetch_me').then((m) => live && m && setMe(m)); tick(); const t = setInterval(tick, 1500); return () => { live = false; clearInterval(t); }; }, [step]); const next = () => setStep((s) => Math.min(s + 1, STEPS.length - 1)); const prev = () => setStep((s) => Math.max(s - 1, 0)); const finish = () => invoke('finish_onboarding'); let body = null; let primary = null; const name = STEPS[step]; if (name === 'welcome') { body = ( <> dudu 语音输入 按住快捷键说话,松开文字就出现在光标处
全程比打字快三倍
); primary = ; } else if (name === 'perms') { body = ( <> 先开两个权限 {isMac ? '麦克风用来听你说话,辅助功能让文字上屏' : '麦克风用来听你说话'}
invoke('request_microphone').then((ok) => setMicOk(!!ok))} /> {isMac && ( invoke('open_accessibility_settings')} /> )}
); primary = ; } else if (name === 'login') { body = ( <> 登录同步时长 微信扫码登录,购买的时长跟着账号走
也可以先试用,每天免费 3 分钟
{me ? ( {me.nickname_masked} 已登录 ) : ( )}
); primary = ; } else { body = ( <> 试一试 点一下下面的输入框,按住快捷键说句话,松开看看