From 60e64d580205f7ce3137da1941173ce4ee42c73e Mon Sep 17 00:00:00 2001 From: moist-webDev Date: Sat, 10 Jun 2023 22:31:45 -0400 Subject: [PATCH] ability to import and exprt data --- app.json | 2 +- package-lock.json | 11 ++++++- package.json | 2 ++ routes/Settings.tsx | 75 ++++++++++++++++++++++++++++++++++++--------- yarn.lock | 7 ++++- 5 files changed, 79 insertions(+), 18 deletions(-) diff --git a/app.json b/app.json index 3dbe6cd..20819b7 100644 --- a/app.json +++ b/app.json @@ -19,7 +19,7 @@ "userInterfaceStyle": "automatic" }, "android": { - "permissions":["READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"], + "permissions":["READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE", "INTERNET"], "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#ffffff" diff --git a/package-lock.json b/package-lock.json index 13db502..7d9d036 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,8 @@ "@rneui/themed": "^4.0.0-rc.7", "@types/react-native": "^0.72.1", "expo": "~48.0.15", + "expo-file-system": "^15.2.2", + "expo-media-library": "^15.2.3", "expo-status-bar": "~1.4.4", "react": "18.2.0", "react-native": "0.71.8", @@ -6049,7 +6051,6 @@ "version": "15.2.2", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.2.2.tgz", "integrity": "sha512-LFkOLcWwlmnjkURxZ3/0ukS35OswX8iuQknLHRHeyk8mUA8fpRPPelD/a1lS+yclqfqavMJmTXVKM1Nsq5XVMA==", - "license": "MIT", "dependencies": { "uuid": "^3.4.0" }, @@ -6087,6 +6088,14 @@ "expo": "*" } }, + "node_modules/expo-media-library": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/expo-media-library/-/expo-media-library-15.2.3.tgz", + "integrity": "sha512-Oz8b8Xsvfj7YcutUBtI84NUIqSnt7iCM5HZ5DyKoWKKiDK/+aUuj3RXNQELG8jUw6pQPgEwgbZ1+J8SdH/y9jw==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.2.0.tgz", diff --git a/package.json b/package.json index 8368f58..25f1f89 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "@rneui/themed": "^4.0.0-rc.7", "@types/react-native": "^0.72.1", "expo": "~48.0.15", + "expo-file-system": "^15.2.2", + "expo-media-library": "^15.2.3", "expo-status-bar": "~1.4.4", "react": "18.2.0", "react-native": "0.71.8", diff --git a/routes/Settings.tsx b/routes/Settings.tsx index 7bee3a4..316e67f 100644 --- a/routes/Settings.tsx +++ b/routes/Settings.tsx @@ -1,11 +1,16 @@ -import { StyleSheet, Text, View, Modal} from 'react-native'; +import { StyleSheet, Text, View, Modal, Alert} from 'react-native'; import Button from '../components/Button'; import { useState, useEffect } from 'react'; import DropDownPicker from 'react-native-dropdown-picker'; import db from '../lib/client'; +import { Platform } from 'react-native'; +import * as MediaLibrary from 'expo-media-library'; +import * as FileSystem from 'expo-file-system'; +const { StorageAccessFramework } = FileSystem; -export default function Settings({theme, changeTheme, themeMode, clearAll}:any){ + +export default function Settings({theme, changeTheme, themeMode, clearAll, resyncData}:any){ const [open, setOpen] = useState(false); const [value, setValue] = useState(themeMode); const [items, setItems] = useState([ @@ -19,13 +24,47 @@ export default function Settings({theme, changeTheme, themeMode, clearAll}:any){ const st = style(theme); - const test = async () => { - //const res = await db.from('test').insert({test: 'test'}); - const res2 = await db.from('test').update({row: 'updated again'}).eq({'id': 1}); - console.log(res2); - //const data = await AsyncStorage.getItem('test'); - const data = await db.from('test').select().eq(); - //console.log(data); + const handleExport = async () => { + const dataToExport = await db.fileExport() + const data = JSON.stringify(dataToExport); + // export dataToExport in json format to a file using react-native-fs + if (Platform.OS === 'android') { + const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync(); + if (permissions.granted) { + // Gets SAF URI from response + const uri = permissions.directoryUri; + // Writes file to SAF URI + await StorageAccessFramework.createFileAsync(uri, 'tali', 'application/json').then(async (fileUri) => { + await StorageAccessFramework.writeAsStringAsync(fileUri, data, { encoding: FileSystem.EncodingType.UTF8 }).catch((err) => console.log(err)) + }) + } + } + }; + + const handleImport = async () => { + StorageAccessFramework.requestDirectoryPermissionsAsync().then(async (permissions) => { + if (permissions.granted) { + const uri = permissions.directoryUri; + const fileUri = await StorageAccessFramework.readDirectoryAsync(uri).then((res) => { + for (let i = 0; i < res.length; i++) { + if (res[i].endsWith('tali.json')) { + return res[i]; + } + } + }) + if (fileUri) { + const data = await StorageAccessFramework.readAsStringAsync(fileUri).then((res) => res); + const dataToImport = JSON.parse(data); + const res = await db.fileImport(dataToImport); + if (res) { + resyncData(); + } else { + Alert.alert('Error importing data', 'File seems to be corrupted'); + clearAll(); + } + } + } + }) } @@ -33,7 +72,7 @@ export default function Settings({theme, changeTheme, themeMode, clearAll}:any){ return ( - + - - Choose Theme: + + Choose Theme: -