Last active
May 9, 2022 07:22
-
-
Save runeb/e59e07f1b89ae07c4819feddbfa027ca to your computer and use it in GitHub Desktop.
React hook for using a Sanity dataset as a general messaging system between users
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCallback, useEffect } from "react"; | |
import type { SanityClient, SanityDocument } from "@sanity/client"; | |
import {nanoid} from "nanoid" | |
type Params<T> = { | |
id: string; | |
client: SanityClient; | |
handler: (from: string, payload: T) => Promise<void>; | |
}; | |
export function useSanityMessaging<T>({ id, handler, client }: Params<T>) { | |
type Message = SanityDocument<{ | |
payload: T, | |
from: string | |
}> | |
// Sending a message to another party is done by creating a document with a | |
// known _type | |
const write = useCallback( | |
(to: string, payload: T) => { | |
client.create({ | |
...{ payload }, | |
from: id, | |
_id: `private.${nanoid()}`, | |
_type: `messages.${to}`, | |
}); | |
}, | |
[client, id] | |
); | |
// Receiving a message from another party is done by subscribing to created | |
// documents of a known _type | |
useEffect(() => { | |
const subscription = client | |
.listen<Message>("* [_type == $type]", { type: `messages.${id}` }) | |
.subscribe((update) => { | |
if (update.transition === "appear") { | |
// A document of the _type we're interested in was created | |
const document = update.result; | |
const { from, payload, _id } = document; | |
// Tell our handler, then delete the document | |
handler(from, payload).then(() => client.delete(_id)); | |
} | |
}); | |
return () => subscription.unsubscribe(); | |
}, [id, client]); | |
return write; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment