diff options
Diffstat (limited to 'src/components/hooks')
-rw-r--r-- | src/components/hooks/useFollowMethods.ts | 60 | ||||
-rw-r--r-- | src/components/hooks/useRichText.ts | 33 |
2 files changed, 93 insertions, 0 deletions
diff --git a/src/components/hooks/useFollowMethods.ts b/src/components/hooks/useFollowMethods.ts new file mode 100644 index 000000000..1e91a1f38 --- /dev/null +++ b/src/components/hooks/useFollowMethods.ts @@ -0,0 +1,60 @@ +import React from 'react' +import {AppBskyActorDefs} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {LogEvents} from '#/lib/statsig/statsig' +import {logger} from '#/logger' +import {Shadow} from '#/state/cache/types' +import {useProfileFollowMutationQueue} from '#/state/queries/profile' +import {useRequireAuth} from '#/state/session' +import * as Toast from '#/view/com/util/Toast' + +export function useFollowMethods({ + profile, + logContext, +}: { + profile: Shadow<AppBskyActorDefs.ProfileViewBasic> + logContext: LogEvents['profile:follow']['logContext'] & + LogEvents['profile:unfollow']['logContext'] +}) { + const {_} = useLingui() + const requireAuth = useRequireAuth() + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + logContext, + ) + + const follow = React.useCallback(() => { + requireAuth(async () => { + try { + await queueFollow() + } catch (e: any) { + logger.error(`useFollowMethods: failed to follow`, {message: String(e)}) + if (e?.name !== 'AbortError') { + Toast.show(_(msg`An issue occurred, please try again.`)) + } + } + }) + }, [_, queueFollow, requireAuth]) + + const unfollow = React.useCallback(() => { + requireAuth(async () => { + try { + await queueUnfollow() + } catch (e: any) { + logger.error(`useFollowMethods: failed to unfollow`, { + message: String(e), + }) + if (e?.name !== 'AbortError') { + Toast.show(_(msg`An issue occurred, please try again.`)) + } + } + }) + }, [_, queueUnfollow, requireAuth]) + + return { + follow, + unfollow, + } +} diff --git a/src/components/hooks/useRichText.ts b/src/components/hooks/useRichText.ts new file mode 100644 index 000000000..e363ae5a9 --- /dev/null +++ b/src/components/hooks/useRichText.ts @@ -0,0 +1,33 @@ +import React from 'react' +import {RichText as RichTextAPI} from '@atproto/api' + +import {getAgent} from '#/state/session' + +export function useRichText(text: string): [RichTextAPI, boolean] { + const [prevText, setPrevText] = React.useState(text) + const [rawRT, setRawRT] = React.useState(() => new RichTextAPI({text})) + const [resolvedRT, setResolvedRT] = React.useState<RichTextAPI | null>(null) + if (text !== prevText) { + setPrevText(text) + setRawRT(new RichTextAPI({text})) + setResolvedRT(null) + // This will queue an immediate re-render + } + React.useEffect(() => { + let ignore = false + async function resolveRTFacets() { + // new each time + const resolvedRT = new RichTextAPI({text}) + await resolvedRT.detectFacets(getAgent()) + if (!ignore) { + setResolvedRT(resolvedRT) + } + } + resolveRTFacets() + return () => { + ignore = true + } + }, [text]) + const isResolving = resolvedRT === null + return [resolvedRT ?? rawRT, isResolving] +} |