about summary refs log tree commit diff
path: root/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'src/state')
-rw-r--r--src/state/queries/preferences/const.ts24
-rw-r--r--src/state/queries/preferences/index.ts129
-rw-r--r--src/state/queries/preferences/moderation.ts18
-rw-r--r--src/state/queries/preferences/types.ts5
-rw-r--r--src/state/session/index.tsx17
-rw-r--r--src/state/shell/index.tsx31
-rw-r--r--src/state/shell/logged-out.tsx37
7 files changed, 185 insertions, 76 deletions
diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts
index 5db137e58..b7f9206e8 100644
--- a/src/state/queries/preferences/const.ts
+++ b/src/state/queries/preferences/const.ts
@@ -2,6 +2,7 @@ import {
   UsePreferencesQueryResponse,
   ThreadViewPreferences,
 } from '#/state/queries/preferences/types'
+import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation'
 
 export const DEFAULT_HOME_FEED_PREFS: UsePreferencesQueryResponse['feedViewPrefs'] =
   {
@@ -25,3 +26,26 @@ export const DEFAULT_PROD_FEEDS = {
   pinned: [DEFAULT_PROD_FEED_PREFIX('whats-hot')],
   saved: [DEFAULT_PROD_FEED_PREFIX('whats-hot')],
 }
+
+export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
+  birthDate: new Date('2022-11-17'), // TODO(pwi)
+  adultContentEnabled: false,
+  feeds: {
+    saved: [],
+    pinned: [],
+    unpinned: [],
+  },
+  // labels are undefined until set by user
+  contentLabels: {
+    nsfw: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.nsfw,
+    nudity: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.nudity,
+    suggestive: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.suggestive,
+    gore: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.gore,
+    hate: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.hate,
+    spam: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.spam,
+    impersonation: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES.impersonation,
+  },
+  feedViewPrefs: DEFAULT_HOME_FEED_PREFS,
+  threadViewPrefs: DEFAULT_THREAD_VIEW_PREFS,
+  userAge: 13, // TODO(pwi)
+}
diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts
index e7fa3b15b..afdec267d 100644
--- a/src/state/queries/preferences/index.ts
+++ b/src/state/queries/preferences/index.ts
@@ -15,6 +15,7 @@ import {temp__migrateLabelPref} from '#/state/queries/preferences/util'
 import {
   DEFAULT_HOME_FEED_PREFS,
   DEFAULT_THREAD_VIEW_PREFS,
+  DEFAULT_LOGGED_OUT_PREFERENCES,
 } from '#/state/queries/preferences/const'
 import {getModerationOpts} from '#/state/queries/preferences/moderation'
 import {STALE} from '#/state/queries'
@@ -23,63 +24,67 @@ export * from '#/state/queries/preferences/types'
 export * from '#/state/queries/preferences/moderation'
 export * from '#/state/queries/preferences/const'
 
-export const usePreferencesQueryKey = ['getPreferences']
+export const preferencesQueryKey = ['getPreferences']
 
 export function usePreferencesQuery() {
-  const {hasSession} = useSession()
   return useQuery({
-    enabled: hasSession,
     staleTime: STALE.MINUTES.ONE,
-    queryKey: usePreferencesQueryKey,
+    queryKey: preferencesQueryKey,
     queryFn: async () => {
-      const res = await getAgent().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 agent = getAgent()
+
+      if (agent.session?.did === undefined) {
+        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,
+        }
+        return preferences
       }
-      return preferences
     },
   })
 }
