From ad6440c86e024c007d31110c0d938e90a2f1d958 Mon Sep 17 00:00:00 2001 From: Tristan Chin Date: Thu, 13 Jul 2023 01:12:23 -0400 Subject: [PATCH] [web] Add temporary migration for old users --- .../web/src/store/persist/migrateOldData.ts | 124 ++++++++++++++++++ .../src/store/persist/onStoreRehydrate.tsx | 4 + 2 files changed, 128 insertions(+) create mode 100644 packages/web/src/store/persist/migrateOldData.ts diff --git a/packages/web/src/store/persist/migrateOldData.ts b/packages/web/src/store/persist/migrateOldData.ts new file mode 100644 index 0000000..d5d3875 --- /dev/null +++ b/packages/web/src/store/persist/migrateOldData.ts @@ -0,0 +1,124 @@ +import { notifications } from "@mantine/notifications"; +import { CallableFunction, Conversation } from "gpt-turbo"; +import { addConversation } from "../actions/conversations/addConversation"; +import { setConversationName } from "../actions/conversations/setConversationName"; +import { setConversationLastEdit } from "../actions/conversations/setConversationLastEdit"; +import { addCallableFunction } from "../actions/callableFunctions/addCallableFunction"; +import { saveContext } from "../actions/savedContexts/saveContext"; +import { savePrompt } from "../actions/savedPrompts/savePrompt"; +import { setDefaultSettings } from "../actions/defaultConversationSettings/setDefaultSettings"; + +const notify = ( + title: string, + message: string, + color = "blue", + autoClose = true +) => { + setTimeout(() => { + notifications.show({ + color, + autoClose, + title, + message, + }); + }, 100); +}; + +// TODO: Remove this after a while. This is to migrate users from the old persistence system to the new one. +// Not EVERYTHING is migrated, but the most important things are. +export const migrateOldData = async () => { + const oldPersistence = localStorage.getItem("gpt-turbo-persistence"); + const oldSettings = localStorage.getItem("gpt-turbo-settings"); + + if (oldPersistence) { + let deleteAfter = true; + try { + const { conversations, functions, contexts, prompts } = + JSON.parse(oldPersistence); + for (const { name, lastEdited, ...conversation } of conversations) { + try { + const c = await Conversation.fromJSON(conversation); + addConversation(c); + setConversationName(c.id, name); + setConversationLastEdit(c.id, lastEdited); + } catch (e) { + deleteAfter = false; + console.error(e); + notify( + "Conversation Migration Failed", + "Failed to migrate one of your conversations to the new storage system.", + "red", + false + ); + } + } + + for (const { displayName, code, ...fn } of functions) { + try { + const f = CallableFunction.fromJSON(fn); + addCallableFunction(f, displayName, code); + } catch (e) { + deleteAfter = false; + console.error(e); + notify( + "Callable Function Migration Failed", + "Failed to migrate one of your callable functions to the new storage system.", + "red", + false + ); + } + } + + for (const { name, value } of contexts) { + saveContext(name, value); + } + + for (const { name, value } of prompts) { + savePrompt(name, value); + } + + if (deleteAfter) { + localStorage.removeItem("gpt-turbo-persistence"); + notify( + "Persistence Migration Complete", + "Your old saved data has been migrated to the new storage system!", + "green" + ); + } else { + notify( + "Persistence Migration Partially Complete", + "Only some of your old saved data has been migrated to the new storage system. Please check the console for more details.", + "yellow" + ); + } + } catch (e) { + console.error(e); + notify( + "Persistence Migration Failed", + "Failed to migrate your old saved data to the new storage system.", + "red", + false + ); + } + } + + if (oldSettings) { + try { + setDefaultSettings(JSON.parse(oldSettings)); + localStorage.removeItem("gpt-turbo-settings"); + notify( + "Settings Migration Complete", + "Your old settings have been migrated to the new storage system!", + "green" + ); + } catch (e) { + console.error(e); + notify( + "Settings Migration Failed", + "Failed to migrate your old settings to the new storage system.", + "red", + false + ); + } + } +}; diff --git a/packages/web/src/store/persist/onStoreRehydrate.tsx b/packages/web/src/store/persist/onStoreRehydrate.tsx index c9c9132..48e2772 100644 --- a/packages/web/src/store/persist/onStoreRehydrate.tsx +++ b/packages/web/src/store/persist/onStoreRehydrate.tsx @@ -5,11 +5,15 @@ import StorageLoadError from "../../components/StorageLoadError"; import { STORAGE_PERSISTENCE_KEY } from "../../config/constants"; import { StoreMigrationError } from "./migrations"; import getErrorInfo from "../../utils/getErrorInfo"; +import { migrateOldData } from "./migrateOldData"; export const onStoreRehydrate = ( _state: AppState ): void | ((state?: AppState, error?: unknown) => void) => { return (_hydratedState, e) => { + // TODO: Remove this after a while to give time for users to migrate to new storage + migrateOldData(); + if (!e) return; const error = e as Error; const isMigrationError = error instanceof StoreMigrationError;