about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/state/queries/feed.ts29
-rw-r--r--src/view/screens/ProfileFeed.tsx75
2 files changed, 90 insertions, 14 deletions
diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts
index e3bcbc83e..58c1261db 100644
--- a/src/state/queries/feed.ts
+++ b/src/state/queries/feed.ts
@@ -160,6 +160,35 @@ export function useFeedSourceInfoQuery({uri}: {uri: string}) {
   })
 }
 
+export const isFeedPublicQueryKey = ({uri}: {uri: string}) => [
+  'isFeedPublic',
+  uri,
+]
+
+export function useIsFeedPublicQuery({uri}: {uri: string}) {
+  return useQuery({
+    queryKey: isFeedPublicQueryKey({uri}),
+    queryFn: async ({queryKey}) => {
+      const [, uri] = queryKey
+      try {
+        const res = await getAgent().app.bsky.feed.getFeed({
+          feed: uri,
+          limit: 1,
+        })
+        return Boolean(res.data.feed)
+      } catch (e: any) {
+        const msg = e.toString() as string
+
+        if (msg.includes('missing jwt')) {
+          return false
+        }
+
+        return true
+      }
+    },
+  })
+}
+
 export const useGetPopularFeedsQueryKey = ['getPopularFeeds']
 
 export function useGetPopularFeedsQuery() {
diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx
index da01cfca6..95589b22a 100644
--- a/src/view/screens/ProfileFeed.tsx
+++ b/src/view/screens/ProfileFeed.tsx
@@ -47,7 +47,11 @@ import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useModalControls} from '#/state/modals'
 import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
-import {useFeedSourceInfoQuery, FeedSourceFeedInfo} from '#/state/queries/feed'
+import {
+  useFeedSourceInfoQuery,
+  FeedSourceFeedInfo,
+  useIsFeedPublicQuery,
+} from '#/state/queries/feed'
 import {useResolveUriQuery} from '#/state/queries/resolve-uri'
 import {
   UsePreferencesQueryResponse,
@@ -131,8 +135,10 @@ export function ProfileFeedScreen(props: Props) {
 function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) {
   const {data: preferences} = usePreferencesQuery()
   const {data: info} = useFeedSourceInfoQuery({uri: feedUri})
+  const {isLoading: isPublicStatusLoading, data: isPublic} =
+    useIsFeedPublicQuery({uri: feedUri})
 
-  if (!preferences || !info) {
+  if (!preferences || !info || isPublicStatusLoading) {
     return (
       <CenteredView>
         <View style={s.p20}>
@@ -146,6 +152,7 @@ function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) {
     <ProfileFeedScreenInner
       preferences={preferences}
       feedInfo={info as FeedSourceFeedInfo}
+      isPublic={Boolean(isPublic)}
     />
   )
 }
@@ -153,9 +160,11 @@ function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) {
 export function ProfileFeedScreenInner({
   preferences,
   feedInfo,
+  isPublic,
 }: {
   preferences: UsePreferencesQueryResponse
   feedInfo: FeedSourceFeedInfo
+  isPublic: boolean
 }) {
   const {_} = useLingui()
   const pal = usePalette('default')
@@ -391,18 +400,24 @@ export function ProfileFeedScreenInner({
         isHeaderReady={true}
         renderHeader={renderHeader}
         onCurrentPageSelected={onCurrentPageSelected}>
-        {({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
-          <FeedSection
-            ref={feedSectionRef}
-            feed={`feedgen|${feedInfo.uri}`}
-            onScroll={onScroll}
-            headerHeight={headerHeight}
-            isScrolledDown={isScrolledDown}
-            scrollElRef={
-              scrollElRef as React.MutableRefObject<FlatList<any> | null>
-            }
-          />
-        )}
+        {({onScroll, headerHeight, isScrolledDown, scrollElRef}) =>
+          isPublic ? (
+            <FeedSection
+              ref={feedSectionRef}
+              feed={`feedgen|${feedInfo.uri}`}
+              onScroll={onScroll}
+              headerHeight={headerHeight}
+              isScrolledDown={isScrolledDown}
+              scrollElRef={
+                scrollElRef as React.MutableRefObject<FlatList<any> | null>
+              }
+            />
+          ) : (
+            <CenteredView sideBorders style={[{paddingTop: headerHeight}]}>
+              <NonPublicFeedMessage />
+            </CenteredView>
+          )
+        }
         {({onScroll, headerHeight, scrollElRef}) => (
           <AboutSection
             feedOwnerDid={feedInfo.creatorDid}
@@ -437,6 +452,38 @@ export function ProfileFeedScreenInner({
   )
 }
 
+function NonPublicFeedMessage() {
+  const pal = usePalette('default')
+
+  return (
+    <View
+      style={[
+        pal.border,
+        {
+          padding: 18,
+          borderTopWidth: 1,
+          minHeight: Dimensions.get('window').height * 1.5,
+        },
+      ]}>
+      <View
+        style={[
+          pal.viewLight,
+          {
+            padding: 12,
+            borderRadius: 8,
+          },
+        ]}>
+        <Text style={[pal.text]}>
+          <Trans>
+            Looks like this feed is only available to users with a Bluesky
+            account. Please sign up or sign in to view this feed!
+          </Trans>
+        </Text>
+      </View>
+    </View>
+  )
+}
+
 interface FeedSectionProps {
   feed: FeedDescriptor
   onScroll: OnScrollHandler