mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-09 15:58:34 +00:00
7ffc9d427e
Cleans up extra blank lines and trailing spaces across multiple components to improve code readability and maintain consistent formatting. No logic or functional changes are introduced.
124 lines
4.3 KiB
TypeScript
124 lines
4.3 KiB
TypeScript
/**
|
|
* FileOpenerDialog - Dialog for choosing how to open a file
|
|
*/
|
|
import { Edit2, Eye, ExternalLink } from 'lucide-react';
|
|
import React, { useCallback, useState } from 'react';
|
|
import { useI18n } from '../application/i18n/I18nProvider';
|
|
import type { FileOpenerType } from '../lib/sftpFileUtils';
|
|
import { getFileExtension, isImageFile, isTextFile } from '../lib/sftpFileUtils';
|
|
import { Button } from './ui/button';
|
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from './ui/dialog';
|
|
|
|
// Extended opener types
|
|
export type ExtendedFileOpenerType = FileOpenerType | 'system-app';
|
|
|
|
interface FileOpenerDialogProps {
|
|
open: boolean;
|
|
onClose: () => void;
|
|
fileName: string;
|
|
onSelect: (openerType: ExtendedFileOpenerType, setAsDefault: boolean) => void;
|
|
}
|
|
|
|
export const FileOpenerDialog: React.FC<FileOpenerDialogProps> = ({
|
|
open,
|
|
onClose,
|
|
fileName,
|
|
onSelect,
|
|
}) => {
|
|
const { t } = useI18n();
|
|
const [setAsDefault, setSetAsDefault] = useState(false);
|
|
const extension = getFileExtension(fileName);
|
|
const canEdit = isTextFile(fileName);
|
|
const canPreview = isImageFile(fileName);
|
|
|
|
const handleSelect = useCallback((openerType: ExtendedFileOpenerType) => {
|
|
onSelect(openerType, setAsDefault);
|
|
onClose();
|
|
}, [onSelect, setAsDefault, onClose]);
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onClose()}>
|
|
<DialogContent className="sm:max-w-[400px]">
|
|
<DialogHeader>
|
|
<DialogTitle>{t('sftp.opener.title')}</DialogTitle>
|
|
<DialogDescription className="truncate">
|
|
{fileName}
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="py-4 space-y-2">
|
|
{canEdit && (
|
|
<Button
|
|
variant="outline"
|
|
className="w-full justify-start gap-3 h-12"
|
|
onClick={() => handleSelect('builtin-editor')}
|
|
>
|
|
<Edit2 size={18} className="text-primary" />
|
|
<div className="text-left">
|
|
<div className="font-medium text-sm">{t('sftp.opener.builtInEditor')}</div>
|
|
<div className="text-xs text-muted-foreground">Edit text files</div>
|
|
</div>
|
|
</Button>
|
|
)}
|
|
|
|
{canPreview && (
|
|
<Button
|
|
variant="outline"
|
|
className="w-full justify-start gap-3 h-12"
|
|
onClick={() => handleSelect('builtin-image-viewer')}
|
|
>
|
|
<Eye size={18} className="text-primary" />
|
|
<div className="text-left">
|
|
<div className="font-medium text-sm">{t('sftp.opener.builtInImageViewer')}</div>
|
|
<div className="text-xs text-muted-foreground">Preview images</div>
|
|
</div>
|
|
</Button>
|
|
)}
|
|
|
|
{/* System application option - TODO: Full implementation needed */}
|
|
<Button
|
|
variant="outline"
|
|
className="w-full justify-start gap-3 h-12"
|
|
onClick={() => handleSelect('system-app')}
|
|
>
|
|
<ExternalLink size={18} className="text-primary" />
|
|
<div className="text-left">
|
|
<div className="font-medium text-sm">{t('sftp.opener.systemApp')}</div>
|
|
<div className="text-xs text-muted-foreground">Open with system application</div>
|
|
</div>
|
|
</Button>
|
|
|
|
{!canEdit && !canPreview && (
|
|
<div className="text-sm text-muted-foreground text-center py-4">
|
|
{t('sftp.opener.onlySystemApp')}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{(canEdit || canPreview) && extension !== 'file' && (
|
|
<div className="flex items-center gap-2 pb-2">
|
|
<input
|
|
type="checkbox"
|
|
id="set-as-default"
|
|
checked={setAsDefault}
|
|
onChange={(e) => setSetAsDefault(e.target.checked)}
|
|
className="rounded border-border"
|
|
/>
|
|
<label htmlFor="set-as-default" className="text-sm text-muted-foreground cursor-pointer">
|
|
{t('sftp.opener.setDefault', { ext: extension })}
|
|
</label>
|
|
</div>
|
|
)}
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onClick={onClose}>
|
|
{t('common.cancel')}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
export default FileOpenerDialog;
|