Experimental hooks.

This commit is contained in:
Paul 2021-07-14 14:42:22 +01:00
parent 7374591458
commit f5e70afb35
3 changed files with 75 additions and 2 deletions

2
external/lang vendored

@ -1 +1 @@
Subproject commit 9f72b064aad85293f332c3f7ce3f4fe5965def37 Subproject commit 1c24f933c97ee0f04fabe9b35a62719295af5cd5

View file

@ -1,9 +1,12 @@
import isEqual from "lodash.isequal";
import { Client, PermissionCalculator } from "revolt.js"; import { Client, PermissionCalculator } from "revolt.js";
import { Channels, Servers, Users } from "revolt.js/dist/api/objects"; import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
import Collection from "revolt.js/dist/maps/Collection"; import Collection from "revolt.js/dist/maps/Collection";
import { useCallback, useContext, useEffect, useState } from "preact/hooks"; import { useCallback, useContext, useEffect, useState } from "preact/hooks";
//#region Hooks v1
// ! Hooks v1 will be deprecated soon.
import { AppContext } from "./RevoltClient"; import { AppContext } from "./RevoltClient";
export interface HookContext { export interface HookContext {
@ -230,3 +233,44 @@ export function useServerPermission(id: string, context?: HookContext) {
const calculator = new PermissionCalculator(ctx.client); const calculator = new PermissionCalculator(ctx.client);
return calculator.forServer(id); 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

View file

@ -1,4 +1,5 @@
import { Wrench } from "@styled-icons/boxicons-solid"; import { Wrench } from "@styled-icons/boxicons-solid";
import { Channels } from "revolt.js/dist/api/objects";
import { useContext } from "preact/hooks"; import { useContext } from "preact/hooks";
@ -6,7 +7,7 @@ import PaintCounter from "../../lib/PaintCounter";
import { TextReact } from "../../lib/i18n"; import { TextReact } from "../../lib/i18n";
import { AppContext } from "../../context/revoltjs/RevoltClient"; 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"; import Header from "../../components/ui/Header";
@ -34,6 +35,7 @@ export default function Developer() {
fields={{ provider: <b>GAMING!</b> }} fields={{ provider: <b>GAMING!</b> }}
/> />
</div> </div>
<DataTest />
<div style={{ padding: "16px" }}> <div style={{ padding: "16px" }}>
{/*<span> {/*<span>
<b>Voice Status:</b> {VoiceStatus[voice.status]} <b>Voice Status:</b> {VoiceStatus[voice.status]}
@ -52,3 +54,30 @@ export default function Developer() {
</div> </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>
);
}