import { queryOptions, useSuspenseQuery } from '@tanstack/react-query' import { useCallback } from 'react' import { ApiCollection } from '../types' import type { FeatureResource } from '../types/resources/feature_resource' import { getFeaturesRequestArgs, getFeaturesQueryKey } from '../utils/request/get_features' import { FIVE_MINUTES, ONE_MINUTE } from '../utils/time' import { ApiClient, useApiClient } from './use_api_client' type FeatureName = (typeof availableFeatures)[keyof typeof availableFeatures] type FeaturesCollection = ApiCollection & { failure?: { status?: number } } export function useFeatures() { const apiClient = useApiClient() const { data } = useSuspenseQuery(featuresQueryOptions(apiClient)) const features = data.data const featureEnabled = useCallback( (featureName: FeatureName) => features.some(feature => feature.name === featureName && feature.enabled), [features] ) return { features, featureEnabled, } } export const featuresQueryOptions = (apiClient: ApiClient) => queryOptions({ queryKey: getFeaturesQueryKey(), queryFn: (): Promise => { return apiClient.chat .get>(getFeaturesRequestArgs()) .catch(error => ({ ...stableEmptyFeatures, failure: { status: error?.status } })) }, staleTime: query => { const failure = query.state.data?.failure if (!failure) return FIVE_MINUTES return failure.status === 429 ? ONE_MINUTE : 0 }, gcTime: Infinity, }) export const availableFeatures = { gender_specific_conversations: 'ROLLOUT_gender_specific_conversations', message_reporting: 'ROLLOUT_MOBILE_message_reporting', granular_notifications_ui: 'ROLLOUT_granular_notification_preferences_ui', custom_conversation_avatars: 'ROLLOUT_custom_conversation_avatars', conversation_safety_lock: 'ROLLOUT_conversation_safety_lock', video_moderation: 'ROLLOUT_MOBILE_video_moderation', dm_search_clear_fix: 'ROLLOUT_MOBILE_dm_search_clear_fix', search: 'QA_MOBILE_search', search_rollout: 'ROLLOUT_MOBILE_search', filter_dropdown: 'QA_MOBILE_filter_dropdown', filter_dropdown_rollout: 'ROLLOUT_MOBILE_filter_dropdown', manual_archiving: 'QA_MOBILE_manual_archiving', manual_archiving_rollout: 'ROLLOUT_MOBILE_manual_archiving', } as const satisfies Record const stableEmptyFeatures: ApiCollection = { data: [], links: {}, meta: { count: 0, totalCount: 0, }, }