diff --git a/external/lang b/external/lang index 9f72b064aad85293f332c3f7ce3f4fe5965def37..1c24f933c97ee0f04fabe9b35a62719295af5cd5 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 bee861126242b2e04f598e06f26244b87499accd..5eb575b6f3834e6763a348a26bff3dc7ba18772c 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<Client, Collection<any>>, + undefined +>; + +interface Depedency { + key: CollectionKeys; + id?: string; +} + +export function useData<T>( + 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 4b561d0323315e506fa3b489a1c7807e3c272416..4c0f3cc03cb19ad5f4e418a8d5a5f52b81768295 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: <b>GAMING!</b> }} /> </div> + <DataTest /> <div style={{ padding: "16px" }}> {/*<span> <b>Voice Status:</b> {VoiceStatus[voice.status]} @@ -52,3 +54,30 @@ export default function Developer() { </div> ); } + +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 ( + <div style={{ padding: "16px" }}> + Channel name: {data.name} + <div style={{ width: "24px" }}> + <PaintCounter small /> + </div> + </div> + ); +}