feat: Add turtle management features including rename, configuration, and GPS locate
This commit is contained in:
@@ -79,6 +79,21 @@ function TurtleCard({ turtle, isSelected, onSelect }) {
|
||||
function TurtleDetails({ turtle }) {
|
||||
const sendCommand = useTurtleStore((state) => state.sendCommand);
|
||||
const setTurtleState = useTurtleStore((state) => state.setTurtleState);
|
||||
const renameTurtle = useTurtleStore((state) => state.renameTurtle);
|
||||
const equipLeft = useTurtleStore((state) => state.equipLeft);
|
||||
const equipRight = useTurtleStore((state) => state.equipRight);
|
||||
const sortInventory = useTurtleStore((state) => state.sortInventory);
|
||||
const selectSlot = useTurtleStore((state) => state.selectSlot);
|
||||
const dropItems = useTurtleStore((state) => state.dropItems);
|
||||
const suckItems = useTurtleStore((state) => state.suckItems);
|
||||
const connectToInventory = useTurtleStore((state) => state.connectToInventory);
|
||||
const updateTurtleConfig = useTurtleStore((state) => state.updateTurtleConfig);
|
||||
const exploreTurtle = useTurtleStore((state) => state.exploreTurtle);
|
||||
const gpsLocateTurtle = useTurtleStore((state) => state.gpsLocateTurtle);
|
||||
|
||||
const [renameValue, setRenameValue] = useState('');
|
||||
const [showConfig, setShowConfig] = useState(false);
|
||||
const [configValues, setConfigValues] = useState({ maxDistance: 200, autoRefuel: true });
|
||||
|
||||
if (!turtle) {
|
||||
return (
|
||||
@@ -96,11 +111,66 @@ function TurtleDetails({ turtle }) {
|
||||
setTurtleState(turtle.turtleID, stateName, data);
|
||||
};
|
||||
|
||||
const handleRename = async () => {
|
||||
if (renameValue.trim()) {
|
||||
await renameTurtle(turtle.turtleID, renameValue.trim());
|
||||
setRenameValue('');
|
||||
}
|
||||
};
|
||||
|
||||
const handleSlotClick = async (slotIndex) => {
|
||||
await selectSlot(turtle.turtleID, slotIndex + 1);
|
||||
};
|
||||
|
||||
const handleConfigSave = async () => {
|
||||
await updateTurtleConfig(turtle.turtleID, configValues);
|
||||
setShowConfig(false);
|
||||
};
|
||||
|
||||
const activeState = turtle.state || turtle.mode || 'idle';
|
||||
const displayName = turtle.label || `Turtle ${turtle.turtleID}`;
|
||||
|
||||
return (
|
||||
<div className="turtle-details">
|
||||
<h2>Turtle {turtle.turtleID} Control</h2>
|
||||
<h2>{displayName} <span style={{color: '#6b7280', fontSize: '0.8em'}}>#{turtle.turtleID}</span></h2>
|
||||
|
||||
{/* Rename + Config bar */}
|
||||
<div className="detail-section" style={{ display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
<input
|
||||
type="text"
|
||||
value={renameValue}
|
||||
onChange={(e) => setRenameValue(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleRename()}
|
||||
placeholder="Rename turtle..."
|
||||
className="rename-input"
|
||||
style={{ flex: 1, minWidth: '120px', padding: '4px 8px', borderRadius: '4px', border: '1px solid #4b5563', background: '#1f2937', color: '#fff' }}
|
||||
/>
|
||||
<button onClick={handleRename} className="command-btn" style={{ padding: '4px 12px' }}>📝 Rename</button>
|
||||
<button onClick={() => setShowConfig(!showConfig)} className="command-btn" style={{ padding: '4px 12px' }}>⚙️ Config</button>
|
||||
<button onClick={() => gpsLocateTurtle(turtle.turtleID)} className="command-btn" style={{ padding: '4px 12px' }}>📡 GPS</button>
|
||||
<button onClick={() => exploreTurtle(turtle.turtleID)} className="command-btn" style={{ padding: '4px 12px' }}>🔎 Inspect</button>
|
||||
</div>
|
||||
|
||||
{/* Config Modal */}
|
||||
{showConfig && (
|
||||
<div className="detail-section" style={{ background: '#1e293b', padding: '12px', borderRadius: '8px', border: '1px solid #334155' }}>
|
||||
<h3>⚙️ Configuration</h3>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', marginTop: '8px' }}>
|
||||
<label style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<span>Max Distance:</span>
|
||||
<input type="number" value={configValues.maxDistance} onChange={(e) => setConfigValues({...configValues, maxDistance: parseInt(e.target.value)})} style={{ width: '80px', padding: '2px 6px', borderRadius: '4px', border: '1px solid #4b5563', background: '#0f172a', color: '#fff' }} />
|
||||
</label>
|
||||
<label style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<span>Auto Refuel:</span>
|
||||
<input type="checkbox" checked={configValues.autoRefuel} onChange={(e) => setConfigValues({...configValues, autoRefuel: e.target.checked})} />
|
||||
</label>
|
||||
<div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>
|
||||
<button onClick={() => setShowConfig(false)} className="command-btn" style={{ padding: '4px 12px' }}>Cancel</button>
|
||||
<button onClick={handleConfigSave} className="command-btn explore" style={{ padding: '4px 12px' }}>💾 Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="detail-section">
|
||||
<h3>Status</h3>
|
||||
|
||||
Reference in New Issue
Block a user