/** * Dialog Components for FileManager */ import React, { useState, useEffect } from 'react'; import { FSNode } from '../../../os/types'; import * as FileSystem from '../../../os/FileSystemService'; import { getFileIcon, getFileIconColor } from '../utils/fileUtils'; import { strings } from '../res/strings'; import { stringsEn } from '../res/strings.en'; import { useAppStrings } from '@/os/useAppStrings'; import * as TimeService from '@/os/TimeService'; // ============================================================================ // Base Dialog // ============================================================================ interface DialogProps { open: boolean; onClose: () => void; title: string; children: React.ReactNode; } export const Dialog: React.FC = ({ open, onClose, title, children }) => { if (!open) return null; return (

{title}

{children}
); }; // ============================================================================ // Input Dialog // ============================================================================ interface InputDialogProps { open: boolean; onClose: () => void; title: string; placeholder?: string; defaultValue?: string; onConfirm: (value: string) => void; confirmText?: string; } export const InputDialog: React.FC = ({ open, onClose, title, placeholder, defaultValue = '', onConfirm, confirmText }) => { const s = useAppStrings(strings, stringsEn); const effectiveConfirmText = confirmText ?? s.dialog_confirm; const [value, setValue] = useState(defaultValue); useEffect(() => { if (open) setValue(defaultValue); }, [open, defaultValue]); const handleConfirm = () => { if (value.trim()) { onConfirm(value.trim()); // Note: onConfirm is responsible for closing the dialog via back() } }; return ( setValue(e.target.value)} placeholder={placeholder} className="w-full px-4 py-3 border border-app-border rounded-xl text-[15px] focus:outline-none focus:border-blue-500" autoFocus onKeyDown={e => e.key === 'Enter' && handleConfirm()} />
); }; // ============================================================================ // Confirm Dialog // ============================================================================ interface ConfirmDialogProps { open: boolean; onClose: () => void; title: string; message: string; onConfirm: () => void; confirmText?: string; cancelText?: string; isDestructive?: boolean; } export const ConfirmDialog: React.FC = ({ open, onClose, title, message, onConfirm, confirmText, cancelText, isDestructive = false }) => { const s = useAppStrings(strings, stringsEn); const effectiveCancelText = cancelText ?? s.dialog_cancel; const effectiveConfirmText = confirmText ?? s.dialog_confirm; if (!open) return null; return (

{title}

{message}

); }; // ============================================================================ // Action Menu (Popup) // ============================================================================ interface ActionMenuProps { open: boolean; onClose: () => void; options: { label: string; onClick: () => void; destructive?: boolean; }[]; } export const ActionMenu: React.FC = ({ open, onClose, options }) => { if (!open) return null; return (
{options.map((opt, index) => ( ))}
); }; // ============================================================================ // File Details Dialog // ============================================================================ export const FileDetailsDialog: React.FC<{ open: boolean; onClose: () => void; file: FSNode | null; }> = ({ open, onClose, file }) => { const s = useAppStrings(strings, stringsEn); if (!open || !file) return null; const formatDate = (timestamp: number) => { const date = TimeService.fromTimestamp(timestamp); return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`; }; const isFolder = file.type === 'directory'; return (
{/* Header with icon */}

{file.name}

{/* Details */}
{s.detail_location} {file.path.replace('/sdcard', '/storage/emulated/0')}
{s.detail_size} {FileSystem.formatFileSize(file.size)}
{s.detail_time} {formatDate(file.modifiedAt)}
{s.detail_readable} {s.detail_yes}
{s.detail_writable} {file.storage === 'preset' ? s.detail_no : s.detail_yes}
{s.detail_hidden} {file.name.startsWith('.') ? s.detail_yes : s.detail_no}
{/* Button */}
); };