about summary refs log tree commit diff
path: root/src/view/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/screens')
-rw-r--r--src/view/screens/Home.tsx220
-rw-r--r--src/view/screens/Notifications.tsx1
-rw-r--r--src/view/screens/Settings.tsx70
-rw-r--r--src/view/screens/Support.tsx10
4 files changed, 45 insertions, 256 deletions
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 8560ad445..ad47e9f9b 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -1,33 +1,22 @@
 import React from 'react'
-import {FlatList, View, useWindowDimensions} from 'react-native'
-import {useFocusEffect, useIsFocused} from '@react-navigation/native'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
+import {useWindowDimensions} from 'react-native'
+import {useFocusEffect} from '@react-navigation/native'
 import {AppBskyFeedGetFeed as GetCustomFeed} from '@atproto/api'
 import {observer} from 'mobx-react-lite'
-import useAppState from 'react-native-appstate-hook'
 import isEqual from 'lodash.isequal'
 import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
 import {PostsFeedModel} from 'state/models/feeds/posts'
 import {withAuthRequired} from 'view/com/auth/withAuthRequired'
-import {TextLink} from 'view/com/util/Link'
-import {Feed} from '../com/posts/Feed'
 import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
 import {FollowingEndOfFeed} from 'view/com/posts/FollowingEndOfFeed'
 import {CustomFeedEmptyState} from 'view/com/posts/CustomFeedEmptyState'
-import {LoadLatestBtn} from '../com/util/load-latest/LoadLatestBtn'
 import {FeedsTabBar} from '../com/pager/FeedsTabBar'
 import {Pager, PagerRef, RenderTabBarFnProps} from 'view/com/pager/Pager'
-import {FAB} from '../com/util/fab/FAB'
 import {useStores} from 'state/index'
-import {usePalette} from 'lib/hooks/usePalette'
-import {s, colors} from 'lib/styles'
-import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
-import {useAnalytics} from 'lib/analytics/analytics'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {ComposeIcon2} from 'lib/icons'
+import {FeedPage} from 'view/com/feeds/FeedPage'
 
