'use client'; import { useState, useEffect, useCallback } from 'react'; import { Check, Copy, ChevronUp, Download } from 'lucide-react'; import { distros, type DistroId } from '@/lib/data'; import { generateInstallScript } from '@/lib/generateInstallScript'; import { analytics } from '@/lib/analytics'; import { useTheme } from '@/hooks/useTheme'; import { ShortcutsBar } from './ShortcutsBar'; import { AurFloatingCard } from './AurFloatingCard'; import { CommandDrawer } from './CommandDrawer'; interface CommandFooterProps { command: string; selectedCount: number; selectedDistro: DistroId; selectedApps: Set; hasAurPackages: boolean; aurAppNames: string[]; hasYayInstalled: boolean; setHasYayInstalled: (value: boolean) => void; searchQuery: string; onSearchChange: (query: string) => void; searchInputRef: React.RefObject; clearAll: () => void; selectedHelper: 'yay' | 'paru'; setSelectedHelper: (helper: 'yay' | 'paru') => void; } // The sticky footer with command preview and copy/download buttons export function CommandFooter({ command, selectedCount, selectedDistro, selectedApps, hasAurPackages, aurAppNames, hasYayInstalled, setHasYayInstalled, searchQuery, onSearchChange, searchInputRef, clearAll, selectedHelper, setSelectedHelper, }: CommandFooterProps) { const [copied, setCopied] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); const [drawerClosing, setDrawerClosing] = useState(false); const { toggle: toggleTheme } = useTheme(); const closeDrawer = useCallback(() => { setDrawerClosing(true); setTimeout(() => { setDrawerOpen(false); setDrawerClosing(false); }, 250); }, []); // Close drawer on Escape useEffect(() => { if (!drawerOpen) return; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') closeDrawer(); }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [drawerOpen, closeDrawer]); const showAur = selectedDistro === 'arch' && hasAurPackages; const distroDisplayName = distros.find(d => d.id === selectedDistro)?.name || selectedDistro; const handleCopy = useCallback(async () => { if (selectedCount === 0) return; await navigator.clipboard.writeText(command); setCopied(true); const distroName = distros.find(d => d.id === selectedDistro)?.name || selectedDistro; analytics.commandCopied(distroName, selectedCount); setTimeout(() => setCopied(false), 3000); }, [command, selectedCount, selectedDistro]); const handleDownload = useCallback(() => { if (selectedCount === 0) return; const script = generateInstallScript({ distroId: selectedDistro, selectedAppIds: selectedApps, helper: selectedHelper, }); const blob = new Blob([script], { type: 'text/x-shellscript' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `tuxmate-${selectedDistro}.sh`; a.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); const distroName = distros.find(d => d.id === selectedDistro)?.name || selectedDistro; analytics.scriptDownloaded(distroName, selectedCount); }, [selectedCount, selectedDistro, selectedApps, selectedHelper]); // Global keyboard shortcuts (vim-like) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ( e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement ) { return; } // Ignore modifier keys (prevents conflicts with browser shortcuts) if (e.ctrlKey || e.altKey || e.metaKey) return; const alwaysEnabled = ['t', 'c']; if (selectedCount === 0 && !alwaysEnabled.includes(e.key)) return; switch (e.key) { case 'y': handleCopy(); break; case 'd': handleDownload(); break; case 't': document.body.classList.add('theme-flash'); setTimeout(() => document.body.classList.remove('theme-flash'), 150); toggleTheme(); break; case 'c': clearAll(); break; case '1': if (showAur) setSelectedHelper('yay'); break; case '2': if (showAur) setSelectedHelper('paru'); break; case 'Tab': e.preventDefault(); if (selectedCount > 0) setDrawerOpen(prev => !prev); break; } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [selectedCount, toggleTheme, clearAll, showAur, setSelectedHelper, handleCopy, handleDownload]); return ( <> {/* AUR Floating Card */} {/* Command Drawer */} {/* Animated footer container */}
{/* Soft glow behind bars */}
{/* Shortcuts Bar */} {/* Command Bar */}
{/* Preview button */} {/* Command text */}
selectedCount > 0 && setDrawerOpen(true)} > 0 ? 'text-[var(--text-primary)]' : 'text-[var(--text-muted)]'}`}> {command}
{/* Download button */} {/* Copy button */}
); }