about summary refs log tree commit diff
path: root/src/view/com/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util')
-rw-r--r--src/view/com/util/ViewHeader.tsx19
-rw-r--r--src/view/com/util/Views.web.tsx11
-rw-r--r--src/view/com/util/fab/FABInner.tsx48
-rw-r--r--src/view/com/util/forms/SelectableBtn.tsx12
-rw-r--r--src/view/com/util/layouts/Breakpoints.web.tsx6
-rw-r--r--src/view/com/util/load-latest/LoadLatestBtn.web.tsx5
-rw-r--r--src/view/com/util/moderation/ContentHider.tsx5
-rw-r--r--src/view/com/util/moderation/PostHider.tsx10
-rw-r--r--src/view/com/util/moderation/ScreenHider.tsx5
-rw-r--r--src/view/com/util/post-embeds/ExternalLinkEmbed.tsx63
-rw-r--r--src/view/com/util/post-embeds/index.tsx19
11 files changed, 131 insertions, 72 deletions
diff --git a/src/view/com/util/ViewHeader.tsx b/src/view/com/util/ViewHeader.tsx
index 7482db8eb..91cdb08c7 100644
--- a/src/view/com/util/ViewHeader.tsx
+++ b/src/view/com/util/ViewHeader.tsx
@@ -8,9 +8,9 @@ import {Text} from './text/Text'
 import {useStores} from 'state/index'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {useAnalytics} from 'lib/analytics/analytics'
 import {NavigationProp} from 'lib/routes/types'
-import {isDesktopWeb} from 'platform/detection'
 
 const BACK_HITSLOP = {left: 20, top: 20, right: 50, bottom: 20}
 
