Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client
117
fork

Configure Feed

Select the types of activity you want to include in your feed.

Display actual number of group clip clop requests (#10333)

authored by

DS Boyce and committed by
GitHub
9ba11baa 8d6d4f98

+103 -12
+38 -12
src/screens/Messages/ConversationSettings.tsx
··· 24 24 import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability' 25 25 import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members' 26 26 import {useLeaveConvo} from '#/state/queries/messages/leave-conversation' 27 + import {useListJoinRequestsQuery} from '#/state/queries/messages/list-join-requests' 27 28 import {useMuteConvo} from '#/state/queries/messages/mute-conversation' 28 29 import {useProfileBlockMutationQueue} from '#/state/queries/profile' 29 30 import {useSession} from '#/state/session' ··· 109 110 <Layout.Header.Slot /> 110 111 </Layout.Header.Outer> 111 112 <ConvoProvider key={convoId} convoId={convoId}> 112 - <SettingsInner /> 113 + <SettingsInner convoId={convoId} /> 113 114 </ConvoProvider> 114 115 </Layout.Screen> 115 116 ) ··· 119 120 return item.type === 'CHAT_MEMBER' ? item.profile.did : item.type 120 121 } 121 122 122 - function SettingsInner() { 123 + function SettingsInner({convoId}: {convoId: string}) { 123 124 const {t: l} = useLingui() 124 125 125 126 const initialNumToRender = useInitialNumToRender({minItemHeight: 68}) ··· 137 138 const data: bsky.profile.AnyProfileView[] = convo?.members ?? [] 138 139 const invites: string[] = [] 139 140 141 + const {data: joinRequestsData, hasNextPage: hasMoreRequests} = 142 + useListJoinRequestsQuery({ 143 + convoId, 144 + enabled: isOwner, 145 + }) 146 + const requestCount = 147 + joinRequestsData?.pages.reduce( 148 + (sum, page) => sum + page.requests.length, 149 + 0, 150 + ) ?? 0 151 + 140 152 const items = [ 141 153 { 142 154 type: 'MEMBERS_AND_REQUESTS', ··· 172 184 return ( 173 185 <MembersAndRequests 174 186 memberCount={data.length} 175 - requestCount={5} 187 + requestCount={requestCount} 188 + hasMoreRequests={!!hasMoreRequests} 176 189 isOwner={isOwner} 177 190 /> 178 191 ) ··· 229 242 function MembersAndRequests({ 230 243 memberCount, 231 244 requestCount, 245 + hasMoreRequests, 232 246 isOwner, 233 247 }: { 234 248 memberCount: number 235 249 requestCount: number 250 + hasMoreRequests: boolean 236 251 isOwner: boolean 237 252 }) { 238 253 const t = useTheme() ··· 245 260 <Trans>Members</Trans>{' '} 246 261 </Text> 247 262 <Text 248 - style={[ 249 - a.text_xs, 250 - a.font_medium, 251 - {color: t.palette.contrast_500}, 252 - ]}>{l`${memberCount}/${MEMBER_LIMIT}`}</Text> 263 + style={[a.text_xs, a.font_medium, {color: t.palette.contrast_500}]}> 264 + {l({ 265 + message: `${memberCount}/${MEMBER_LIMIT}`, 266 + comment: 267 + 'The number of group chat members out of the total number of permitted users.', 268 + })} 269 + </Text> 253 270 </View> 254 271 {isOwner && requestCount > 0 ? ( 255 272 <InlineLinkText 256 273 label={l`View incoming group chat requests`} 257 274 style={[a.text_sm, a.text_right, a.font_semi_bold]} 258 275 to="#"> 259 - {l`${plural(requestCount, { 260 - one: '# request', 261 - other: '# requests', 262 - })}`} 276 + {hasMoreRequests 277 + ? l({ 278 + message: `${requestCount}+ requests`, 279 + comment: 280 + 'Displayed when there are more than 50 requests to join a group chat', 281 + }) 282 + : l({ 283 + message: `${plural(requestCount, { 284 + one: '# request', 285 + other: '# requests', 286 + })}`, 287 + comment: 'The number of requests to join a group chat.', 288 + })} 263 289 </InlineLinkText> 264 290 ) : null} 265 291 </View>
+65
src/state/queries/messages/list-join-requests.ts
··· 1 + import {useEffect} from 'react' 2 + import {ChatBskyConvoDefs} from '@atproto/api' 3 + import {useInfiniteQuery, useQueryClient} from '@tanstack/react-query' 4 + 5 + import {DM_SERVICE_HEADERS} from '#/lib/constants' 6 + import {useMessagesEventBus} from '#/state/messages/events' 7 + import {createQueryKey} from '#/state/queries/util' 8 + import {useAgent} from '#/state/session' 9 + import {STALE} from '..' 10 + 11 + const listJoinRequestsQueryKeyRoot = 'list-join-requests' 12 + 13 + export const createListJoinRequestsQueryKey = (args: {convoId: string}) => 14 + createQueryKey(listJoinRequestsQueryKeyRoot, args) 15 + 16 + export function useListJoinRequestsQuery({ 17 + convoId, 18 + enabled, 19 + }: { 20 + convoId: string | undefined 21 + enabled?: boolean 22 + }) { 23 + const agent = useAgent() 24 + const queryClient = useQueryClient() 25 + const messagesBus = useMessagesEventBus() 26 + const isEnabled = enabled !== false && !!convoId 27 + 28 + useEffect(() => { 29 + if (!isEnabled || !convoId) return 30 + 31 + return messagesBus.on( 32 + event => { 33 + if (event.type !== 'logs') return 34 + for (const log of event.logs) { 35 + if ( 36 + ChatBskyConvoDefs.isLogIncomingJoinRequest(log) || 37 + ChatBskyConvoDefs.isLogApproveJoinRequest(log) || 38 + ChatBskyConvoDefs.isLogRejectJoinRequest(log) 39 + ) { 40 + void queryClient.invalidateQueries({ 41 + queryKey: createListJoinRequestsQueryKey({convoId}), 42 + }) 43 + return 44 + } 45 + } 46 + }, 47 + {convoId}, 48 + ) 49 + }, [isEnabled, convoId, messagesBus, queryClient]) 50 + 51 + return useInfiniteQuery({ 52 + enabled: isEnabled, 53 + queryKey: createListJoinRequestsQueryKey({convoId: convoId ?? ''}), 54 + queryFn: async ({pageParam}) => { 55 + const {data} = await agent.chat.bsky.group.listJoinRequests( 56 + {convoId: convoId!, cursor: pageParam, limit: 50}, 57 + {headers: DM_SERVICE_HEADERS}, 58 + ) 59 + return data 60 + }, 61 + initialPageParam: undefined as string | undefined, 62 + getNextPageParam: page => page.cursor, 63 + staleTime: STALE.MINUTES.ONE, 64 + }) 65 + }