import React, { useEffect, useRef, useState } from 'react'; import { KeyboardAvoidingView, Modal, Platform, Pressable, ScrollView, Text, TextInput, View } from 'react-native'; import Ionicons from '@expo/vector-icons/Ionicons'; import { styles } from '../styles'; import { cn } from '../utils/cn'; export default function BackupModal({ visible, onClose, exportJson, importJson, setImportJson, exportFile, importFile, applyImport, }) { const exportInputRef = useRef(null); const [showExportJson, setShowExportJson] = useState(false); const [copyState, setCopyState] = useState('idle'); useEffect(() => { if (!visible) return; setShowExportJson(false); setCopyState('idle'); }, [visible]); useEffect(() => { if (copyState !== 'copied') return undefined; const timeout = setTimeout(() => setCopyState('idle'), 1400); return () => clearTimeout(timeout); }, [copyState]); async function handleCopyData() { if (Platform.OS === 'web' && typeof navigator !== 'undefined' && navigator.clipboard?.writeText) { try { await navigator.clipboard.writeText(exportJson); setCopyState('copied'); return; } catch { // fall through to manual copy fallback } } setShowExportJson(true); setCopyState('manual'); if (Platform.OS === 'android') { return; } requestAnimationFrame(() => { exportInputRef.current?.focus?.(); if (exportInputRef.current?.setNativeProps) { exportInputRef.current.setNativeProps({ selection: { start: 0, end: exportJson.length }, }); } }); } return ( Backup & Restore Close Export JSON Use Show JSON or Copy Data. setShowExportJson((prev) => !prev)}> {showExportJson ? 'Hide JSON' : 'Show JSON'} {copyState === 'copied' ? 'Copied' : 'Copy Data'} Export File {copyState === 'manual' ? ( Direct clipboard is unavailable here. JSON is shown for manual copy. ) : null} {showExportJson ? ( Platform.OS === 'android' ? ( {exportJson} ) : ( ) ) : null} Import JSON Paste a previous backup. This will replace current data. Pick Backup File Import & Replace ); }