@@ -35,6 +35,7 @@ export const ViewHeader = observer(function ({
   const store = useStores()
   const navigation = useNavigation<NavigationProp>()
   const {track} = useAnalytics()
+  const {isDesktop, isTablet} = useWebMediaQueries()
 
   const onPressBack = React.useCallback(() => {
     if (navigation.canGoBack()) {
@@ -49,7 +50,7 @@ export const ViewHeader = observer(function ({
     store.shell.openDrawer()
   }, [track, store])
 
-  if (isDesktopWeb) {
+  if (isDesktop) {
     if (showOnDesktop) {
       return (
         <DesktopWebHeader
@@ -84,13 +85,13 @@ export const ViewHeader = observer(function ({
                 icon="angle-left"
                 style={[styles.backIcon, pal.text]}
               />
-            ) : (
+            ) : !isTablet ? (
               <FontAwesomeIcon
                 size={18}
                 icon="bars"
                 style={[styles.backIcon, pal.textLight]}
               />
-            )}
+            ) : null}
           </TouchableOpacity>
         ) : null}
         <View style={styles.titleContainer} pointerEvents="none">
@@ -122,6 +123,7 @@ function DesktopWebHeader({
     <CenteredView
       style={[
         styles.header,
+        styles.headerFixed,
         styles.desktopHeader,
         pal.border,
         {
@@ -178,6 +180,7 @@ const Container = observer(
         <View
           style={[
             styles.header,
+            styles.headerFixed,
             pal.view,
             pal.border,
             showBorder && styles.border,
@@ -190,9 +193,9 @@ const Container = observer(
       <Animated.View
         style={[
           styles.header,
+          styles.headerFloating,
           pal.view,
           pal.border,
-          styles.headerFloating,
           transform,
           showBorder && styles.border,
         ]}>
@@ -208,6 +211,12 @@ const styles = StyleSheet.create({
     alignItems: 'center',
     paddingHorizontal: 12,
     paddingVertical: 6,
+    width: '100%',
+  },
+  headerFixed: {
+    maxWidth: 600,
+    marginLeft: 'auto',
+    marginRight: 'auto',
   },
   headerFloating: {
     position: 'absolute',
diff --git a/src/view/com/util/Views.web.tsx b/src/view/com/util/Views.web.tsx
index 3313492e1..58a367f20 100644
--- a/src/view/com/util/Views.web.tsx
+++ b/src/view/com/util/Views.web.tsx
@@ -24,6 +24,7 @@ import {
 } from 'react-native'
 import {addStyle} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 
 interface AddedProps {
   desktopFixedHeight?: boolean
@@ -48,6 +49,7 @@ export const FlatList = React.forwardRef(function <ItemT>(
   ref: React.Ref<RNFlatList>,
 ) {
   const pal = usePalette('default')
+  const {isMobile} = useWebMediaQueries()
   contentContainerStyle = addStyle(
     contentContainerStyle,
     styles.containerScroll,
@@ -67,6 +69,12 @@ export const FlatList = React.forwardRef(function <ItemT>(
   }
   if (desktopFixedHeight) {
     style = addStyle(style, styles.fixedHeight)
+    if (!isMobile) {
+      contentContainerStyle = addStyle(
+        contentContainerStyle,
+        styles.stableGutters,
+      )
+    }
   }
   return (
     <RNFlatList
@@ -126,6 +134,9 @@ const styles = StyleSheet.create({
   },
   fixedHeight: {
     height: '100vh',
+  },
+  stableGutters: {
+    // @ts-ignore web only -prf
     scrollbarGutter: 'stable both-edges',
   },
 })
diff --git a/src/view/com/util/fab/FABInner.tsx b/src/view/com/util/fab/FABInner.tsx
index 76824e575..afd172c82 100644
--- a/src/view/com/util/fab/FABInner.tsx
+++ b/src/view/com/util/fab/FABInner.tsx
@@ -5,7 +5,8 @@ import LinearGradient from 'react-native-linear-gradient'
 import {gradients} from 'lib/styles'
 import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
 import {useStores} from 'state/index'
-import {isMobileWeb} from 'platform/detection'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {isWeb} from 'platform/detection'
 
 export interface FABProps
   extends ComponentProps<typeof TouchableWithoutFeedback> {
@@ -14,6 +15,7 @@ export interface FABProps
 }
 
 export const FABInner = observer(({testID, icon, ...props}: FABProps) => {
+  const {isTablet} = useWebMediaQueries()
   const store = useStores()
   const interp = useAnimatedValue(0)
   React.useEffect(() => {
@@ -24,18 +26,33 @@ export const FABInner = observer(({testID, icon, ...props}: FABProps) => {
       isInteraction: false,
     }).start()
   }, [interp, store.shell.minimalShellMode])
-  const transform = {
-    transform: [{translateY: Animated.multiply(interp, 60)}],
-  }
+  const transform = isTablet
+    ? undefined
+    : {
+        transform: [{translateY: Animated.multiply(interp, 60)}],
+      }
+  const size = isTablet ? styles.sizeLarge : styles.sizeRegular
   return (
     <TouchableWithoutFeedback testID={testID} {...props}>
       <Animated.View
-        style={[styles.outer, isMobileWeb && styles.mobileWebOuter, transform]}>
+        style={[
+          styles.outer,
+          size,
+          isWeb && isTablet
+            ? {
+                right: 50,
+                bottom: 50,
+              }
+            : {
+                bottom: 114,
+              },
+          transform,
+        ]}>
         <LinearGradient
           colors={[gradients.blueLight.start, gradients.blueLight.end]}
           start={{x: 0, y: 0}}
           end={{x: 1, y: 1}}
-          style={styles.inner}>
+          style={[styles.inner, size]}>
           {icon}
         </LinearGradient>
       </Animated.View>
@@ -44,22 +61,23 @@ export const FABInner = observer(({testID, icon, ...props}: FABProps) => {
 })
 
 const styles = StyleSheet.create({
+  sizeRegular: {
+    width: 60,
+    height: 60,
+    borderRadius: 30,
+  },
+  sizeLarge: {
+    width: 70,
+    height: 70,
+    borderRadius: 35,
+  },
   outer: {
     position: 'absolute',
     zIndex: 1,
     right: 24,
     bottom: 94,
-    width: 60,
-    height: 60,
-    borderRadius: 30,
-  },
-  mobileWebOuter: {
-    bottom: 114,
   },
   inner: {
-    width: 60,
-    height: 60,
-    borderRadius: 30,
     justifyContent: 'center',
     alignItems: 'center',
   },
diff --git a/src/view/com/util/forms/SelectableBtn.tsx b/src/view/com/util/forms/SelectableBtn.tsx
index 4b494264e..f09d063a1 100644
--- a/src/view/com/util/forms/SelectableBtn.tsx
+++ b/src/view/com/util/forms/SelectableBtn.tsx
@@ -2,7 +2,7 @@ import React from 'react'
 import {Pressable, ViewStyle, StyleProp, StyleSheet} from 'react-native'
 import {Text} from '../text/Text'
 import {usePalette} from 'lib/hooks/usePalette'
-import {isDesktopWeb} from 'platform/detection'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 
 interface SelectableBtnProps {
   testID?: string
@@ -28,12 +28,16 @@ export function SelectableBtn({
   const pal = usePalette('default')
   const palPrimary = usePalette('inverted')
   const needsWidthStyles = !style || !('width' in style || 'flex' in style)
+  const {isMobile} = useWebMediaQueries()
   return (
     <Pressable
       testID={testID}
       style={[
         styles.btn,
-        needsWidthStyles && styles.btnWidth,
+        needsWidthStyles && {
+          flex: isMobile ? 1 : undefined,
+          width: !isMobile ? 100 : undefined,
+        },
         left && styles.btnLeft,
         right && styles.btnRight,
         pal.border,
@@ -58,10 +62,6 @@ const styles = StyleSheet.create({
     paddingHorizontal: 10,
     paddingVertical: 10,
   },
-  btnWidth: {
-    flex: isDesktopWeb ? undefined : 1,
-    width: isDesktopWeb ? 100 : undefined,
-  },
   btnLeft: {
     borderTopLeftRadius: 8,
     borderBottomLeftRadius: 8,
diff --git a/src/view/com/util/layouts/Breakpoints.web.tsx b/src/view/com/util/layouts/Breakpoints.web.tsx
index 7031a1735..5cf73df0c 100644
--- a/src/view/com/util/layouts/Breakpoints.web.tsx
+++ b/src/view/com/util/layouts/Breakpoints.web.tsx
@@ -2,18 +2,18 @@ import React from 'react'
 import MediaQuery from 'react-responsive'
 
 export const Desktop = ({children}: React.PropsWithChildren<{}>) => (
-  <MediaQuery minWidth={1224}>{children}</MediaQuery>
+  <MediaQuery minWidth={1300}>{children}</MediaQuery>
 )
 export const TabletOrDesktop = ({children}: React.PropsWithChildren<{}>) => (
   <MediaQuery minWidth={800}>{children}</MediaQuery>
 )
 export const Tablet = ({children}: React.PropsWithChildren<{}>) => (
-  <MediaQuery minWidth={800} maxWidth={1224}>
+  <MediaQuery minWidth={800} maxWidth={1300}>
     {children}
   </MediaQuery>
 )
 export const TabletOrMobile = ({children}: React.PropsWithChildren<{}>) => (
-  <MediaQuery maxWidth={1224}>{children}</MediaQuery>
+  <MediaQuery maxWidth={1300}>{children}</MediaQuery>
 )
 export const Mobile = ({children}: React.PropsWithChildren<{}>) => (
   <MediaQuery maxWidth={800}>{children}</MediaQuery>
diff --git a/src/view/com/util/load-latest/LoadLatestBtn.web.tsx b/src/view/com/util/load-latest/LoadLatestBtn.web.tsx
index c90e5dfb1..c9576e56b 100644
--- a/src/view/com/util/load-latest/LoadLatestBtn.web.tsx
+++ b/src/view/com/util/load-latest/LoadLatestBtn.web.tsx
@@ -3,8 +3,8 @@ import {StyleSheet, TouchableOpacity} from 'react-native'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {Text} from '../text/Text'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {LoadLatestBtn as LoadLatestBtnMobile} from './LoadLatestBtnMobile'
-import {isMobileWeb} from 'platform/detection'
 import {HITSLOP_20} from 'lib/constants'
 
 export const LoadLatestBtn = ({
@@ -19,7 +19,8 @@ export const LoadLatestBtn = ({
   minimalShellMode?: boolean
 }) => {
   const pal = usePalette('default')
-  if (isMobileWeb) {
+  const {isMobile} = useWebMediaQueries()
+  if (isMobile) {
     return (
       <LoadLatestBtnMobile
         onPress={onPress}
diff --git a/src/view/com/util/moderation/ContentHider.tsx b/src/view/com/util/moderation/ContentHider.tsx
index 853f7840c..6cf1cefd0 100644
--- a/src/view/com/util/moderation/ContentHider.tsx
+++ b/src/view/com/util/moderation/ContentHider.tsx
@@ -1,12 +1,12 @@
 import React from 'react'
 import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {ModerationUI} from '@atproto/api'
 import {Text} from '../text/Text'
 import {ShieldExclamation} from 'lib/icons'
 import {describeModerationCause} from 'lib/moderation'
 import {useStores} from 'state/index'
-import {isDesktopWeb} from 'platform/detection'
 
 export function ContentHider({
   testID,
@@ -24,6 +24,7 @@ export function ContentHider({
 }>) {
   const store = useStores()
   const pal = usePalette('default')
+  const {isMobile} = useWebMediaQueries()
   const [override, setOverride] = React.useState(false)
 
   if (!moderation.blur || (ignoreMute && moderation.cause?.type === 'muted')) {
@@ -54,6 +55,7 @@ export function ContentHider({
         accessibilityLabel=""
         style={[
           styles.cover,
+          {paddingRight: isMobile ? 22 : 18},
           moderation.noOverride
             ? {borderWidth: 1, borderColor: pal.colors.borderDark}
             : pal.viewLight,
@@ -96,7 +98,6 @@ const styles = StyleSheet.create({
     marginTop: 4,
     paddingVertical: 14,
     paddingLeft: 14,
-    paddingRight: isDesktopWeb ? 18 : 22,
   },
   showBtn: {
     marginLeft: 'auto',
diff --git a/src/view/com/util/moderation/PostHider.tsx b/src/view/com/util/moderation/PostHider.tsx
index 2a52561d4..443885dfa 100644
--- a/src/view/com/util/moderation/PostHider.tsx
+++ b/src/view/com/util/moderation/PostHider.tsx
@@ -2,13 +2,13 @@ import React, {ComponentProps} from 'react'
 import {StyleSheet, Pressable, View} from 'react-native'
 import {ModerationUI} from '@atproto/api'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {Link} from '../Link'
 import {Text} from '../text/Text'
 import {addStyle} from 'lib/styles'
 import {describeModerationCause} from 'lib/moderation'
 import {ShieldExclamation} from 'lib/icons'
 import {useStores} from 'state/index'
-import {isDesktopWeb} from 'platform/detection'
 
 interface Props extends ComponentProps<typeof Link> {
   // testID?: string
@@ -27,6 +27,7 @@ export function PostHider({
 }: Props) {
   const store = useStores()
   const pal = usePalette('default')
+  const {isMobile} = useWebMediaQueries()
   const [override, setOverride] = React.useState(false)
 
   if (!moderation.blur) {
@@ -55,7 +56,11 @@ export function PostHider({
         accessibilityRole="button"
         accessibilityHint={override ? 'Hide the content' : 'Show the content'}
         accessibilityLabel=""
-        style={[styles.description, pal.viewLight]}>
+        style={[
+          styles.description,
+          {paddingRight: isMobile ? 22 : 18},
+          pal.viewLight,
+        ]}>
         <Pressable
           onPress={() => {
             store.shell.openModal({
@@ -100,7 +105,6 @@ const styles = StyleSheet.create({
     gap: 4,
     paddingVertical: 14,
     paddingLeft: 18,
-    paddingRight: isDesktopWeb ? 18 : 22,
     marginTop: 1,
   },
   showBtn: {
diff --git a/src/view/com/util/moderation/ScreenHider.tsx b/src/view/com/util/moderation/ScreenHider.tsx
index b76b1101c..0224b9fee 100644
--- a/src/view/com/util/moderation/ScreenHider.tsx
+++ b/src/view/com/util/moderation/ScreenHider.tsx
@@ -13,10 +13,10 @@ import {
 import {useNavigation} from '@react-navigation/native'
 import {ModerationUI} from '@atproto/api'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {NavigationProp} from 'lib/routes/types'
 import {Text} from '../text/Text'
 import {Button} from '../forms/Button'
-import {isDesktopWeb} from 'platform/detection'
 import {describeModerationCause} from 'lib/moderation'
 import {useStores} from 'state/index'
 
@@ -39,6 +39,7 @@ export function ScreenHider({
   const palInverted = usePalette('inverted')
   const [override, setOverride] = React.useState(false)
   const navigation = useNavigation<NavigationProp>()
+  const {isMobile} = useWebMediaQueries()
 
   if (!moderation.blur || override) {
     return (
@@ -85,7 +86,7 @@ export function ScreenHider({
           </Text>
         </TouchableWithoutFeedback>
       </Text>
-      {!isDesktopWeb && <View style={styles.spacer} />}
+      {isMobile && <View style={styles.spacer} />}
       <View style={styles.btnContainer}>
         <Button
           type="inverted"
diff --git a/src/view/com/util/post-embeds/ExternalLinkEmbed.tsx b/src/view/com/util/post-embeds/ExternalLinkEmbed.tsx
index 81f1ca560..d5bb38fb2 100644
--- a/src/view/com/util/post-embeds/ExternalLinkEmbed.tsx
+++ b/src/view/com/util/post-embeds/ExternalLinkEmbed.tsx
@@ -3,8 +3,8 @@ import {Image} from 'expo-image'
 import {Text} from '../text/Text'
 import {StyleSheet, View} from 'react-native'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {AppBskyEmbedExternal} from '@atproto/api'
-import {isDesktopWeb} from 'platform/detection'
 import {toNiceDomain} from 'lib/strings/url-helpers'
 
 export const ExternalLinkEmbed = ({
@@ -15,10 +15,31 @@ export const ExternalLinkEmbed = ({
   imageChild?: React.ReactNode
 }) => {
   const pal = usePalette('default')
+  const {isMobile} = useWebMediaQueries()
   return (
-    <View style={styles.extContainer}>
+    <View
+      style={{
+        flexDirection: isMobile ? 'column' : 'row',
+      }}>
       {link.thumb ? (
-        <View style={styles.extImageContainer}>
+        <View
+          style={
+            !isMobile
+              ? {
+                  borderTopLeftRadius: 6,
+                  borderBottomLeftRadius: 6,
+                  width: 120,
+                  aspectRatio: 1,
+                  overflow: 'hidden',
+                }
+              : {
+                  borderTopLeftRadius: 6,
+                  borderTopRightRadius: 6,
+                  width: '100%',
+                  height: 200,
+                  overflow: 'hidden',
+                }
+          }>
           <Image
             style={styles.extImage}
             source={{uri: link.thumb}}
@@ -27,7 +48,13 @@ export const ExternalLinkEmbed = ({
           {imageChild}
         </View>
       ) : undefined}
-      <View style={styles.extInner}>
+      <View
+        style={{
+          paddingHorizontal: isMobile ? 10 : 14,
+          paddingTop: 8,
+          paddingBottom: 10,
+          flex: !isMobile ? 1 : undefined,
+        }}>
         <Text
           type="sm"
           numberOfLines={1}
@@ -36,14 +63,14 @@ export const ExternalLinkEmbed = ({
         </Text>
         <Text
           type="lg-bold"
-          numberOfLines={isDesktopWeb ? 2 : 4}
+          numberOfLines={isMobile ? 4 : 2}
           style={[pal.text]}>
           {link.title || link.uri}
         </Text>
         {link.description ? (
           <Text
             type="md"
-            numberOfLines={isDesktopWeb ? 2 : 4}
+            numberOfLines={isMobile ? 4 : 2}
             style={[pal.text, styles.extDescription]}>
             {link.description}
           </Text>
@@ -54,30 +81,6 @@ export const ExternalLinkEmbed = ({
 }
 
 const styles = StyleSheet.create({
-  extContainer: {
-    flexDirection: isDesktopWeb ? 'row' : 'column',
-  },
-  extInner: {
-    paddingHorizontal: isDesktopWeb ? 14 : 10,
-    paddingTop: 8,
-    paddingBottom: 10,
-    flex: isDesktopWeb ? 1 : undefined,
-  },
-  extImageContainer: isDesktopWeb
-    ? {
-        borderTopLeftRadius: 6,
-        borderBottomLeftRadius: 6,
-        width: 120,
-        aspectRatio: 1,
-        overflow: 'hidden',
-      }
-    : {
-        borderTopLeftRadius: 6,
-        borderTopRightRadius: 6,
-        width: '100%',
-        height: 200,
-        overflow: 'hidden',
-      },
   extImage: {
     width: '100%',
     height: 200,
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index bf2365f18..ce6da4a1b 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -22,6 +22,7 @@ import {ImageLayoutGrid} from '../images/ImageLayoutGrid'
 import {ImagesLightbox} from 'state/models/ui/shell'
 import {useStores} from 'state/index'
 import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {YoutubeEmbed} from './YoutubeEmbed'
 import {ExternalLinkEmbed} from './ExternalLinkEmbed'
 import {getYoutubeVideoId} from 'lib/strings/url-helpers'
@@ -29,7 +30,6 @@ import {MaybeQuoteEmbed} from './QuoteEmbed'
 import {AutoSizedImage} from '../images/AutoSizedImage'
 import {CustomFeedEmbed} from './CustomFeedEmbed'
 import {ListEmbed} from './ListEmbed'
-import {isDesktopWeb} from 'platform/detection'
 import {isCauseALabelOnUri} from 'lib/moderation'
 
 type Embed =
@@ -50,6 +50,7 @@ export function PostEmbeds({
 }) {
   const pal = usePalette('default')
   const store = useStores()
+  const {isMobile} = useWebMediaQueries()
 
   // quote post with media
   // =
@@ -111,7 +112,10 @@ export function PostEmbeds({
               uri={thumb}
               onPress={() => openLightbox(0)}
               onPressIn={() => onPressIn(0)}
-              style={styles.singleImage}>
+              style={[
+                styles.singleImage,
+                isMobile && styles.singleImageMobile,
+              ]}>
               {alt === '' ? null : (
                 <View style={styles.altContainer}>
                   <Text style={styles.alt} accessible={false}>
@@ -130,7 +134,11 @@ export function PostEmbeds({
             images={embed.images}
             onPress={openLightbox}
             onPressIn={onPressIn}
-            style={embed.images.length === 1 ? styles.singleImage : undefined}
+            style={
+              embed.images.length === 1
+                ? [styles.singleImage, isMobile && styles.singleImageMobile]
+                : undefined
+            }
           />
         </View>
       )
@@ -169,7 +177,10 @@ const styles = StyleSheet.create({
   },
   singleImage: {
     borderRadius: 8,
-    maxHeight: isDesktopWeb ? 1000 : 500,
+    maxHeight: 1000,
+  },
+  singleImageMobile: {
+    maxHeight: 500,
   },
   extOuter: {
     borderWidth: 1,