-const POLL_FREQ = 30e3 // 30sec
+export const POLL_FREQ = 30e3 // 30sec
 
 type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
 export const HomeScreen = withAuthRequired(
@@ -98,7 +87,9 @@ export const HomeScreen = withAuthRequired(
       (props: RenderTabBarFnProps) => {
         return (
           <FeedsTabBar
-            {...props}
+            key="FEEDS_TAB_BAR"
+            selectedPage={props.selectedPage}
+            onSelect={props.onSelect}
             testID="homeScreenFeedTabs"
             onPressSelected={onPressSelected}
           />
@@ -111,10 +102,6 @@ export const HomeScreen = withAuthRequired(
       return <FollowingEmptyState />
     }, [])
 
-    const renderFollowingEndOfFeed = React.useCallback(() => {
-      return <FollowingEndOfFeed />
-    }, [])
-
     const renderCustomFeedEmptyState = React.useCallback(() => {
       return <CustomFeedEmptyState />
     }, [])
@@ -132,7 +119,7 @@ export const HomeScreen = withAuthRequired(
           isPageFocused={selectedPage === 0}
           feed={store.me.mainFeed}
           renderEmptyState={renderFollowingEmptyState}
-          renderEndOfFeed={renderFollowingEndOfFeed}
+          renderEndOfFeed={FollowingEndOfFeed}
         />
         {customFeeds.map((f, index) => {
           return (
@@ -150,196 +137,7 @@ export const HomeScreen = withAuthRequired(
   }),
 )
 
-const FeedPage = observer(function FeedPageImpl({
-  testID,
-  isPageFocused,
-  feed,
-  renderEmptyState,
-  renderEndOfFeed,
-}: {
-  testID?: string
-  feed: PostsFeedModel
-  isPageFocused: boolean
-  renderEmptyState?: () => JSX.Element
-  renderEndOfFeed?: () => JSX.Element
-}) {
-  const store = useStores()
-  const pal = usePalette('default')
-  const {isDesktop} = useWebMediaQueries()
-  const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll(store)
-  const {screen, track} = useAnalytics()
-  const headerOffset = useHeaderOffset()
-  const scrollElRef = React.useRef<FlatList>(null)
-  const {appState} = useAppState({
-    onForeground: () => doPoll(true),
-  })
-  const isScreenFocused = useIsFocused()
-  const hasNew = feed.hasNewLatest && !feed.isRefreshing
-
-  React.useEffect(() => {
-    // called on first load
-    if (!feed.hasLoaded && isPageFocused) {
-      feed.setup()
-    }
-  }, [isPageFocused, feed])
-
-  const doPoll = React.useCallback(
-    (knownActive = false) => {
-      if (
-        (!knownActive && appState !== 'active') ||
-        !isScreenFocused ||
-        !isPageFocused
-      ) {
-        return
-      }
-      if (feed.isLoading) {
-        return
-      }
-      store.log.debug('HomeScreen: Polling for new posts')
-      feed.checkForLatest()
-    },
-    [appState, isScreenFocused, isPageFocused, store, feed],
-  )
-
-  const scrollToTop = React.useCallback(() => {
-    scrollElRef.current?.scrollToOffset({offset: -headerOffset})
-    resetMainScroll()
-  }, [headerOffset, resetMainScroll])
-
-  const onSoftReset = React.useCallback(() => {
-    if (isPageFocused) {
-      scrollToTop()
-      feed.refresh()
-    }
-  }, [isPageFocused, scrollToTop, feed])
-
-  // fires when page within screen is activated/deactivated
-  // - check for latest
-  React.useEffect(() => {
-    if (!isPageFocused || !isScreenFocused) {
-      return
-    }
-
-    const softResetSub = store.onScreenSoftReset(onSoftReset)
-    const feedCleanup = feed.registerListeners()
-    const pollInterval = setInterval(doPoll, POLL_FREQ)
-
-    screen('Feed')
-    store.log.debug('HomeScreen: Updating feed')
-    feed.checkForLatest()
-
-    return () => {
-      clearInterval(pollInterval)
-      softResetSub.remove()
-      feedCleanup()
-    }
-  }, [store, doPoll, onSoftReset, screen, feed, isPageFocused, isScreenFocused])
-
-  const onPressCompose = React.useCallback(() => {
-    track('HomeScreen:PressCompose')
-    store.shell.openComposer({})
-  }, [store, track])
-
-  const onPressTryAgain = React.useCallback(() => {
-    feed.refresh()
-  }, [feed])
-
-  const onPressLoadLatest = React.useCallback(() => {
-    scrollToTop()
-    feed.refresh()
-  }, [feed, scrollToTop])
-
-  const ListHeaderComponent = React.useCallback(() => {
-    if (isDesktop) {
-      return (
-        <View
-          style={[
-            pal.view,
-            {
-              flexDirection: 'row',
-              alignItems: 'center',
-              justifyContent: 'space-between',
-              paddingHorizontal: 18,
-              paddingVertical: 12,
-            },
-          ]}>
-          <TextLink
-            type="title-lg"
-            href="/"
-            style={[pal.text, {fontWeight: 'bold'}]}
-            text={
-              <>
-                {store.session.isSandbox ? 'SANDBOX' : 'Bluesky'}{' '}
-                {hasNew && (
-                  <View
-                    style={{
-                      top: -8,
-                      backgroundColor: colors.blue3,
-                      width: 8,
-                      height: 8,
-                      borderRadius: 4,
-                    }}
-                  />
-                )}
-              </>
-            }
-            onPress={() => store.emitScreenSoftReset()}
-          />
-          <TextLink
-            type="title-lg"
-            href="/settings/home-feed"
-            style={{fontWeight: 'bold'}}
-            accessibilityLabel="Feed Preferences"
-            accessibilityHint=""
-            text={
-              <FontAwesomeIcon
-                icon="sliders"
-                style={pal.textLight as FontAwesomeIconStyle}
-              />
-            }
-          />
-        </View>
-      )
-    }
-    return <></>
-  }, [isDesktop, pal, store, hasNew])
-
-  return (
-    <View testID={testID} style={s.h100pct}>
-      <Feed
-        testID={testID ? `${testID}-feed` : undefined}
-        key="default"
-        feed={feed}
-        scrollElRef={scrollElRef}
-        onPressTryAgain={onPressTryAgain}
-        onScroll={onMainScroll}
-        scrollEventThrottle={100}
-        renderEmptyState={renderEmptyState}
-        renderEndOfFeed={renderEndOfFeed}
-        ListHeaderComponent={ListHeaderComponent}
-        headerOffset={headerOffset}
-      />
-      {(isScrolledDown || hasNew) && (
-        <LoadLatestBtn
-          onPress={onPressLoadLatest}
-          label="Load new posts"
-          showIndicator={hasNew}
-          minimalShellMode={store.shell.minimalShellMode}
-        />
-      )}
-      <FAB
-        testID="composeFAB"
-        onPress={onPressCompose}
-        icon={<ComposeIcon2 strokeWidth={1.5} size={29} style={s.white} />}
-        accessibilityRole="button"
-        accessibilityLabel="New post"
-        accessibilityHint=""
-      />
-    </View>
-  )
-})
-
-function useHeaderOffset() {
+export function useHeaderOffset() {
   const {isDesktop, isTablet} = useWebMediaQueries()
   const {fontScale} = useWindowDimensions()
   if (isDesktop) {
diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx
index 977401350..b00bfb765 100644
--- a/src/view/screens/Notifications.tsx
+++ b/src/view/screens/Notifications.tsx
@@ -156,7 +156,6 @@ export const NotificationsScreen = withAuthRequired(
             onPress={onPressLoadLatest}
             label="Load new notifications"
             showIndicator={hasNew}
-            minimalShellMode={true}
           />
         )}
       </View>
diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx
index f75222c1f..2112ec7d1 100644
--- a/src/view/screens/Settings.tsx
+++ b/src/view/screens/Settings.tsx
@@ -322,45 +322,37 @@ export const SettingsScreen = withAuthRequired(
 
           <View style={styles.spacer20} />
 
-          {store.me.invitesAvailable !== null && (
-            <>
-              <Text type="xl-bold" style={[pal.text, styles.heading]}>
-                Invite a Friend
-              </Text>
-              <TouchableOpacity
-                testID="inviteFriendBtn"
-                style={[
-                  styles.linkCard,
-                  pal.view,
-                  isSwitching && styles.dimmed,
-                ]}
-                onPress={isSwitching ? undefined : onPressInviteCodes}
-                accessibilityRole="button"
-                accessibilityLabel="Invite"
-                accessibilityHint="Opens invite code list">
-                <View
-                  style={[
-                    styles.iconContainer,
-                    store.me.invitesAvailable > 0 ? primaryBg : pal.btn,
-                  ]}>
-                  <FontAwesomeIcon
-                    icon="ticket"
-                    style={
-                      (store.me.invitesAvailable > 0
-                        ? primaryText
-                        : pal.text) as FontAwesomeIconStyle
-                    }
-                  />
-                </View>
-                <Text
-                  type="lg"
-                  style={store.me.invitesAvailable > 0 ? pal.link : pal.text}>
-                  {formatCount(store.me.invitesAvailable)} invite{' '}
-                  {pluralize(store.me.invitesAvailable, 'code')} available
-                </Text>
-              </TouchableOpacity>
-            </>
-          )}
+          <Text type="xl-bold" style={[pal.text, styles.heading]}>
+            Invite a Friend
+          </Text>
+          <TouchableOpacity
+            testID="inviteFriendBtn"
+            style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]}
+            onPress={isSwitching ? undefined : onPressInviteCodes}
+            accessibilityRole="button"
+            accessibilityLabel="Invite"
+            accessibilityHint="Opens invite code list">
+            <View
+              style={[
+                styles.iconContainer,
+                store.me.invitesAvailable > 0 ? primaryBg : pal.btn,
+              ]}>
+              <FontAwesomeIcon
+                icon="ticket"
+                style={
+                  (store.me.invitesAvailable > 0
+                    ? primaryText
+                    : pal.text) as FontAwesomeIconStyle
+                }
+              />
+            </View>
+            <Text
+              type="lg"
+              style={store.me.invitesAvailable > 0 ? pal.link : pal.text}>
+              {formatCount(store.me.invitesAvailable)} invite{' '}
+              {pluralize(store.me.invitesAvailable, 'code')} available
+            </Text>
+          </TouchableOpacity>
 
           <View style={styles.spacer20} />
 
diff --git a/src/view/screens/Support.tsx b/src/view/screens/Support.tsx
index de1b38b84..dc00d473d 100644
--- a/src/view/screens/Support.tsx
+++ b/src/view/screens/Support.tsx
@@ -9,6 +9,7 @@ import {TextLink} from 'view/com/util/Link'
 import {CenteredView} from 'view/com/util/Views'
 import {usePalette} from 'lib/hooks/usePalette'
 import {s} from 'lib/styles'
+import {HELP_DESK_URL} from 'lib/constants'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Support'>
 export const SupportScreen = (_props: Props) => {
@@ -29,14 +30,13 @@ export const SupportScreen = (_props: Props) => {
           Support
         </Text>
         <Text style={[pal.text, s.p20]}>
-          If you need help, email us at{' '}
+          The support form has been moved. If you need help, please
           <TextLink
-            href="mailto:support@bsky.app"
-            text="support@bsky.app"
+            href={HELP_DESK_URL}
+            text=" click here"
             style={pal.link}
           />{' '}
-          with a description of your issue and information about how we can help
-          you.
+          or visit {HELP_DESK_URL} to get in touch with us.
         </Text>
       </CenteredView>
     </View>