import { useRef } from 'react'; import { readClipboard } from '@/lib/clipboard'; import { useMediaQuery } from '@/lib/useMediaQuery'; import { Icon, type IconName } from '@/ui/Icon'; import styles from './ActionBar.module.css'; interface Props { /** dock:手机底部动作栏;toolbar:电脑列表上方的工具条 */ layout: 'dock' | 'toolbar'; /** 添加文件、文本:空间发到空间里,分享放进草稿 */ onFiles: (files: File[]) => void; onText: (text: string) => void; onCompose: () => void; /** 不传则不显示扫码(分享草稿里不需要) */ onScan?: () => void; } interface Action { key: string; label: string; icon: IconName; /** 触屏专有(相册、拍照) */ touchOnly?: boolean; run: () => void; } export function ActionBar({ layout, onFiles, onText, onCompose, onScan }: Props) { const touch = useMediaQuery('(pointer: coarse)'); const fileRef = useRef(null); const galleryRef = useRef(null); const cameraRef = useRef(null); async function paste() { const clip = await readClipboard(); if (!clip) return onCompose(); // 无权限时退回到手动输入 if (clip.files.length > 0) onFiles(clip.files); else if (clip.text.trim()) onText(clip.text.trim()); } const actions: Action[] = [ { key: 'paste', label: '粘贴', icon: 'paste', run: () => void paste() }, { key: 'file', label: '文件', icon: 'file', run: () => fileRef.current?.click() }, { key: 'gallery', label: '相册', icon: 'image', touchOnly: true, run: () => galleryRef.current?.click() }, { key: 'camera', label: '拍照', icon: 'camera', touchOnly: true, run: () => cameraRef.current?.click() }, ...(onScan ? [{ key: 'scan', label: '扫码', icon: 'scan' as const, run: onScan }] : []), { key: 'write', label: '写', icon: 'edit', run: onCompose }, ]; const shown = actions.filter((a) => layout === 'dock' || touch || !a.touchOnly); function onPick(files: FileList | null) { if (files?.length) onFiles([...files]); } return (
{ onPick(e.target.files); e.target.value = ''; }} /> { onPick(e.target.files); e.target.value = ''; }} /> { onPick(e.target.files); e.target.value = ''; }} /> {shown.map((a) => ( ))}
); }