From 8161a07dba401f04dac93f861e6b2cffe53ab7e3 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 1 Oct 2022 00:42:50 +0200 Subject: Add in client updater, Notices API --- src/utils/IpcEvents.ts | 5 +++++ src/utils/misc.tsx | 30 +++++++++++++++++++++++++---- src/utils/types.ts | 2 ++ src/utils/updater.ts | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 src/utils/updater.ts (limited to 'src/utils') diff --git a/src/utils/IpcEvents.ts b/src/utils/IpcEvents.ts index 6061fcb..b0a53f2 100644 --- a/src/utils/IpcEvents.ts +++ b/src/utils/IpcEvents.ts @@ -19,4 +19,9 @@ export default strEnum({ SET_SETTINGS: "VencordSetSettings", OPEN_EXTERNAL: "VencordOpenExternal", OPEN_PATH: "VencordOpenPath", + GET_UPDATES: "VencordGetUpdates", + GET_REPO: "VencordGetRepo", + GET_HASHES: "VencordGetHashes", + UPDATE: "VencordUpdate", + BUILD: "VencordBuild" } as const); diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx index 8a9afe1..4159906 100644 --- a/src/utils/misc.tsx +++ b/src/utils/misc.tsx @@ -1,3 +1,4 @@ +import { FilterFn, find } from "../webpack"; import { React } from "../webpack/common"; /** @@ -7,9 +8,22 @@ import { React } from "../webpack/common"; */ export function lazy(factory: () => T): () => T { let cache: T; - return () => { - return cache ?? (cache = factory()); - }; + return () => cache ?? (cache = factory()); +} + +/** + * Do a lazy webpack search. Searches the module on first property access + * @param filter Filter function + * @returns Proxy. Note that only get and set are implemented, all other operations will have unexpected + * results. + */ +export function lazyWebpack(filter: FilterFn): T { + const getMod = lazy(() => find(filter)); + + return new Proxy({}, { + get: (_, prop) => getMod()[prop], + set: (_, prop, v) => getMod()[prop] = v + }) as T; } /** @@ -48,7 +62,7 @@ export function useAwaiter(factory: () => Promise, fallbackValue: T | null export function LazyComponent(factory: () => React.ComponentType) { return (props: T) => { const Component = React.useMemo(factory, []); - return ; + return ; }; } @@ -98,3 +112,11 @@ export function humanFriendlyJoin(elements: any[], mapper: (e: any) => string = return s; } + +/** + * Calls .join(" ") on the arguments + * classes("one", "two") => "one two" + */ +export function classes(...classes: string[]) { + return classes.join(" "); +} diff --git a/src/utils/types.ts b/src/utils/types.ts index f7936a4..05441e8 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -29,3 +29,5 @@ interface PluginDef { dependencies?: string[], required?: boolean; } + +export type IpcRes = { ok: true; value: V; } | { ok: false, error: any; }; diff --git a/src/utils/updater.ts b/src/utils/updater.ts new file mode 100644 index 0000000..b3fa812 --- /dev/null +++ b/src/utils/updater.ts @@ -0,0 +1,51 @@ +import IpcEvents from "./IpcEvents"; +import Logger from "./logger"; +import { IpcRes } from './types'; + +export const UpdateLogger = new Logger("Updater", "white"); +export let isOutdated = false; +export let changes: Record<"hash" | "author" | "message", string>[]; + +async function Unwrap(p: Promise>) { + const res = await p; + + if (res.ok) return res.value; + throw res.error; +} + +export async function checkForUpdates() { + changes = await Unwrap(VencordNative.ipc.invoke>(IpcEvents.GET_UPDATES)); + return (isOutdated = changes.length > 0); +} + +export async function update() { + if (!isOutdated) return true; + + const res = await Unwrap(VencordNative.ipc.invoke>(IpcEvents.UPDATE)); + + if (res) + isOutdated = false; + + return res; +} + +export function getRepo() { + return Unwrap(VencordNative.ipc.invoke>(IpcEvents.GET_REPO)); +} + +type Hashes = Record<"patcher.js" | "preload.js" | "renderer.js", string>; + +/** + * @returns true if hard restart is required + */ +export async function rebuild() { + const oldHashes = await Unwrap(VencordNative.ipc.invoke>(IpcEvents.GET_HASHES)); + + if (!await Unwrap(VencordNative.ipc.invoke>(IpcEvents.BUILD))) + throw new Error("The Build failed. Please try manually building the new update"); + + const newHashes = await Unwrap(VencordNative.ipc.invoke>(IpcEvents.GET_HASHES)); + + return oldHashes["patcher.js"] !== newHashes["patcher.js"] || + oldHashes["preload.js"] !== newHashes["preload.js"]; +} -- cgit