// 首次启动引导(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 = (
<>
试一试
点一下下面的输入框,按住快捷键说句话,松开看看
>
);
primary = ;
}
return (
{body}
{step > 0 && }
{primary}
);
}
createRoot(document.getElementById('root')).render();