diff options
Diffstat (limited to 'src/view/com/util')
-rw-r--r-- | src/view/com/util/List.web.tsx | 5 | ||||
-rw-r--r-- | src/view/com/util/LoadingPlaceholder.tsx | 45 | ||||
-rw-r--r-- | src/view/com/util/UserInfoText.tsx | 6 | ||||
-rw-r--r-- | src/view/com/util/forms/PostDropdownBtn.tsx | 8 | ||||
-rw-r--r-- | src/view/com/util/images/Gallery.tsx | 7 | ||||
-rw-r--r-- | src/view/com/util/images/ImageLayoutGrid.tsx | 39 | ||||
-rw-r--r-- | src/view/com/util/load-latest/LoadLatestBtn.tsx | 10 | ||||
-rw-r--r-- | src/view/com/util/post-ctrls/PostCtrls.tsx | 26 |
8 files changed, 98 insertions, 48 deletions
diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index 3e81a8c37..29bad2db8 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -300,6 +300,9 @@ export const List = memo(React.forwardRef(ListImpl)) as <ItemT>( props: ListProps<ItemT> & {ref?: React.Ref<ListMethods>}, ) => React.ReactElement +// https://stackoverflow.com/questions/7944460/detect-safari-browser +const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) + const styles = StyleSheet.create({ contentContainer: { borderLeftWidth: 1, @@ -313,7 +316,7 @@ const styles = StyleSheet.create({ }, row: { // @ts-ignore web only - contentVisibility: 'auto', + contentVisibility: isSafari ? '' : 'auto', // Safari support for this is buggy. }, minHeightViewport: { // @ts-ignore web only diff --git a/src/view/com/util/LoadingPlaceholder.tsx b/src/view/com/util/LoadingPlaceholder.tsx index 8941bfb9c..6dfe12598 100644 --- a/src/view/com/util/LoadingPlaceholder.tsx +++ b/src/view/com/util/LoadingPlaceholder.tsx @@ -67,28 +67,36 @@ export function PostLoadingPlaceholder({ <LoadingPlaceholder width="95%" height={6} style={{marginBottom: 8}} /> <LoadingPlaceholder width="80%" height={6} style={{marginBottom: 11}} /> <View style={styles.postCtrls}> - <View style={[styles.postCtrl, {paddingLeft: 0}]}> - <CommentBottomArrow - style={[{color: theme.palette.default.icon, marginTop: 1}]} - strokeWidth={3} - size={15} - /> + <View style={styles.postCtrl}> + <View style={[styles.postBtn, {paddingLeft: 0}]}> + <CommentBottomArrow + style={[{color: theme.palette.default.icon, marginTop: 1}]} + strokeWidth={3} + size={15} + /> + </View> + </View> + <View style={styles.postCtrl}> + <View style={styles.postBtn}> + <RepostIcon + style={{color: theme.palette.default.icon}} + strokeWidth={3} + size={20} + /> + </View> </View> <View style={styles.postCtrl}> - <RepostIcon - style={{color: theme.palette.default.icon}} - strokeWidth={3} - size={20} - /> + <View style={styles.postBtn}> + <HeartIcon + style={{color: theme.palette.default.icon} as ViewStyle} + size={16} + strokeWidth={3} + /> + </View> </View> <View style={styles.postCtrl}> - <HeartIcon - style={{color: theme.palette.default.icon} as ViewStyle} - size={16} - strokeWidth={3} - /> + <View style={styles.postBtn} /> </View> - <View style={{width: 30, height: 30}} /> </View> </View> </View> @@ -279,6 +287,9 @@ const styles = StyleSheet.create({ justifyContent: 'space-between', }, postCtrl: { + flex: 1, + }, + postBtn: { padding: 5, flex: 1, flexDirection: 'row', diff --git a/src/view/com/util/UserInfoText.tsx b/src/view/com/util/UserInfoText.tsx index e5d2ceb03..9cb9997f6 100644 --- a/src/view/com/util/UserInfoText.tsx +++ b/src/view/com/util/UserInfoText.tsx @@ -9,6 +9,7 @@ import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {makeProfileLink} from 'lib/routes/links' import {useProfileQuery} from '#/state/queries/profile' +import {STALE} from '#/state/queries' export function UserInfoText({ type = 'md', @@ -29,7 +30,10 @@ export function UserInfoText({ attr = attr || 'handle' failed = failed || 'user' - const {data: profile, isError} = useProfileQuery({did}) + const {data: profile, isError} = useProfileQuery({ + did, + staleTime: STALE.INFINITY, + }) let inner if (isError) { diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx index 940f39057..e56c88d2c 100644 --- a/src/view/com/util/forms/PostDropdownBtn.tsx +++ b/src/view/com/util/forms/PostDropdownBtn.tsx @@ -1,5 +1,5 @@ import React, {memo} from 'react' -import {Linking, StyleProp, View, ViewStyle} from 'react-native' +import {StyleProp, View, ViewStyle} from 'react-native' import Clipboard from '@react-native-clipboard/clipboard' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import { @@ -24,6 +24,7 @@ import {usePostDeleteMutation} from '#/state/queries/post' import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads' import {useLanguagePrefs} from '#/state/preferences' import {useHiddenPosts, useHiddenPostsApi} from '#/state/preferences' +import {useOpenLink} from '#/state/preferences/in-app-browser' import {logger} from '#/logger' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -61,6 +62,7 @@ let PostDropdownBtn = ({ const postDeleteMutation = usePostDeleteMutation() const hiddenPosts = useHiddenPosts() const {hidePost} = useHiddenPostsApi() + const openLink = useOpenLink() const rootUri = record.reply?.root?.uri || postUri const isThreadMuted = mutedThreads.includes(rootUri) @@ -111,8 +113,8 @@ let PostDropdownBtn = ({ }, [_, richText]) const onOpenTranslate = React.useCallback(() => { - Linking.openURL(translatorUrl) - }, [translatorUrl]) + openLink(translatorUrl) + }, [openLink, translatorUrl]) const onHidePost = React.useCallback(() => { hidePost({uri: postUri}) diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx index e7110372c..7de3b093a 100644 --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -4,6 +4,7 @@ import {StyleSheet, Text, Pressable, View} from 'react-native' import {Image} from 'expo-image' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {isWeb} from 'platform/detection' type EventFunction = (index: number) => void @@ -70,8 +71,10 @@ const styles = StyleSheet.create({ paddingHorizontal: 6, paddingVertical: 3, position: 'absolute', - left: 8, - bottom: 8, + // Related to margin/gap hack. This keeps the alt label in the same position + // on all platforms + left: isWeb ? 8 : 5, + bottom: isWeb ? 8 : 5, }, alt: { color: 'white', diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx index 23e807b6a..ba6c04f50 100644 --- a/src/view/com/util/images/ImageLayoutGrid.tsx +++ b/src/view/com/util/images/ImageLayoutGrid.tsx @@ -2,6 +2,7 @@ import React from 'react' import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' import {AppBskyEmbedImages} from '@atproto/api' import {GalleryItem} from './Gallery' +import {isWeb} from 'platform/detection' interface ImageLayoutGridProps { images: AppBskyEmbedImages.ViewImage[] @@ -47,10 +48,10 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { case 3: return ( <View style={styles.flexRow}> - <View style={{flex: 2, aspectRatio: 1}}> + <View style={styles.threeSingle}> <GalleryItem {...props} index={0} imageStyle={styles.image} /> </View> - <View style={{flex: 1}}> + <View style={styles.threeDouble}> <View style={styles.smallItem}> <GalleryItem {...props} index={1} imageStyle={styles.image} /> </View> @@ -88,18 +89,38 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { } } -// This is used to compute margins (rather than flexbox gap) due to Yoga bugs: +// On web we use margin to calculate gap, as aspectRatio does not properly size +// all images on web. On native though we cannot rely on margin, since the +// negative margin interferes with the swipe controls on pagers. // https://github.com/facebook/yoga/issues/1418 +// https://github.com/bluesky-social/social-app/issues/2601 const IMAGE_GAP = 5 const styles = StyleSheet.create({ - container: { - marginHorizontal: -IMAGE_GAP / 2, - marginVertical: -IMAGE_GAP / 2, + container: isWeb + ? { + marginHorizontal: -IMAGE_GAP / 2, + marginVertical: -IMAGE_GAP / 2, + } + : { + gap: IMAGE_GAP, + }, + flexRow: { + flexDirection: 'row', + gap: isWeb ? undefined : IMAGE_GAP, }, - flexRow: {flexDirection: 'row'}, smallItem: {flex: 1, aspectRatio: 1}, - image: { - margin: IMAGE_GAP / 2, + image: isWeb + ? { + margin: IMAGE_GAP / 2, + } + : {}, + threeSingle: { + flex: 2, + aspectRatio: isWeb ? 1 : undefined, + }, + threeDouble: { + flex: 1, + gap: isWeb ? undefined : IMAGE_GAP, }, }) 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-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index a6d7e38c3..249111a04 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -149,7 +149,7 @@ let PostCtrls = ({ ) : undefined} </TouchableOpacity> </View> - <View style={[styles.ctrl]}> + <View style={styles.ctrl}> <RepostButton big={big} isReposted={!!post.viewer?.repost} @@ -194,19 +194,19 @@ let PostCtrls = ({ </TouchableOpacity> </View> {big ? undefined : ( - <PostDropdownBtn - testID="postDropdownBtn" - postAuthor={post.author} - postCid={post.cid} - postUri={post.uri} - record={record} - richText={richText} - showAppealLabelItem={showAppealLabelItem} - style={styles.btnPad} - /> + <View style={styles.ctrl}> + <PostDropdownBtn + testID="postDropdownBtn" + postAuthor={post.author} + postCid={post.cid} + postUri={post.uri} + record={record} + richText={richText} + showAppealLabelItem={showAppealLabelItem} + style={styles.btnPad} + /> + </View> )} - {/* used for adding pad to the right side */} - <View /> </View> ) } |