about summary refs log tree commit diff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/com/auth/create/Step3.tsx2
-rw-r--r--src/view/com/modals/DeleteAccount.tsx22
-rw-r--r--src/view/com/pager/Pager.tsx16
-rw-r--r--src/view/com/pager/Pager.web.tsx18
-rw-r--r--src/view/com/pager/PagerWithHeader.tsx3
-rw-r--r--src/view/com/pager/PagerWithHeader.web.tsx3
-rw-r--r--src/view/com/util/Link.tsx25
-rw-r--r--src/view/com/util/WebAuxClickWrapper.tsx30
-rw-r--r--src/view/com/util/load-latest/LoadLatestBtn.tsx10
-rw-r--r--src/view/com/util/post-embeds/index.tsx17
-rw-r--r--src/view/screens/Home.tsx6
-rw-r--r--src/view/screens/Search/Search.tsx18
-rw-r--r--src/view/shell/createNativeStackNavigatorWithAuth.tsx10
-rw-r--r--src/view/shell/index.tsx11
-rw-r--r--src/view/shell/index.web.tsx2
15 files changed, 112 insertions, 81 deletions
diff --git a/src/view/com/auth/create/Step3.tsx b/src/view/com/auth/create/Step3.tsx
index 2fd265535..3a52abf80 100644
--- a/src/view/com/auth/create/Step3.tsx
+++ b/src/view/com/auth/create/Step3.tsx
@@ -43,7 +43,7 @@ export function Step3({
         />
         <Text type="lg" style={[pal.text, s.pl5, s.pt10]}>
           <Trans>Your full handle will be</Trans>{' '}
-          <Text type="lg-bold" style={[pal.text, s.ml5]}>
+          <Text type="lg-bold" style={pal.text}>
             @{createFullHandle(uiState.handle, uiState.userDomain)}
           </Text>
         </Text>
diff --git a/src/view/com/modals/DeleteAccount.tsx b/src/view/com/modals/DeleteAccount.tsx
index 945d7bc89..40d78cfe0 100644
--- a/src/view/com/modals/DeleteAccount.tsx
+++ b/src/view/com/modals/DeleteAccount.tsx
@@ -1,11 +1,12 @@
 import React from 'react'
 import {
+  SafeAreaView,
   ActivityIndicator,
   StyleSheet,
   TouchableOpacity,
   View,
 } from 'react-native'
-import {TextInput} from './util'
+import {TextInput, ScrollView} from './util'
 import LinearGradient from 'react-native-linear-gradient'
 import * as Toast from '../util/Toast'
 import {Text} from '../util/text/Text'
@@ -20,8 +21,9 @@ import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useModalControls} from '#/state/modals'
 import {useSession, useSessionApi, getAgent} from '#/state/session'
+import {isAndroid} from 'platform/detection'
 
-export const snapPoints = ['60%']
+export const snapPoints = isAndroid ? ['90%'] : ['55%']
 
 export function Component({}: {}) {
   const pal = usePalette('default')
@@ -76,8 +78,10 @@ export function Component({}: {}) {
     closeModal()
   }
   return (
-    <View style={[styles.container, pal.view]}>
-      <View style={[styles.innerContainer, pal.view]}>
+    <SafeAreaView style={[s.flex1]}>
+      <ScrollView
+        contentContainerStyle={[pal.view]}
+        keyboardShouldPersistTaps="handled">
         <View style={[styles.titleContainer, pal.view]}>
           <Text type="title-xl" style={[s.textCenter, pal.text]}>
             <Trans>Delete Account</Trans>
@@ -234,18 +238,12 @@ export function Component({}: {}) {
             )}
           </>
         )}
-      </View>
-    </View>
+      </ScrollView>
+    </SafeAreaView>
   )
 }
 
 const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-  },
