Bluesky app fork with some witchin' additions 馃挮
at readme-update 126 lines 3.3 kB view raw
1import {ComAtprotoTempCheckHandleAvailability} from '@atproto/api' 2import {useQuery} from '@tanstack/react-query' 3 4import { 5 BSKY_SERVICE, 6 BSKY_SERVICE_DID, 7 PUBLIC_BSKY_SERVICE, 8} from '#/lib/constants' 9import {createFullHandle} from '#/lib/strings/handles' 10import {useDebouncedValue} from '#/components/live/utils' 11import {useAnalytics} from '#/analytics' 12import * as bsky from '#/types/bsky' 13import {Agent} from '../session/agent' 14 15export const RQKEY_handleAvailability = ( 16 handle: string, 17 domain: string, 18 serviceDid: string, 19) => ['handle-availability', {handle, domain, serviceDid}] 20 21export function useHandleAvailabilityQuery( 22 { 23 username, 24 serviceDomain, 25 serviceDid, 26 enabled, 27 birthDate, 28 email, 29 }: { 30 username: string 31 serviceDomain: string 32 serviceDid: string 33 enabled: boolean 34 birthDate?: string 35 email?: string 36 }, 37 debounceDelayMs = 500, 38) { 39 const ax = useAnalytics() 40 const name = username.trim() 41 const debouncedHandle = useDebouncedValue(name, debounceDelayMs) 42 43 return { 44 debouncedUsername: debouncedHandle, 45 enabled: enabled && name === debouncedHandle, 46 query: useQuery({ 47 enabled: enabled && name === debouncedHandle, 48 queryKey: RQKEY_handleAvailability( 49 debouncedHandle, 50 serviceDomain, 51 serviceDid, 52 ), 53 queryFn: async () => { 54 const handle = createFullHandle(name, serviceDomain) 55 const res = await checkHandleAvailability(handle, serviceDid, { 56 email, 57 birthDate, 58 }) 59 if (res.available) { 60 ax.metric('signup:handleAvailable', {typeahead: true}) 61 } else { 62 ax.metric('signup:handleTaken', {typeahead: true}) 63 } 64 return res 65 }, 66 }), 67 } 68} 69 70export async function checkHandleAvailability( 71 handle: string, 72 serviceDid: string, 73 { 74 email, 75 birthDate, 76 }: { 77 email?: string 78 birthDate?: string 79 }, 80) { 81 if (serviceDid === BSKY_SERVICE_DID) { 82 const agent = new Agent(null, {service: BSKY_SERVICE}) 83 // entryway has a special API for handle availability 84 const {data} = await agent.com.atproto.temp.checkHandleAvailability({ 85 handle, 86 birthDate, 87 email, 88 }) 89 90 if ( 91 bsky.dangerousIsType<ComAtprotoTempCheckHandleAvailability.ResultAvailable>( 92 data.result, 93 ComAtprotoTempCheckHandleAvailability.isResultAvailable, 94 ) 95 ) { 96 return {available: true} as const 97 } else if ( 98 bsky.dangerousIsType<ComAtprotoTempCheckHandleAvailability.ResultUnavailable>( 99 data.result, 100 ComAtprotoTempCheckHandleAvailability.isResultUnavailable, 101 ) 102 ) { 103 return { 104 available: false, 105 suggestions: data.result.suggestions, 106 } as const 107 } else { 108 throw new Error( 109 `Unexpected result of \`checkHandleAvailability\`: ${JSON.stringify(data.result)}`, 110 ) 111 } 112 } else { 113 // 3rd party PDSes won't have this API so just try and resolve the handle 114 const agent = new Agent(null, {service: PUBLIC_BSKY_SERVICE}) 115 try { 116 const res = await agent.resolveHandle({ 117 handle, 118 }) 119 120 if (res.data.did) { 121 return {available: false} as const 122 } 123 } catch {} 124 return {available: true} as const 125 } 126}