From f5e70afb35e64274f56cfae58bb5f8456787ff6e Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 14 Jul 2021 14:42:22 +0100 Subject: [PATCH] Experimental hooks. --- external/lang | 2 +- src/context/revoltjs/hooks.ts | 44 +++++++++++++++++++++++++++++++ src/pages/developer/Developer.tsx | 31 +++++++++++++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/external/lang b/external/lang index 9f72b064..1c24f933 160000 --- a/external/lang +++ b/external/lang @@ -1 +1 @@ -Subproject commit 9f72b064aad85293f332c3f7ce3f4fe5965def37 +Subproject commit 1c24f933c97ee0f04fabe9b35a62719295af5cd5 diff --git a/src/context/revoltjs/hooks.ts b/src/context/revoltjs/hooks.ts index bee86112..5eb575b6 100644 --- a/src/context/revoltjs/hooks.ts +++ b/src/context/revoltjs/hooks.ts @@ -1,9 +1,12 @@ +import isEqual from "lodash.isequal"; import { Client, PermissionCalculator } from "revolt.js"; import { Channels, Servers, Users } from "revolt.js/dist/api/objects"; import Collection from "revolt.js/dist/maps/Collection"; import { useCallback, useContext, useEffect, useState } from "preact/hooks"; +//#region Hooks v1 +// ! Hooks v1 will be deprecated soon. import { AppContext } from "./RevoltClient"; export interface HookContext { @@ -230,3 +233,44 @@ export function useServerPermission(id: string, context?: HookContext) { const calculator = new PermissionCalculator(ctx.client); return calculator.forServer(id); } +//#endregion + +//#region Hooks v2 +type CollectionKeys = Exclude< + keyof PickProperties>, + undefined +>; + +interface Depedency { + key: CollectionKeys; + id?: string; +} + +export function useData( + cb: (client: Client) => T, + dependencies: Depedency[], +): T { + // ! FIXME: not sure if this may cost a lot + const client = useContext(AppContext); + const [data, setData] = useState(cb(client)); + + useEffect(() => { + let fns = dependencies.map((dependency) => { + function update() { + let generated = cb(client); + if (!isEqual(data, generated)) { + setData(generated); + } + } + + client[dependency.key].addListener("update", update); + return () => + client[dependency.key].removeListener("update", update); + }); + + return () => fns.forEach((x) => x()); + }, [data]); + + return data; +} +//#endregion diff --git a/src/pages/developer/Developer.tsx b/src/pages/developer/Developer.tsx index 4b561d03..4c0f3cc0 100644 --- a/src/pages/developer/Developer.tsx +++ b/src/pages/developer/Developer.tsx @@ -1,4 +1,5 @@ import { Wrench } from "@styled-icons/boxicons-solid"; +import { Channels } from "revolt.js/dist/api/objects"; import { useContext } from "preact/hooks"; @@ -6,7 +7,7 @@ import PaintCounter from "../../lib/PaintCounter"; import { TextReact } from "../../lib/i18n"; import { AppContext } from "../../context/revoltjs/RevoltClient"; -import { useUserPermission } from "../../context/revoltjs/hooks"; +import { useData, useUserPermission } from "../../context/revoltjs/hooks"; import Header from "../../components/ui/Header"; @@ -34,6 +35,7 @@ export default function Developer() { fields={{ provider: GAMING! }} /> +
{/* Voice Status: {VoiceStatus[voice.status]} @@ -52,3 +54,30 @@ export default function Developer() {
); } + +function DataTest() { + const channel_id = ( + useContext(AppContext) + .channels.toArray() + .find((x) => x.channel_type === "Group") as Channels.GroupChannel + )._id; + + const data = useData( + (client) => { + return { + name: (client.channels.get(channel_id) as Channels.GroupChannel) + .name, + }; + }, + [{ key: "channels", id: channel_id }], + ); + + return ( +
+ Channel name: {data.name} +
+ +
+
+ ); +}