diff --git a/src/core/ui/components/AddonPage.tsx b/src/core/ui/components/AddonPage.tsx index a906494..d57fa3e 100644 --- a/src/core/ui/components/AddonPage.tsx +++ b/src/core/ui/components/AddonPage.tsx @@ -78,7 +78,7 @@ export default function AddonPage({ card: CardComponent, ...pr icon={findAssetId("PlusLargeIcon")} onPress={props.onFABPress ?? (() => { // from ./InstallButton.tsx - clipboard.getString().then(content => + clipboard.getString().then((content: string) => showInputAlert({ initialValue: content.match(HTTP_REGEX_MULTI)?.[0] ?? "", placeholder: Strings.URL_PLACEHOLDER, diff --git a/src/lib/api/native/fs.ts b/src/lib/api/native/fs.ts index c5f2b93..43cd3d0 100644 --- a/src/lib/api/native/fs.ts +++ b/src/lib/api/native/fs.ts @@ -41,16 +41,11 @@ export async function writeFile(path: string, data: string, prefix = "pyoncord/" * @param path Path to the file * @param fallback Fallback data to return if the file doesn't exist, and will be written to the file */ -export async function readFile(path: string, fallback?: string | null, prefix = "pyoncord/"): Promise { +export async function readFile(path: string, prefix = "pyoncord/"): Promise { try { return await FileManager.readFile(`${FileManager.getConstants().DocumentsDirPath}/${prefix}${path}`, "utf8"); - } catch { - if (fallback == null) { - throw new Error(`Errored while reading ${path} doesn't exist`); - } - - await writeFile(path, fallback); - return fallback; + } catch (err) { + throw new Error(`An error occured while writing to '${path}'`, { cause: err }); } } diff --git a/src/lib/api/storage/new.ts b/src/lib/api/storage/new.ts index b48ccf8..6f7fc09 100644 --- a/src/lib/api/storage/new.ts +++ b/src/lib/api/storage/new.ts @@ -1,10 +1,12 @@ // New iteration of storage API, mostly yoinked from unreleased pyoncord (and sunrise?) import { fileExists, readFile, writeFile } from "@lib/api/native/fs"; import { Emitter } from "@lib/utils/emitter"; +import invariant from "@lib/utils/invariant"; interface StorageBackend { get: () => Promise; - set: (data: T) => void | Promise; + set: (data: T) => Promise; + exists: () => Promise; } const emitterSymbol = Symbol.for("bunny.storage.emitter"); @@ -13,12 +15,11 @@ const storagePromiseSymbol = Symbol.for("bunny.storage.promise"); const _loadedPath = {} as Record; -function createFileBackend(filePath: string, dflt = {} as T): StorageBackend { +function createFileBackend(filePath: string): StorageBackend { return { get: async () => { try { - const raw = await readFile(filePath, JSON.stringify(dflt)); - return JSON.parse(raw); + return JSON.parse(await readFile(filePath)); } catch (e) { throw new Error(`Failed to parse storage '${filePath}: ${e}'`); } @@ -26,6 +27,9 @@ function createFileBackend(filePath: string, dflt = {} as T): StorageBackend< set: async data => { if (!data || typeof data !== "object") throw new Error("data needs to be an object"); await writeFile(filePath, JSON.stringify(data)); + }, + exists: async () => { + return await fileExists(filePath); } }; } @@ -106,7 +110,6 @@ export function useProxy(storage: T & { [key in typeof storageInitErrorSymbol const [, forceUpdate] = React.useReducer(n => ~n, 0); React.useEffect(() => { - // TODO const listener = () => forceUpdate(); emitter.on("SET", listener); @@ -135,9 +138,18 @@ export function createStorageAndCallback(path: string, dflt = {} as T, cb: (p cb(proxy); }; - const backend = createFileBackend(path, dflt); + const backend = createFileBackend(path); if (_loadedPath[path]) callback(_loadedPath[path]); - else backend.get().then(d => callback(d)); + else { + backend.exists().then(async exists => { + if (!exists) { + await backend.set(dflt); + callback(dflt); + } else { + callback(await backend.get()); + } + }); + } } export async function createStorageAsync(path: string, dflt = {} as T): Promise { @@ -178,8 +190,11 @@ export async function preloadStorageIfExists(path: string) { if (_loadedPath[path]) return; if (!await fileExists(path)) return; - const data = await createFileBackend(path).get(); - _loadedPath[path] = data; + try { + const data = await createFileBackend(path).get(); + invariant(data !== undefined); + _loadedPath[path] = data; + } catch {} } export function awaitStorage(...proxies: any[]) {