Merge pull request #1104 from streetwriters/fix-migration-flow

Fix migration flow
This commit is contained in:
Ammar Ahmed
2022-09-29 20:26:03 +05:00
committed by GitHub
3 changed files with 121 additions and 41 deletions

View File

@@ -102,7 +102,8 @@ const Launcher = React.memo(
if (db.migrations.required() && !verifyUser) { if (db.migrations.required() && !verifyUser) {
presentSheet({ presentSheet({
component: <Migrate />, component: <Migrate />,
onClose: () => { onClose: async () => {
await db.init();
loadNotes(); loadNotes();
}, },
disableClosing: true disableClosing: true
@@ -117,10 +118,6 @@ const Launcher = React.memo(
} }
}, [loadNotes, verifyUser]); }, [loadNotes, verifyUser]);
// useEffect(() => {
// hideSplashScreen();
// }, [verifyUser]);
useEffect(() => { useEffect(() => {
if (!loading) { if (!loading) {
doAppLoadActions(); doAppLoadActions();

View File

@@ -20,22 +20,92 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react"; import React, { useState } from "react";
import { View } from "react-native"; import { View } from "react-native";
import { db } from "../../../common/database"; import { db } from "../../../common/database";
import { MMKV } from "../../../common/database/mmkv";
import BackupService from "../../../services/backup"; import BackupService from "../../../services/backup";
import { eSendEvent, ToastEvent } from "../../../services/event-manager"; import {
eSendEvent,
presentSheet,
ToastEvent
} from "../../../services/event-manager";
import { useThemeStore } from "../../../stores/use-theme-store"; import { useThemeStore } from "../../../stores/use-theme-store";
import { eCloseProgressDialog } from "../../../utils/events"; import { eCloseProgressDialog } from "../../../utils/events";
import { sleep } from "../../../utils/time"; import { sleep } from "../../../utils/time";
import { Dialog } from "../../dialog"; import { Dialog } from "../../dialog";
import DialogHeader from "../../dialog/dialog-header"; import DialogHeader from "../../dialog/dialog-header";
import { presentDialog } from "../../dialog/functions"; import { presentDialog } from "../../dialog/functions";
import SheetProvider from "../../sheet-provider";
import { Button } from "../../ui/button"; import { Button } from "../../ui/button";
import { Notice } from "../../ui/notice"; import { Notice } from "../../ui/notice";
import Seperator from "../../ui/seperator"; import Seperator from "../../ui/seperator";
import { ProgressBarComponent } from "../../ui/svg/lazy"; import { ProgressBarComponent } from "../../ui/svg/lazy";
import Paragraph from "../../ui/typography/paragraph"; import Paragraph from "../../ui/typography/paragraph";
import { Issue } from "../github/issue";
const alertMessage = `Read carefully before continuing:
It is required that you download and save a backup of your data.
Some merge conflicts in your notes after a migration are expected. It is recommended that you resolve them carefully. But if you are feeling reckless and want to risk losing some data, you can logout log back in.
If you face any other issues or are unsure about what to do, feel free to reach out to us via https://discord.com/invite/zQBK97EE22 or email us at support@streetwriters.co`;
export const makeError = (
stack: string,
component: string
) => `Please let us know what happened. What steps we can take to reproduce the issue here.
_______________________________
Stacktrace: In ${component}::${stack}`;
export default function Migrate() { export default function Migrate() {
const colors = useThemeStore((state) => state.colors); const colors = useThemeStore((state) => state.colors);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [_error, _setError] = useState<Error>();
const [reset, setReset] = useState(false);
const reportError = (error: Error) => {
_setError(error);
presentSheet({
context: "local",
component: (
<Issue
issueTitle={"Database migration failed"}
defaultBody={makeError(error.stack || "", "Migration")}
defaultTitle={error.message}
/>
)
});
};
const startMigration = async () => {
try {
setLoading(true);
const backupSaved = await BackupService.run(false, "local");
if (!backupSaved) {
ToastEvent.show({
heading: "Migration failed",
message: "You must download a backup of your data before migrating.",
context: "local"
});
setLoading(false);
return;
}
await db.migrations?.migrate();
eSendEvent(eCloseProgressDialog);
setLoading(false);
await sleep(500);
presentDialog({
title: "Migration successful",
paragraph:
"Your data has been migrated. If you face any issues after the migration please reach out to us via email or Discord.",
context: "global",
negativeText: "Ok"
});
} catch (e) {
setLoading(false);
reportError(e as Error);
}
};
return ( return (
<View <View
@@ -51,17 +121,7 @@ export default function Migrate() {
} }
/> />
<Seperator /> <Seperator />
<Notice <Notice type="alert" selectable={true} text={alertMessage} />
type="alert"
selectable={true}
text={`Read before continuing:
It is required that you download and save a backup of your data.
Some merge conflicts in your notes after a migration are expected. It is recommended that you resolve them carefully. But if you are feeling reckless and want to risk losing some data, you can logout log back in.
If you face any other issues or are unsure about what to do, feel free to reach out to us via https://discord.com/invite/zQBK97EE22 or email us at support@streetwriters.co`}
/>
{loading ? ( {loading ? (
<> <>
@@ -94,35 +154,51 @@ If you face any other issues or are unsure about what to do, feel free to reach
</Paragraph> </Paragraph>
</View> </View>
</> </>
) : _error ? (
<>
<Paragraph
style={{
marginTop: 20,
textAlign: "center"
}}
>
An error occured while migrating your data. You can logout of your
account and try to relogin. However this is not recommended as it
may result in some data loss if your data was not synced.
</Paragraph>
{reset ? (
<Paragraph
style={{
marginTop: 10,
textAlign: "center"
}}
>
App data has been cleared. Kindly relaunch the app to login again.
</Paragraph>
) : (
<Button
title="Logout & clear app data"
type="error"
width={250}
onPress={async () => {
MMKV.clearStore();
setReset(true);
}}
style={{
borderRadius: 100,
height: 45,
marginTop: 10
}}
/>
)}
</>
) : ( ) : (
<Button <Button
title="Start migration" title="Start migration"
type="accent" type="accent"
width={250} width={250}
onPress={async () => { onPress={startMigration}
setLoading(true);
const backupSaved = await BackupService.run(false, "local");
if (!backupSaved) {
ToastEvent.show({
heading: "Migration failed",
message:
"You must download a backup of your data before migrating.",
context: "local"
});
setLoading(false);
}
await db.migrations?.migrate();
eSendEvent(eCloseProgressDialog);
setLoading(false);
await sleep(500);
presentDialog({
title: "Migration successful",
paragraph:
"Your data has been migrated. If you face any issues after the migration please reach out to us via email or Discord.",
context: "global",
negativeText: "Ok"
});
}}
style={{ style={{
borderRadius: 100, borderRadius: 100,
height: 45, height: 45,
@@ -131,6 +207,7 @@ If you face any other issues or are unsure about what to do, feel free to reach
/> />
)} )}
<Dialog context="local" /> <Dialog context="local" />
<SheetProvider context="local" />
</View> </View>
); );
} }

View File

@@ -63,6 +63,8 @@ export const migrations = {
5.5: {}, 5.5: {},
5.6: { 5.6: {
notebook: (item) => { notebook: (item) => {
if (!item.topics) return item;
item.topics = item.topics.map((topic) => { item.topics = item.topics.map((topic) => {
delete topic.notes; delete topic.notes;
return topic; return topic;
@@ -70,7 +72,11 @@ export const migrations = {
return item; return item;
}, },
settings: async (item, db) => { settings: async (item, db) => {
if (!item.pins) return item;
for (const pin of item.pins) { for (const pin of item.pins) {
if (!pin.data) continue;
await db.shortcuts.add({ await db.shortcuts.add({
item: { item: {
type: pin.type, type: pin.type,