@@ -107,7 +112,7 @@ export function useClearPreferencesMutation() {
       await getAgent().app.bsky.actor.putPreferences({preferences: []})
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -125,7 +130,7 @@ export function usePreferencesSetContentLabelMutation() {
       await getAgent().setContentLabelPref(labelGroup, visibility)
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -139,7 +144,7 @@ export function usePreferencesSetAdultContentMutation() {
       await getAgent().setAdultContentEnabled(enabled)
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -153,7 +158,7 @@ export function usePreferencesSetBirthDateMutation() {
       await getAgent().setPersonalDetails({birthDate})
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -167,7 +172,7 @@ export function useSetFeedViewPreferencesMutation() {
       await getAgent().setFeedViewPrefs('home', prefs)
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -181,7 +186,7 @@ export function useSetThreadViewPreferencesMutation() {
       await getAgent().setThreadViewPrefs(prefs)
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -199,7 +204,7 @@ export function useSetSaveFeedsMutation() {
       await getAgent().setSavedFeeds(saved, pinned)
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -214,7 +219,7 @@ export function useSaveFeedMutation() {
       track('CustomFeed:Save')
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -229,7 +234,7 @@ export function useRemoveFeedMutation() {
       track('CustomFeed:Unsave')
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -244,7 +249,7 @@ export function usePinFeedMutation() {
       track('CustomFeed:Pin', {uri})
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
@@ -259,7 +264,7 @@ export function useUnpinFeedMutation() {
       track('CustomFeed:Unpin', {uri})
       // triggers a refetch
       await queryClient.invalidateQueries({
-        queryKey: usePreferencesQueryKey,
+        queryKey: preferencesQueryKey,
       })
     },
   })
diff --git a/src/state/queries/preferences/moderation.ts b/src/state/queries/preferences/moderation.ts
index a26380a36..cdae52937 100644
--- a/src/state/queries/preferences/moderation.ts
+++ b/src/state/queries/preferences/moderation.ts
@@ -34,6 +34,24 @@ export const DEFAULT_LABEL_PREFERENCES: Record<
   impersonation: 'hide',
 }
 
+/**
+ * More strict than our default settings for logged in users.
+ *
+ * TODO(pwi)
+ */
+export const DEFAULT_LOGGED_OUT_LABEL_PREFERENCES: Record<
+  ConfigurableLabelGroup,
+  LabelPreference
+> = {
+  nsfw: 'hide',
+  nudity: 'hide',
+  suggestive: 'hide',
+  gore: 'hide',
+  hate: 'hide',
+  spam: 'hide',
+  impersonation: 'hide',
+}
+
 export const ILLEGAL_LABEL_GROUP: LabelGroupConfig = {
   id: 'illegal',
   title: 'Illegal Content',
diff --git a/src/state/queries/preferences/types.ts b/src/state/queries/preferences/types.ts
index ff7420673..5fca8d558 100644
--- a/src/state/queries/preferences/types.ts
+++ b/src/state/queries/preferences/types.ts
@@ -43,7 +43,10 @@ export type UsePreferencesQueryResponse = Omit<
   }
 }
 
-export type ThreadViewPreferences = Omit<BskyThreadViewPreference, 'sort'> & {
+export type ThreadViewPreferences = Pick<
+  BskyThreadViewPreference,
+  'prioritizeFollowedUsers'
+> & {
   sort: 'oldest' | 'newest' | 'most-likes' | 'random' | string
   lab_treeViewEnabled?: boolean
 }
diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx
index 97bd6e976..d7541295b 100644
--- a/src/state/session/index.tsx
+++ b/src/state/session/index.tsx
@@ -8,6 +8,7 @@ import * as persisted from '#/state/persisted'
 import {PUBLIC_BSKY_AGENT} from '#/state/queries'
 import {IS_PROD} from '#/lib/constants'
 import {emitSessionLoaded, emitSessionDropped} from '../events'
+import {useLoggedOutViewControls} from '#/state/shell/logged-out'
 
 let __globalAgent: BskyAgent = PUBLIC_BSKY_AGENT
 
@@ -515,3 +516,19 @@ export function useSession() {
 export function useSessionApi() {
   return React.useContext(ApiContext)
 }
+
+export function useRequireAuth() {
+  const {hasSession} = useSession()
+  const {setShowLoggedOut} = useLoggedOutViewControls()
+
+  return React.useCallback(
+    (fn: () => void) => {
+      if (hasSession) {
+        fn()
+      } else {
+        setShowLoggedOut(true)
+      }
+    },
+    [hasSession, setShowLoggedOut],
+  )
+}
diff --git a/src/state/shell/index.tsx b/src/state/shell/index.tsx
index 53f05055c..897a66020 100644
--- a/src/state/shell/index.tsx
+++ b/src/state/shell/index.tsx
@@ -7,6 +7,7 @@ import {Provider as ColorModeProvider} from './color-mode'
 import {Provider as OnboardingProvider} from './onboarding'
 import {Provider as ComposerProvider} from './composer'
 import {Provider as TickEveryMinuteProvider} from './tick-every-minute'
+import {Provider as LoggedOutViewProvider} from './logged-out'
 
 export {useIsDrawerOpen, useSetDrawerOpen} from './drawer-open'
 export {
@@ -22,19 +23,23 @@ export {useTickEveryMinute} from './tick-every-minute'
 export function Provider({children}: React.PropsWithChildren<{}>) {
   return (
     <ShellLayoutProvder>
-      <DrawerOpenProvider>
-        <DrawerSwipableProvider>
-          <MinimalModeProvider>
-            <ColorModeProvider>
-              <OnboardingProvider>
-                <ComposerProvider>
-                  <TickEveryMinuteProvider>{children}</TickEveryMinuteProvider>
-                </ComposerProvider>
-              </OnboardingProvider>
-            </ColorModeProvider>
-          </MinimalModeProvider>
-        </DrawerSwipableProvider>
-      </DrawerOpenProvider>
+      <LoggedOutViewProvider>
+        <DrawerOpenProvider>
+          <DrawerSwipableProvider>
+            <MinimalModeProvider>
+              <ColorModeProvider>
+                <OnboardingProvider>
+                  <ComposerProvider>
+                    <TickEveryMinuteProvider>
+                      {children}
+                    </TickEveryMinuteProvider>
+                  </ComposerProvider>
+                </OnboardingProvider>
+              </ColorModeProvider>
+            </MinimalModeProvider>
+          </DrawerSwipableProvider>
+        </DrawerOpenProvider>
+      </LoggedOutViewProvider>
     </ShellLayoutProvder>
   )
 }
diff --git a/src/state/shell/logged-out.tsx b/src/state/shell/logged-out.tsx
new file mode 100644
index 000000000..19eaee76b
--- /dev/null
+++ b/src/state/shell/logged-out.tsx
@@ -0,0 +1,37 @@
+import React from 'react'
+
+type StateContext = {
+  showLoggedOut: boolean
+}
+
+const StateContext = React.createContext<StateContext>({
+  showLoggedOut: false,
+})
+const ControlsContext = React.createContext<{
+  setShowLoggedOut: (show: boolean) => void
+}>({
+  setShowLoggedOut: () => {},
+})
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+  const [showLoggedOut, setShowLoggedOut] = React.useState(false)
+
+  const state = React.useMemo(() => ({showLoggedOut}), [showLoggedOut])
+  const controls = React.useMemo(() => ({setShowLoggedOut}), [setShowLoggedOut])
+
+  return (
+    <StateContext.Provider value={state}>
+      <ControlsContext.Provider value={controls}>
+        {children}
+      </ControlsContext.Provider>
+    </StateContext.Provider>
+  )
+}
+
+export function useLoggedOutView() {
+  return React.useContext(StateContext)
+}
+
+export function useLoggedOutViewControls() {
+  return React.useContext(ControlsContext)
+}