import {useMemo, useState} from 'react' import {type TextStyle, View, type ViewStyle} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {type NativeStackScreenProps} from '@react-navigation/native-stack' import {useQueryClient} from '@tanstack/react-query' import debounce from 'lodash.debounce' import {type CommonNavigatorParams} from '#/lib/routes/types' import { preferencesQueryKey, usePreferencesQuery, } from '#/state/queries/preferences' import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {createGetSuggestedFeedsQueryKey} from '#/state/queries/trending/useGetSuggestedFeedsQuery' import {createGetSuggestedUsersQueryKey} from '#/state/queries/trending/useGetSuggestedUsersQuery' import {createSuggestedStarterPacksQueryKey} from '#/state/queries/useSuggestedStarterPacksQuery' import {useAgent} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {useInterestsDisplayNames} from '#/screens/Onboarding/state' import {atoms as a, useGutters, useTheme} from '#/alf' import {Admonition} from '#/components/Admonition' import {Divider} from '#/components/Divider' import * as Toggle from '#/components/forms/Toggle' import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' type Props = NativeStackScreenProps export function InterestsSettingsScreen({}: Props) { const t = useTheme() const gutters = useGutters(['base']) const {data: preferences} = usePreferencesQuery() const [isSaving, setIsSaving] = useState(false) return ( Your interests {isSaving && } Your selected interests help us serve you content you care about. {preferences ? ( ) : ( )} ) } function Inner({ preferences, setIsSaving, }: { preferences: UsePreferencesQueryResponse setIsSaving: (isSaving: boolean) => void }) { const {_} = useLingui() const agent = useAgent() const qc = useQueryClient() const interestsDisplayNames = useInterestsDisplayNames() const preselectedInterests = useMemo( () => preferences.interests.tags || [], [preferences.interests.tags], ) const [interests, setInterests] = useState(preselectedInterests) const saveInterests = useMemo(() => { return debounce(async (interests: string[]) => { const noEdits = interests.length === preselectedInterests.length && preselectedInterests.every(pre => { return interests.find(int => int === pre) }) if (noEdits) return setIsSaving(true) try { await agent.setInterestsPref({tags: interests}) qc.setQueriesData( {queryKey: preferencesQueryKey}, (old?: UsePreferencesQueryResponse) => { if (!old) return old old.interests.tags = interests return old }, ) await Promise.all([ qc.resetQueries({queryKey: createSuggestedStarterPacksQueryKey()}), qc.resetQueries({queryKey: createGetSuggestedFeedsQueryKey()}), qc.resetQueries({queryKey: createGetSuggestedUsersQueryKey({})}), ]) Toast.show( _( msg({ message: 'Your interests have been updated!', context: 'toast', }), ), ) } catch (error) { Toast.show( _( msg({ message: 'Failed to save your interests.', context: 'toast', }), ), 'xmark', ) } finally { setIsSaving(false) } }, 1500) }, [_, agent, setIsSaving, qc, preselectedInterests]) const onChangeInterests = async (interests: string[]) => { setInterests(interests) saveInterests(interests) } return ( <> {interests.length === 0 && ( We recommend selecting at least two interests. )} {INTERESTS.map(interest => { const name = interestsDisplayNames[interest] if (!name) return null return ( ) })} ) } export function InterestButton({interest}: {interest: string}) { const t = useTheme() const interestsDisplayNames = useInterestsDisplayNames() const ctx = Toggle.useItemContext() const styles = useMemo(() => { const hovered: ViewStyle[] = [t.atoms.bg_contrast_100] const focused: ViewStyle[] = [] const pressed: ViewStyle[] = [] const selected: ViewStyle[] = [t.atoms.bg_contrast_900] const selectedHover: ViewStyle[] = [t.atoms.bg_contrast_975] const textSelected: TextStyle[] = [t.atoms.text_inverted] return { hovered, focused, pressed, selected, selectedHover, textSelected, } }, [t]) return ( {interestsDisplayNames[interest]} ) } const INTERESTS = [ 'animals', 'art', 'books', 'comedy', 'comics', 'culture', 'dev', 'education', 'food', 'gaming', 'journalism', 'movies', 'music', 'nature', 'news', 'pets', 'photography', 'politics', 'science', 'sports', 'tech', 'tv', 'writers', ]