-  innerContainer: {
-    paddingBottom: 20,
-  },
   titleContainer: {
     display: 'flex',
     flexDirection: 'row',
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index 834b1c0d0..06ec2e450 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -22,7 +22,6 @@ export interface RenderTabBarFnProps {
 export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
 
 interface Props {
-  tabBarPosition?: 'top' | 'bottom'
   initialPage?: number
   renderTabBar: RenderTabBarFn
   onPageSelected?: (index: number) => void
@@ -36,7 +35,6 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
   function PagerImpl(
     {
       children,
-      tabBarPosition = 'top',
       initialPage = 0,
       renderTabBar,
       onPageScrollStateChanged,
@@ -122,11 +120,10 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
 
     return (
       <View testID={testID} style={s.flex1}>
-        {tabBarPosition === 'top' &&
-          renderTabBar({
-            selectedPage,
-            onSelect: onTabBarSelect,
-          })}
+        {renderTabBar({
+          selectedPage,
+          onSelect: onTabBarSelect,
+        })}
         <AnimatedPagerView
           ref={pagerView}
           style={s.flex1}
@@ -136,11 +133,6 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
           onPageScroll={onPageScroll}>
           {children}
         </AnimatedPagerView>
-        {tabBarPosition === 'bottom' &&
-          renderTabBar({
-            selectedPage,
-            onSelect: onTabBarSelect,
-          })}
       </View>
     )
   },
diff --git a/src/view/com/pager/Pager.web.tsx b/src/view/com/pager/Pager.web.tsx
index dde799e42..d7113bb05 100644
--- a/src/view/com/pager/Pager.web.tsx
+++ b/src/view/com/pager/Pager.web.tsx
@@ -11,7 +11,6 @@ export interface RenderTabBarFnProps {
 export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
 
 interface Props {
-  tabBarPosition?: 'top' | 'bottom'
   initialPage?: number
   renderTabBar: RenderTabBarFn
   onPageSelected?: (index: number) => void
@@ -20,7 +19,6 @@ interface Props {
 export const Pager = React.forwardRef(function PagerImpl(
   {
     children,
-    tabBarPosition = 'top',
     initialPage = 0,
     renderTabBar,
     onPageSelected,
@@ -72,22 +70,16 @@ export const Pager = React.forwardRef(function PagerImpl(
 
   return (
     <View style={s.hContentRegion}>
-      {tabBarPosition === 'top' &&
-        renderTabBar({
-          selectedPage,
-          tabBarAnchor: <View ref={anchorRef} />,
-          onSelect: onTabBarSelect,
-        })}
+      {renderTabBar({
+        selectedPage,
+        tabBarAnchor: <View ref={anchorRef} />,
+        onSelect: onTabBarSelect,
+      })}
       {React.Children.map(children, (child, i) => (
         <View style={selectedPage === i ? s.flex1 : s.hidden} key={`page-${i}`}>
           {child}
         </View>
       ))}
-      {tabBarPosition === 'bottom' &&
-        renderTabBar({
-          selectedPage,
-          onSelect: onTabBarSelect,
-        })}
     </View>
   )
 })
diff --git a/src/view/com/pager/PagerWithHeader.tsx b/src/view/com/pager/PagerWithHeader.tsx
index 279b607ad..7e9ed24db 100644
--- a/src/view/com/pager/PagerWithHeader.tsx
+++ b/src/view/com/pager/PagerWithHeader.tsx
@@ -183,8 +183,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
         initialPage={initialPage}
         onPageSelected={onPageSelectedInner}
         onPageSelecting={onPageSelecting}
-        renderTabBar={renderTabBar}
-        tabBarPosition="top">
+        renderTabBar={renderTabBar}>
         {toArray(children)
           .filter(Boolean)
           .map((child, i) => {
diff --git a/src/view/com/pager/PagerWithHeader.web.tsx b/src/view/com/pager/PagerWithHeader.web.tsx
index 0a18a9e7d..4f959d548 100644
--- a/src/view/com/pager/PagerWithHeader.web.tsx
+++ b/src/view/com/pager/PagerWithHeader.web.tsx
@@ -76,8 +76,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
         initialPage={initialPage}
         onPageSelected={onPageSelectedInner}
         onPageSelecting={onPageSelecting}
-        renderTabBar={renderTabBar}
-        tabBarPosition="top">
+        renderTabBar={renderTabBar}>
         {toArray(children)
           .filter(Boolean)
           .map((child, i) => {
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx
index a517ba430..afbdeb8f4 100644
--- a/src/view/com/util/Link.tsx
+++ b/src/view/com/util/Link.tsx
@@ -31,6 +31,7 @@ import {PressableWithHover} from './PressableWithHover'
 import FixedTouchableHighlight from '../pager/FixedTouchableHighlight'
 import {useModalControls} from '#/state/modals'
 import {useOpenLink} from '#/state/preferences/in-app-browser'
+import {WebAuxClickWrapper} from 'view/com/util/WebAuxClickWrapper'
 
 type Event =
   | React.MouseEvent<HTMLAnchorElement, MouseEvent>
@@ -104,17 +105,19 @@ export const Link = memo(function Link({
       )
     }
     return (
-      <TouchableWithoutFeedback
-        testID={testID}
-        onPress={onPress}
-        accessible={accessible}
-        accessibilityRole="link"
-        {...props}>
-        {/* @ts-ignore web only -prf */}
-        <View style={style} href={anchorHref}>
-          {children ? children : <Text>{title || 'link'}</Text>}
-        </View>
-      </TouchableWithoutFeedback>
+      <WebAuxClickWrapper>
+        <TouchableWithoutFeedback
+          testID={testID}
+          onPress={onPress}
+          accessible={accessible}
+          accessibilityRole="link"
+          {...props}>
+          {/* @ts-ignore web only -prf */}
+          <View style={style} href={anchorHref}>
+            {children ? children : <Text>{title || 'link'}</Text>}
+          </View>
+        </TouchableWithoutFeedback>
+      </WebAuxClickWrapper>
     )
   }
 
diff --git a/src/view/com/util/WebAuxClickWrapper.tsx b/src/view/com/util/WebAuxClickWrapper.tsx
new file mode 100644
index 000000000..8105a8518
--- /dev/null
+++ b/src/view/com/util/WebAuxClickWrapper.tsx
@@ -0,0 +1,30 @@
+import React from 'react'
+import {Platform} from 'react-native'
+
+const onMouseUp = (e: React.MouseEvent & {target: HTMLElement}) => {
+  // Only handle whenever it is the middle button
+  if (e.button !== 1 || e.target.closest('a') || e.target.tagName === 'A') {
+    return
+  }
+
+  e.target.dispatchEvent(
+    new MouseEvent('click', {metaKey: true, bubbles: true}),
+  )
+}
+
+const onMouseDown = (e: React.MouseEvent) => {
+  // Prevents the middle click scroll from enabling
+  if (e.button !== 1) return
+  e.preventDefault()
+}
+
+export function WebAuxClickWrapper({children}: React.PropsWithChildren<{}>) {
+  if (Platform.OS !== 'web') return children
+
+  return (
+    // @ts-ignore web only
+    <div onMouseDown={onMouseDown} onMouseUp={onMouseUp}>
+      {children}
+    </div>
+  )
+}
diff --git a/src/view/com/util/load-latest/LoadLatestBtn.tsx b/src/view/com/util/load-latest/LoadLatestBtn.tsx
index 970d3a73a..5fad11760 100644
--- a/src/view/com/util/load-latest/LoadLatestBtn.tsx
+++ b/src/view/com/util/load-latest/LoadLatestBtn.tsx
@@ -10,6 +10,7 @@ import Animated from 'react-native-reanimated'
 const AnimatedTouchableOpacity =
   Animated.createAnimatedComponent(TouchableOpacity)
 import {isWeb} from 'platform/detection'
+import {useSession} from 'state/session'
 
 export function LoadLatestBtn({
   onPress,
@@ -21,9 +22,14 @@ export function LoadLatestBtn({
   showIndicator: boolean
 }) {
   const pal = usePalette('default')
-  const {isDesktop, isTablet, isMobile} = useWebMediaQueries()
+  const {hasSession} = useSession()
+  const {isDesktop, isTablet, isMobile, isTabletOrMobile} = useWebMediaQueries()
   const {fabMinimalShellTransform} = useMinimalShellMode()
 
+  // Adjust height of the fab if we have a session only on mobile web. If we don't have a session, we want to adjust
+  // it on both tablet and mobile since we are showing the bottom bar (see createNativeStackNavigatorWithAuth)
+  const showBottomBar = hasSession ? isMobile : isTabletOrMobile
+
   return (
     <AnimatedTouchableOpacity
       style={[
@@ -32,7 +38,7 @@ export function LoadLatestBtn({
         isTablet && styles.loadLatestTablet,
         pal.borderDark,
         pal.view,
-        isMobile && fabMinimalShellTransform,
+        showBottomBar && fabMinimalShellTransform,
       ]}
       onPress={onPress}
       hitSlop={HITSLOP_20}
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index 6f168a293..7e235babb 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, {useCallback} from 'react'
 import {
   StyleSheet,
   StyleProp,
@@ -29,6 +29,8 @@ import {ListEmbed} from './ListEmbed'
 import {isCauseALabelOnUri, isQuoteBlurred} from 'lib/moderation'
 import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
 import {ContentHider} from '../moderation/ContentHider'
+import {isNative} from '#/platform/detection'
+import {shareUrl} from '#/lib/sharing'
 
 type Embed =
   | AppBskyEmbedRecord.View
@@ -51,6 +53,16 @@ export function PostEmbeds({
   const pal = usePalette('default')
   const {openLightbox} = useLightboxControls()
 
+  const externalUri = AppBskyEmbedExternal.isView(embed)
+    ? embed.external.uri
+    : null
+
+  const onShareExternal = useCallback(() => {
+    if (externalUri && isNative) {
+      shareUrl(externalUri)
+    }
+  }, [externalUri])
+
   // quote post with media
   // =
   if (AppBskyEmbedRecordWithMedia.isView(embed)) {
@@ -164,7 +176,8 @@ export function PostEmbeds({
         anchorNoUnderline
         href={link.uri}
         style={[styles.extOuter, pal.view, pal.borderDark, style]}
-        hoverStyle={{borderColor: pal.colors.borderLinkHover}}>
+        hoverStyle={{borderColor: pal.colors.borderLinkHover}}
+        onLongPress={onShareExternal}>
         <ExternalLinkEmbed link={link} />
       </Link>
     )
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 7d6a40f02..1da276488 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -184,8 +184,7 @@ function HomeScreenReady({
       initialPage={clamp(selectedPageIndex, 0, customFeeds.length)}
       onPageSelected={onPageSelected}
       onPageScrollStateChanged={onPageScrollStateChanged}
-      renderTabBar={renderTabBar}
-      tabBarPosition="top">
+      renderTabBar={renderTabBar}>
       <FeedPage
         key="1"
         testID="followingFeedPage"
@@ -212,8 +211,7 @@ function HomeScreenReady({
       testID="homeScreen"
       onPageSelected={onPageSelected}
       onPageScrollStateChanged={onPageScrollStateChanged}
-      renderTabBar={renderTabBar}
-      tabBarPosition="top">
+      renderTabBar={renderTabBar}>
       <HomeLoggedOutCTA />
     </Pager>
   )
diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx
index 4703899a2..142726701 100644
--- a/src/view/screens/Search/Search.tsx
+++ b/src/view/screens/Search/Search.tsx
@@ -190,7 +190,13 @@ type SearchResultSlice =
 
 function SearchScreenPostResults({query}: {query: string}) {
   const {_} = useLingui()
+  const {currentAccount} = useSession()
   const [isPTR, setIsPTR] = React.useState(false)
+
+  const augmentedQuery = React.useMemo(() => {
+    return augmentSearchQuery(query || '', {did: currentAccount?.did})
+  }, [query, currentAccount])
+
   const {
     isFetched,
     data: results,
@@ -200,7 +206,7 @@ function SearchScreenPostResults({query}: {query: string}) {
     fetchNextPage,
     isFetchingNextPage,
     hasNextPage,
-  } = useSearchPostsQuery({query})
+  } = useSearchPostsQuery({query: augmentedQuery})
 
   const onPullToRefresh = React.useCallback(async () => {
     setIsPTR(true)
@@ -319,13 +325,9 @@ export function SearchScreenInner({
   const pal = usePalette('default')
   const setMinimalShellMode = useSetMinimalShellMode()
   const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
-  const {hasSession, currentAccount} = useSession()
+  const {hasSession} = useSession()
   const {isDesktop} = useWebMediaQueries()
 
-  const augmentedQuery = React.useMemo(() => {
-    return augmentSearchQuery(query || '', {did: currentAccount?.did})
-  }, [query, currentAccount])
-
   const onPageSelected = React.useCallback(
     (index: number) => {
       setMinimalShellMode(false)
@@ -337,7 +339,6 @@ export function SearchScreenInner({
   if (hasSession) {
     return query ? (
       <Pager
-        tabBarPosition="top"
         onPageSelected={onPageSelected}
         renderTabBar={props => (
           <CenteredView
@@ -348,7 +349,7 @@ export function SearchScreenInner({
         )}
         initialPage={0}>
         <View>
-          <SearchScreenPostResults query={augmentedQuery} />
+          <SearchScreenPostResults query={query} />
         </View>
         <View>
           <SearchScreenUserResults query={query} />
@@ -380,7 +381,6 @@ export function SearchScreenInner({
 
   return query ? (
     <Pager
-      tabBarPosition="top"
       onPageSelected={onPageSelected}
       renderTabBar={props => (
         <CenteredView
diff --git a/src/view/shell/createNativeStackNavigatorWithAuth.tsx b/src/view/shell/createNativeStackNavigatorWithAuth.tsx
index 0f240ea00..938213c31 100644
--- a/src/view/shell/createNativeStackNavigatorWithAuth.tsx
+++ b/src/view/shell/createNativeStackNavigatorWithAuth.tsx
@@ -101,7 +101,7 @@ function NativeStackNavigator({
   const onboardingState = useOnboardingState()
   const {showLoggedOut} = useLoggedOutView()
   const {setShowLoggedOut} = useLoggedOutViewControls()
-  const {isMobile} = useWebMediaQueries()
+  const {isMobile, isTabletOrMobile} = useWebMediaQueries()
   if ((!PWI_ENABLED || activeRouteRequiresAuth) && !hasSession) {
     return <LoggedOut />
   }
@@ -134,6 +134,10 @@ function NativeStackNavigator({
     }
   }
 
+  // Show the bottom bar if we have a session only on mobile web. If we don't have a session, we want to show it
+  // on both tablet and mobile web so that we see the sign up CTA.
+  const showBottomBar = hasSession ? isMobile : isTabletOrMobile
+
   return (
     <NavigationContent>
       <NativeStackView
@@ -142,8 +146,8 @@ function NativeStackNavigator({
         navigation={navigation}
         descriptors={newDescriptors}
       />
-      {isWeb && isMobile && <BottomBarWeb />}
-      {isWeb && !isMobile && (
+      {isWeb && showBottomBar && <BottomBarWeb />}
+      {isWeb && !showBottomBar && (
         <>
           <DesktopLeftNav />
           <DesktopRightNav routeName={activeRoute.name} />
diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx
index 5320aebfc..6b0cc6808 100644
--- a/src/view/shell/index.tsx
+++ b/src/view/shell/index.tsx
@@ -52,6 +52,8 @@ function ShellInner() {
   const canGoBack = useNavigationState(state => !isStateAtTabRoot(state))
   const {hasSession, currentAccount} = useSession()
   const closeAnyActiveElement = useCloseAnyActiveElement()
+  // start undefined
+  const currentAccountDid = React.useRef<string | undefined>(undefined)
 
   React.useEffect(() => {
     let listener = {remove() {}}
@@ -66,13 +68,10 @@ function ShellInner() {
   }, [closeAnyActiveElement])
 
   React.useEffect(() => {
-    if (currentAccount) {
+    // only runs when did changes
+    if (currentAccount && currentAccountDid.current !== currentAccount.did) {
+      currentAccountDid.current = currentAccount.did
       notifications.requestPermissionsAndRegisterToken(currentAccount)
-    }
-  }, [currentAccount])
-
-  React.useEffect(() => {
-    if (currentAccount) {
       const unsub = notifications.registerTokenChangeHandler(currentAccount)
       return unsub
     }
diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx
index 76f4f5c9b..97c065502 100644
--- a/src/view/shell/index.web.tsx
+++ b/src/view/shell/index.web.tsx
@@ -11,7 +11,6 @@ import {DrawerContent} from './Drawer'
 import {useWebMediaQueries} from '../../lib/hooks/useWebMediaQueries'
 import {useNavigation} from '@react-navigation/native'
 import {NavigationProp} from 'lib/routes/types'
-import {useAuxClick} from 'lib/hooks/useAuxClick'
 import {t} from '@lingui/macro'
 import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
 import {useCloseAllActiveElements} from '#/state/util'
@@ -26,7 +25,6 @@ function ShellInner() {
   const closeAllActiveElements = useCloseAllActiveElements()
 
   useWebBodyScrollLock(isDrawerOpen)
-  useAuxClick()
 
   useEffect(() => {
     const unsubscribe = navigator.addListener('state', () => {