mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 04:00:59 +01:00
mobile: fix restore backup
This commit is contained in:
@@ -17,14 +17,21 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { LegendList } from "@legendapp/list";
|
||||
import { formatBytes, getFormattedDate } from "@notesnook/common";
|
||||
import { LegacyBackupFile } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { keepLocalCopy, pick } from "@react-native-documents/picker";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { ActivityIndicator, FlatList, Platform, View } from "react-native";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
FlatList,
|
||||
Platform,
|
||||
ScrollView,
|
||||
View
|
||||
} from "react-native";
|
||||
import RNFetchBlob, { ReactNativeBlobUtilStat } from "react-native-blob-util";
|
||||
import { pick, keepLocalCopy } from "@react-native-documents/picker";
|
||||
import * as ScopedStorage from "react-native-scoped-storage";
|
||||
import { unzip } from "react-native-zip-archive";
|
||||
import { DatabaseLogger, db } from "../../../common/database";
|
||||
@@ -323,6 +330,7 @@ export const RestoreBackup = () => {
|
||||
|
||||
setFiles(files);
|
||||
BACKUP_FILES_CACHE.splice(0, BACKUP_FILES_CACHE.length, ...files);
|
||||
setLoading(false);
|
||||
} catch (e) {
|
||||
e;
|
||||
} finally {
|
||||
@@ -343,160 +351,152 @@ export const RestoreBackup = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<FlatList
|
||||
data={[0]}
|
||||
renderItem={() => {
|
||||
return (
|
||||
<View>
|
||||
<SectionItem
|
||||
item={{
|
||||
id: "restore-from-files",
|
||||
name: strings.restoreFromFiles(),
|
||||
icon: "folder",
|
||||
modifer: async () => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: true
|
||||
});
|
||||
const file = await pick();
|
||||
|
||||
const fileCopy = await keepLocalCopy({
|
||||
destination: "cachesDirectory",
|
||||
files: [
|
||||
{
|
||||
uri: file[0].uri,
|
||||
fileName:
|
||||
file[0].name ?? `backup_restore_${Date.now()}`
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (fileCopy[0].status === "error") {
|
||||
ToastManager.error(new Error("File copy error"));
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: false
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
restoreBackup({
|
||||
uri:
|
||||
Platform.OS === "android"
|
||||
? (("file://" + fileCopy[0].sourceUri) as string)
|
||||
: (fileCopy[0].sourceUri as string),
|
||||
deleteFile: true
|
||||
});
|
||||
},
|
||||
description: strings.selectBackupFileDesc()
|
||||
}}
|
||||
/>
|
||||
|
||||
{Platform.OS === "android" ? (
|
||||
<SectionItem
|
||||
item={{
|
||||
id: "select-backup-folder",
|
||||
name: strings.selectBackupFolder(),
|
||||
icon: "folder",
|
||||
modifer: async () => {
|
||||
const folder = await ScopedStorage.openDocumentTree(true);
|
||||
let subfolder;
|
||||
if (folder.name !== "Notesnook backups") {
|
||||
subfolder = await ScopedStorage.createDirectory(
|
||||
folder.uri,
|
||||
"Notesnook backups"
|
||||
);
|
||||
} else {
|
||||
subfolder = folder;
|
||||
}
|
||||
SettingsService.set({
|
||||
backupDirectoryAndroid: subfolder
|
||||
});
|
||||
setBackupDirectoryAndroid(subfolder);
|
||||
setLoading(true);
|
||||
checkBackups();
|
||||
},
|
||||
description: strings.selectFolderForBackupFilesDesc()
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<FlatList
|
||||
ListHeaderComponent={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.primary.background,
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
color={colors.primary.accent}
|
||||
size={AppFontSize.xs}
|
||||
>
|
||||
{strings.recentBackups()}
|
||||
</Heading>
|
||||
</View>
|
||||
}
|
||||
stickyHeaderIndices={[0]}
|
||||
ListEmptyComponent={
|
||||
loading ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 300,
|
||||
paddingHorizontal: 50
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color={colors.primary.accent}
|
||||
size={AppFontSize.lg}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
height: 300,
|
||||
paddingHorizontal: 50
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{strings.noBackupsFound()}.
|
||||
</Paragraph>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
windowSize={2}
|
||||
keyExtractor={(item) =>
|
||||
(item as ScopedStorage.FileType).name ||
|
||||
(item as ReactNativeBlobUtilStat).filename
|
||||
}
|
||||
style={{
|
||||
paddingHorizontal: DefaultAppStyles.GAP
|
||||
}}
|
||||
ListFooterComponent={
|
||||
<View
|
||||
style={{
|
||||
height: 200
|
||||
}}
|
||||
/>
|
||||
}
|
||||
data={files}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
<ScrollView
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<SectionItem
|
||||
item={{
|
||||
id: "restore-from-files",
|
||||
name: strings.restoreFromFiles(),
|
||||
icon: "folder",
|
||||
modifer: async () => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: true
|
||||
});
|
||||
const file = await pick();
|
||||
|
||||
const fileCopy = await keepLocalCopy({
|
||||
destination: "cachesDirectory",
|
||||
files: [
|
||||
{
|
||||
uri: file[0].uri,
|
||||
fileName: file[0].name ?? `backup_restore_${Date.now()}`
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (fileCopy[0].status === "error") {
|
||||
ToastManager.error(new Error("File copy error"));
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: false
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
restoreBackup({
|
||||
uri:
|
||||
Platform.OS === "android"
|
||||
? (("file://" + fileCopy[0].sourceUri) as string)
|
||||
: (fileCopy[0].sourceUri as string),
|
||||
deleteFile: true
|
||||
});
|
||||
},
|
||||
description: strings.selectBackupFileDesc()
|
||||
}}
|
||||
/>
|
||||
|
||||
{Platform.OS === "android" ? (
|
||||
<SectionItem
|
||||
item={{
|
||||
id: "select-backup-folder",
|
||||
name: strings.selectBackupFolder(),
|
||||
icon: "folder",
|
||||
modifer: async () => {
|
||||
const folder = await ScopedStorage.openDocumentTree(true);
|
||||
let subfolder;
|
||||
if (folder.name !== "Notesnook backups") {
|
||||
subfolder = await ScopedStorage.createDirectory(
|
||||
folder.uri,
|
||||
"Notesnook backups"
|
||||
);
|
||||
} else {
|
||||
subfolder = folder;
|
||||
}
|
||||
SettingsService.set({
|
||||
backupDirectoryAndroid: subfolder
|
||||
});
|
||||
setBackupDirectoryAndroid(subfolder);
|
||||
setLoading(true);
|
||||
checkBackups();
|
||||
},
|
||||
description: strings.selectFolderForBackupFilesDesc()
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<LegendList
|
||||
ListHeaderComponent={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.primary.background,
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL,
|
||||
paddingHorizontal: DefaultAppStyles.GAP
|
||||
}}
|
||||
>
|
||||
<Heading color={colors.primary.accent} size={AppFontSize.xs}>
|
||||
{strings.recentBackups()}
|
||||
</Heading>
|
||||
</View>
|
||||
}
|
||||
ListEmptyComponent={
|
||||
loading ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 300,
|
||||
paddingHorizontal: 50
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color={colors.primary.accent}
|
||||
size={AppFontSize.lg}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
height: 300,
|
||||
paddingHorizontal: 50
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{strings.noBackupsFound()}.
|
||||
</Paragraph>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
keyExtractor={(item) =>
|
||||
(item as ScopedStorage.FileType).name ||
|
||||
(item as ReactNativeBlobUtilStat).filename
|
||||
}
|
||||
ListFooterComponent={
|
||||
<View
|
||||
style={{
|
||||
height: 200
|
||||
}}
|
||||
/>
|
||||
}
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
data={files}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</ScrollView>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -530,10 +530,16 @@ const BackupItem = ({
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 0.5,
|
||||
borderBottomColor: colors.primary.border,
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL,
|
||||
paddingHorizontal: DefaultAppStyles.GAP,
|
||||
gap: DefaultAppStyles.GAP_SMALL
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
<View
|
||||
style={{
|
||||
flexShrink: 1
|
||||
}}
|
||||
>
|
||||
<Paragraph size={AppFontSize.sm}>{itemName}</Paragraph>
|
||||
<Paragraph
|
||||
size={AppFontSize.xs}
|
||||
|
||||
Reference in New Issue
Block a user