Compare commits

...

1 Commits

Author SHA1 Message Date
Eric Bailey 250fbc89e2 Sync prefs, add background task provider 2023-12-06 10:59:02 -06:00
4 changed files with 100 additions and 48 deletions
+4
View File
@@ -35,6 +35,7 @@ import {
} from 'state/session'
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
import * as persisted from '#/state/persisted'
import {AccountBackgroundTaskProvider} from '#/state/AccountBackgroundTaskProvider'
SplashScreen.preventAutoHideAsync()
@@ -69,6 +70,9 @@ function InnerApp() {
<React.Fragment
// Resets the entire tree below when it changes:
key={currentAccount?.did}>
{/* Must live inside the tree reset above */}
<AccountBackgroundTaskProvider />
<LoggedOutViewProvider>
<UnreadNotifsProvider>
<ThemeProvider theme={colorMode}>
+4
View File
@@ -29,6 +29,7 @@ import {
} from 'state/session'
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
import * as persisted from '#/state/persisted'
import {AccountBackgroundTaskProvider} from '#/state/AccountBackgroundTaskProvider'
function InnerApp() {
const {isInitialLoad, currentAccount} = useSession()
@@ -56,6 +57,9 @@ function InnerApp() {
<React.Fragment
// Resets the entire tree below when it changes:
key={currentAccount?.did}>
{/* Must live inside the tree reset above */}
<AccountBackgroundTaskProvider />
<LoggedOutViewProvider>
<UnreadNotifsProvider>
<ThemeProvider theme={colorMode}>
@@ -0,0 +1,24 @@
import React from 'react'
import {useSession} from '#/state/session'
import {useSyncPreferences} from '#/state/queries/preferences'
/**
* Must live inside our "tree-reset" fragment in App.tsx, so that when the
* current user changes, we clean up the intervals.
*/
export function AccountBackgroundTaskProvider() {
const {currentAccount} = useSession()
const syncPreferences = useSyncPreferences()
const preferencesSyncInterval = React.useRef<NodeJS.Timeout | undefined>(
undefined,
)
React.useEffect(() => {
if (!currentAccount) return
preferencesSyncInterval.current = setInterval(syncPreferences, 15e3)
return () => clearInterval(preferencesSyncInterval.current)
}, [currentAccount, syncPreferences])
return null
}
+68 -48
View File
@@ -1,6 +1,10 @@
import {useMemo} from 'react'
import {useMemo, useCallback} from 'react'
import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query'
import {LabelPreference, BskyFeedViewPreference} from '@atproto/api'
import {
LabelPreference,
BskyFeedViewPreference,
BskyPreferences,
} from '@atproto/api'
import {track} from '#/lib/analytics/analytics'
import {getAge} from '#/lib/strings/time'
@@ -26,6 +30,56 @@ export * from '#/state/queries/preferences/const'
export const preferencesQueryKey = ['getPreferences']
function mergePreferencesResponseWithDefaults(
res: BskyPreferences,
): UsePreferencesQueryResponse {
return {
...res,
feeds: {
saved: res.feeds?.saved || [],
pinned: res.feeds?.pinned || [],
unpinned:
res.feeds.saved?.filter(f => {
return !res.feeds.pinned?.includes(f)
}) || [],
},
// labels are undefined until set by user
contentLabels: {
nsfw: temp__migrateLabelPref(
res.contentLabels?.nsfw || DEFAULT_LABEL_PREFERENCES.nsfw,
),
nudity: temp__migrateLabelPref(
res.contentLabels?.nudity || DEFAULT_LABEL_PREFERENCES.nudity,
),
suggestive: temp__migrateLabelPref(
res.contentLabels?.suggestive || DEFAULT_LABEL_PREFERENCES.suggestive,
),
gore: temp__migrateLabelPref(
res.contentLabels?.gore || DEFAULT_LABEL_PREFERENCES.gore,
),
hate: temp__migrateLabelPref(
res.contentLabels?.hate || DEFAULT_LABEL_PREFERENCES.hate,
),
spam: temp__migrateLabelPref(
res.contentLabels?.spam || DEFAULT_LABEL_PREFERENCES.spam,
),
impersonation: temp__migrateLabelPref(
res.contentLabels?.impersonation ||
DEFAULT_LABEL_PREFERENCES.impersonation,
),
},
feedViewPrefs: {
...DEFAULT_HOME_FEED_PREFS,
...(res.feedViewPrefs.home || {}),
},
threadViewPrefs: {
...DEFAULT_THREAD_VIEW_PREFS,
...(res.threadViewPrefs ?? {}),
},
userAge: res.birthDate ? getAge(res.birthDate) : undefined,
}
}
export function usePreferencesQuery() {
return useQuery({
staleTime: STALE.MINUTES.ONE,
@@ -37,58 +91,24 @@ export function usePreferencesQuery() {
return DEFAULT_LOGGED_OUT_PREFERENCES
} else {
const res = await agent.getPreferences()
const preferences: UsePreferencesQueryResponse = {
...res,
feeds: {
saved: res.feeds?.saved || [],
pinned: res.feeds?.pinned || [],
unpinned:
res.feeds.saved?.filter(f => {
return !res.feeds.pinned?.includes(f)
}) || [],
},
// labels are undefined until set by user
contentLabels: {
nsfw: temp__migrateLabelPref(
res.contentLabels?.nsfw || DEFAULT_LABEL_PREFERENCES.nsfw,
),
nudity: temp__migrateLabelPref(
res.contentLabels?.nudity || DEFAULT_LABEL_PREFERENCES.nudity,
),
suggestive: temp__migrateLabelPref(
res.contentLabels?.suggestive ||
DEFAULT_LABEL_PREFERENCES.suggestive,
),
gore: temp__migrateLabelPref(
res.contentLabels?.gore || DEFAULT_LABEL_PREFERENCES.gore,
),
hate: temp__migrateLabelPref(
res.contentLabels?.hate || DEFAULT_LABEL_PREFERENCES.hate,
),
spam: temp__migrateLabelPref(
res.contentLabels?.spam || DEFAULT_LABEL_PREFERENCES.spam,
),
impersonation: temp__migrateLabelPref(
res.contentLabels?.impersonation ||
DEFAULT_LABEL_PREFERENCES.impersonation,
),
},
feedViewPrefs: {
...DEFAULT_HOME_FEED_PREFS,
...(res.feedViewPrefs.home || {}),
},
threadViewPrefs: {
...DEFAULT_THREAD_VIEW_PREFS,
...(res.threadViewPrefs ?? {}),
},
userAge: res.birthDate ? getAge(res.birthDate) : undefined,
}
const preferences = mergePreferencesResponseWithDefaults(res)
return preferences
}
},
})
}
export function useSyncPreferences() {
const queryClient = useQueryClient()
return useCallback(async () => {
queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
refetchType: 'none',
})
}, [queryClient])
}
export function useModerationOpts() {
const {currentAccount} = useSession()
const prefs = usePreferencesQuery()