import React, { useState, useRef, useEffect } from 'react';
import {
Activity,
RotateCw,
Bluetooth,
Battery,
ChevronLeft,
Zap,
Sliders,
Waves,
Power
} from 'lucide-react';
import { AreaChart, Area, ResponsiveContainer } from 'recharts';
type ViewMode = 'hub' | 'free' | 'pattern';
type DeviceState = 'disconnected' | 'connecting' | 'connected';
interface Pattern {
id: string;
name: string;
icon: React.ReactNode;
color: string;
}
const PATTERNS: Pattern[] = [
{ id: 'pulse', name: '脉冲跳动', icon: , color: '#C084FC' },
{ id: 'wave', name: '深海潮汐', icon: , color: '#60A5FA' },
{ id: 'climb', name: '登峰造极', icon: , color: '#34D399' },
{ id: 'storm', name: '雷雨风暴', icon: , color: '#FBBF24' },
{ id: 'chaos', name: '随机漫步', icon: , color: '#F472B6' },
{ id: 'sos', name: 'SOS', icon: , color: '#F87171' },
];
const DeviceCard: React.FC<{
status: DeviceState;
onConnect: () => void;
onDisconnect: () => void;
}> = ({ status, onConnect, onDisconnect }) => {
return (
Link-X Pro
{status === 'connected' && (
ONLINE
)}
{status === 'disconnected' ? '设备未连接' : status === 'connecting' ? '正在搜索信号...' : 'ID: 884-X9-01'}
{status === 'connected' && (
)}
);
};
const FreeControlView: React.FC<{ onBack: () => void }> = ({ onBack }) => {
const [intensity, setIntensity] = useState(0);
const [isClimax, setIsClimax] = useState(false);
const controlRef = useRef(null);
const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {
if (!controlRef.current) return;
const rect = controlRef.current.getBoundingClientRect();
const clientY = 'touches' in e ? e.touches[0].clientY : (e as React.MouseEvent).clientY;
const relativeY = Math.max(0, Math.min(1, (rect.bottom - clientY) / rect.height));
setIntensity(Math.round(relativeY * 100));
};
const handleClimax = () => {
setIsClimax(true);
setIntensity(100);
if (window.navigator.vibrate) window.navigator.vibrate(500);
setTimeout(() => {
setIsClimax(false);
setIntensity(20);
}, 3000);
};
return (
自由操控
e.buttons === 1 && handleInteraction(e)}
onMouseMove={(e) => e.buttons === 1 && handleInteraction(e)}
>
上下滑动触控板以控制强度
);
};
const PatternControlView: React.FC<{ onBack: () => void }> = ({ onBack }) => {
const [activePattern, setActivePattern] = useState(null);
const [globalIntensity, setGlobalIntensity] = useState(50);
const generateWaveData = (patternId: string | null) => {
if (!patternId) return Array(20).fill({ v: 10 });
return Array.from({ length: 20 }, (_, i) => ({
v: patternId === 'pulse' ? (i % 5 === 0 ? 90 : 20) :
patternId === 'wave' ? 40 + Math.sin(i) * 30 :
Math.random() * 80 + 10
}));
};
const [waveData, setWaveData] = useState(generateWaveData(null));
useEffect(() => {
if (activePattern) {
const interval = setInterval(() => {
setWaveData(prev => {
const next = [...prev.slice(1), { v: Math.random() * (globalIntensity) + 20 }];
return next;
});
}, 100);
return () => clearInterval(interval);
} else {
setWaveData(Array(20).fill({ v: 10 }));
}
}, [activePattern, globalIntensity]);
return (
波形控制
{PATTERNS.map(p => {
const isActive = activePattern === p.id;
return (
)
})}
);
};
const ManualControl: React.FC = () => {
const [view, setView] = useState('hub');
const [deviceStatus, setDeviceStatus] = useState('disconnected');
const connectDevice = () => {
setDeviceStatus('connecting');
setTimeout(() => setDeviceStatus('connected'), 1500);
};
const disconnectDevice = () => {
setDeviceStatus('disconnected');
};
if (view === 'free') return setView('hub')} />
;
if (view === 'pattern') return ;
return (
操控模式
);
};
export default ManualControl;