bump it bop it upgrade it (rn 79/expo 53) (#8281)
* basic bumps * more tweaking * fix rn patch * fix crop picker patch * fix media library patch * rm unnecessary patch * fix notifications patch * update bottomsheet * Update withAppDelegateReferrer.js * Delete withNoBundleCompression.js * rm withNoBundleCompression plugin * rm findLast shim * metro package exports is enabled by default * update react/react-dom/react-compiler * fix reanimated issue * vendor expo-ized emoji popup * fix types * hackfix view full thread * Update EmojiPickerModule.podspec * more upgrades * fix multiformats package version * add baseurl * bump mmkv * bumps * update react-keyed-flatten-children * bump locale packages * fix emoji picker dark mode * rn upgrades * Revert "bump locale packages" This reverts commitfc82f0f173. * upgrade testing-library * rm test renderer * update patch name minors * rm findNodeHandle from tabbar * only do scrollview tag thing on ios * disable package exports * update expo notifications handler * memoize emoji picker styles * fix tests, mock multiformats * bump some dev deps with RC versions * completely rearchitect toasts * rm logs * layout animation config for composer footer * disable autolinking for patched libs * undo lingui changes * version bump from release candidate to 0.1 * update atproto deps * rm @did-plc/server * fix key issue (maybe) * move URL polyfill to the polyfill file * fix yarn lock * upgrade to 53.0.3 * reanimated layout anim bug patch * workletize a function that wasn't getting autoworkletized anymore (#8309) * bump to expo 53.0.4 * bump RN to 0.79.2 * fix yarn lock ci * Revert "completely rearchitect toasts" This reverts commit2e2fcaeeed. * final upgrades * chore: cleanup yarn lock * prettier --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import 'react-native-url-polyfill/auto'
|
||||
import '#/logger/sentry/setup'
|
||||
import '#/logger/bitdrift/setup'
|
||||
import '#/view/icons'
|
||||
|
||||
+2
-2
@@ -951,8 +951,8 @@ export const atoms = {
|
||||
userSelect: 'all',
|
||||
},
|
||||
outline_inset_1: {
|
||||
outlineOffset: '-1px',
|
||||
} as StyleProp<ViewStyle>,
|
||||
outlineOffset: -1,
|
||||
},
|
||||
|
||||
/*
|
||||
* Text decoration
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React, {Children} from 'react'
|
||||
import {TextProps as RNTextProps} from 'react-native'
|
||||
import {StyleProp, TextStyle} from 'react-native'
|
||||
import {Children} from 'react'
|
||||
import {type TextProps as RNTextProps} from 'react-native'
|
||||
import {type StyleProp, type TextStyle} from 'react-native'
|
||||
import {UITextView} from 'react-native-uitextview'
|
||||
import createEmojiRegex from 'emoji-regex'
|
||||
import type React from 'react'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {Alf, applyFonts, atoms, flatten} from '#/alf'
|
||||
import {type Alf, applyFonts, atoms, flatten} from '#/alf'
|
||||
|
||||
/**
|
||||
* Util to calculate lineHeight from a text size atom and a leading atom
|
||||
@@ -110,7 +111,10 @@ export function renderChildrenWithEmoji(
|
||||
return child.split(EMOJI).map((stringPart, index) => [
|
||||
stringPart,
|
||||
emojis[index] ? (
|
||||
<UITextView {...props} style={[props?.style, {fontFamily: 'System'}]}>
|
||||
<UITextView
|
||||
{...props}
|
||||
style={[props?.style, {fontFamily: 'System'}]}
|
||||
key={index}>
|
||||
{emojis[index]}
|
||||
</UITextView>
|
||||
) : null,
|
||||
|
||||
@@ -23,6 +23,7 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {parseStarterPackUri} from '#/lib/strings/starter-pack'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useActorStarterPacksQuery} from '#/state/queries/actor-starter-packs'
|
||||
import {List, type ListRef} from '#/view/com/util/List'
|
||||
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||
@@ -111,7 +112,7 @@ export const ProfileStarterPacks = React.forwardRef<
|
||||
}, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
|
||||
|
||||
useEffect(() => {
|
||||
if (enabled && scrollElRef.current) {
|
||||
if (isIOS && enabled && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import {useState} from 'react'
|
||||
import {Modal, Pressable, View} from 'react-native'
|
||||
// @ts-expect-error internal component, not supposed to be used directly
|
||||
// waiting on more customisability: https://github.com/okwasniewski/react-native-emoji-popup/issues/1#issuecomment-2737463753
|
||||
import EmojiPopupView from 'react-native-emoji-popup/src/EmojiPopupViewNativeComponent'
|
||||
import {SafeAreaView} from 'react-native-safe-area-context'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon} from '#/components/Button'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded} from '#/components/icons/Times'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as CloseIcon} from '#/components/icons/Times'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {EmojiPicker} from '../../../modules/expo-emoji-picker'
|
||||
|
||||
export function EmojiPopup({
|
||||
children,
|
||||
@@ -34,13 +33,14 @@ export function EmojiPopup({
|
||||
|
||||
<Modal
|
||||
animationType="slide"
|
||||
transparent={true}
|
||||
visible={modalVisible}
|
||||
onRequestClose={() => setModalVisible(false)}>
|
||||
<View style={[a.flex_1, {backgroundColor: t.palette.white}]}>
|
||||
onRequestClose={() => setModalVisible(false)}
|
||||
transparent
|
||||
statusBarTranslucent
|
||||
navigationBarTranslucent>
|
||||
<SafeAreaView style={[a.flex_1, t.atoms.bg]}>
|
||||
<View
|
||||
style={[
|
||||
t.atoms.bg,
|
||||
a.pl_lg,
|
||||
a.pr_md,
|
||||
a.py_sm,
|
||||
@@ -61,21 +61,16 @@ export function EmojiPopup({
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
shape="round">
|
||||
<ButtonIcon icon={TimesLarge_Stroke2_Corner0_Rounded} />
|
||||
<ButtonIcon icon={CloseIcon} />
|
||||
</Button>
|
||||
</View>
|
||||
<EmojiPopupView
|
||||
onEmojiSelected={({
|
||||
nativeEvent: {emoji},
|
||||
}: {
|
||||
nativeEvent: {emoji: string}
|
||||
}) => {
|
||||
<EmojiPicker
|
||||
onEmojiSelected={emoji => {
|
||||
setModalVisible(false)
|
||||
onEmojiSelected(emoji)
|
||||
}}
|
||||
style={[a.flex_1, a.w_full]}
|
||||
/>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1 +1 @@
|
||||
export {EmojiPopup} from 'react-native-emoji-popup'
|
||||
export {EmojiPicker as EmojiPopup} from '../../../modules/expo-emoji-picker'
|
||||
|
||||
+15
-15
@@ -1,23 +1,23 @@
|
||||
import {
|
||||
$Typed,
|
||||
AppBskyEmbedExternal,
|
||||
AppBskyEmbedImages,
|
||||
AppBskyEmbedRecord,
|
||||
AppBskyEmbedRecordWithMedia,
|
||||
AppBskyEmbedVideo,
|
||||
AppBskyFeedPost,
|
||||
type $Typed,
|
||||
type AppBskyEmbedExternal,
|
||||
type AppBskyEmbedImages,
|
||||
type AppBskyEmbedRecord,
|
||||
type AppBskyEmbedRecordWithMedia,
|
||||
type AppBskyEmbedVideo,
|
||||
type AppBskyFeedPost,
|
||||
AtUri,
|
||||
BlobRef,
|
||||
BskyAgent,
|
||||
ComAtprotoLabelDefs,
|
||||
ComAtprotoRepoApplyWrites,
|
||||
ComAtprotoRepoStrongRef,
|
||||
type BskyAgent,
|
||||
type ComAtprotoLabelDefs,
|
||||
type ComAtprotoRepoApplyWrites,
|
||||
type ComAtprotoRepoStrongRef,
|
||||
RichText,
|
||||
} from '@atproto/api'
|
||||
import {TID} from '@atproto/common-web'
|
||||
import * as dcbor from '@ipld/dag-cbor'
|
||||
import {t} from '@lingui/macro'
|
||||
import {QueryClient} from '@tanstack/react-query'
|
||||
import {type QueryClient} from '@tanstack/react-query'
|
||||
import {sha256} from 'js-sha256'
|
||||
import {CID} from 'multiformats/cid'
|
||||
import * as Hasher from 'multiformats/hashes/hasher'
|
||||
@@ -35,9 +35,9 @@ import {
|
||||
threadgateAllowUISettingToAllowRecordValue,
|
||||
} from '#/state/queries/threadgate'
|
||||
import {
|
||||
EmbedDraft,
|
||||
PostDraft,
|
||||
ThreadDraft,
|
||||
type EmbedDraft,
|
||||
type PostDraft,
|
||||
type ThreadDraft,
|
||||
} from '#/view/com/composer/state/composer'
|
||||
import {createGIFDescription} from '../gif-alt-text'
|
||||
import {uploadBlob} from './upload-blob'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {ForwardedRef, useEffect, useMemo, useRef} from 'react'
|
||||
import type {ScrollView} from 'react-native'
|
||||
import {findNodeHandle, Platform} from 'react-native'
|
||||
import {type ForwardedRef, useEffect, useMemo, useRef} from 'react'
|
||||
import {type ScrollView} from 'react-native'
|
||||
import {Platform} from 'react-native'
|
||||
|
||||
import {mergeRefs} from '#/lib/merge-refs'
|
||||
|
||||
@@ -19,7 +19,7 @@ export function useDraggableScroll<Scrollable extends ScrollView = ScrollView>({
|
||||
if (Platform.OS !== 'web' || !ref.current) {
|
||||
return
|
||||
}
|
||||
const slider = findNodeHandle(ref.current) as unknown as HTMLDivElement
|
||||
const slider = ref.current as unknown as HTMLDivElement
|
||||
if (!slider) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import {CommonActions, useNavigation} from '@react-navigation/native'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
|
||||
import {NavigationProp} from '#/lib/routes/types'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {Logger} from '#/logger'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
@@ -41,10 +41,11 @@ type NotificationPayload =
|
||||
}
|
||||
|
||||
const DEFAULT_HANDLER_OPTIONS = {
|
||||
shouldShowAlert: false,
|
||||
shouldShowBanner: false,
|
||||
shouldShowList: false,
|
||||
shouldPlaySound: false,
|
||||
shouldSetBadge: true,
|
||||
}
|
||||
} satisfies Notifications.NotificationBehavior
|
||||
|
||||
// These need to stay outside the hook to persist between account switches
|
||||
let storedPayload: NotificationPayload | undefined
|
||||
@@ -195,11 +196,13 @@ export function useNotificationsHandler() {
|
||||
payload.reason === 'chat-message' &&
|
||||
payload.recipientDid === currentAccount?.did
|
||||
) {
|
||||
const shouldAlert = payload.convoId !== currentConvoId
|
||||
return {
|
||||
shouldShowAlert: payload.convoId !== currentConvoId,
|
||||
shouldShowList: shouldAlert,
|
||||
shouldShowBanner: shouldAlert,
|
||||
shouldPlaySound: false,
|
||||
shouldSetBadge: false,
|
||||
}
|
||||
} satisfies Notifications.NotificationBehavior
|
||||
}
|
||||
|
||||
// Any notification other than a chat message should invalidate the unread page
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {AtUri} from '@atproto/api'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
export function createStarterPackLinkFromAndroidReferrer(
|
||||
referrerQueryString: string,
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import 'react-native-url-polyfill/auto'
|
||||
import 'fast-text-encoding'
|
||||
// @ts-ignore no decl -prf
|
||||
import findLast from 'array.prototype.findlast'
|
||||
export {}
|
||||
|
||||
findLast.shim()
|
||||
|
||||
/**
|
||||
https://github.com/MaxArt2501/base64-js
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// @ts-ignore no decl -prf
|
||||
import * as findLast from 'array.prototype.findlast'
|
||||
import 'array.prototype.findlast/auto'
|
||||
/// <reference lib="dom" />
|
||||
|
||||
findLast.shim()
|
||||
|
||||
// @ts-ignore whatever typescript wants to complain about here, I dont care about -prf
|
||||
window.setImmediate = (cb: () => void) => setTimeout(cb, 0)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import {useLingui} from '@lingui/react'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {isIOS, isNative} from '#/platform/detection'
|
||||
import {type FeedDescriptor} from '#/state/queries/post-feed'
|
||||
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
||||
import {truncateAndInvalidate} from '#/state/queries/util'
|
||||
@@ -67,7 +67,7 @@ export const ProfileFeedSection = React.forwardRef<
|
||||
}, [_])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isFocused && scrollElRef.current) {
|
||||
if (isIOS && isFocused && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {useLingui} from '@lingui/react'
|
||||
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
||||
import {isLabelerSubscribed, lookupLabelValueDefinition} from '#/lib/moderation'
|
||||
import {useScrollHandlers} from '#/lib/ScrollContext'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {isIOS, isNative} from '#/platform/detection'
|
||||
import {type ListRef} from '#/view/com/util/List'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Divider} from '#/components/Divider'
|
||||
@@ -92,7 +92,7 @@ export const ProfileLabelsSection = React.forwardRef<
|
||||
}))
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isFocused && scrollElRef.current) {
|
||||
if (isIOS && isFocused && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ import {LazyQuoteEmbed, QuoteX} from '#/view/com/util/post-embeds/QuoteEmbed'
|
||||
import {Text} from '#/view/com/util/text/Text'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {atoms as a, native, useTheme} from '#/alf'
|
||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog'
|
||||
@@ -1266,39 +1266,41 @@ function ComposerFooter({
|
||||
a.justify_between,
|
||||
]}>
|
||||
<View style={[a.flex_row, a.align_center]}>
|
||||
{video && video.status !== 'done' ? (
|
||||
<VideoUploadToolbar state={video} />
|
||||
) : (
|
||||
<ToolbarWrapper style={[a.flex_row, a.align_center, a.gap_xs]}>
|
||||
<SelectPhotoBtn
|
||||
size={images.length}
|
||||
disabled={media?.type === 'images' ? isMaxImages : !!media}
|
||||
onAdd={onImageAdd}
|
||||
/>
|
||||
<SelectVideoBtn
|
||||
onSelectVideo={asset => onSelectVideo(post.id, asset)}
|
||||
disabled={!!media}
|
||||
setError={onError}
|
||||
/>
|
||||
<OpenCameraBtn
|
||||
disabled={media?.type === 'images' ? isMaxImages : !!media}
|
||||
onAdd={onImageAdd}
|
||||
/>
|
||||
<SelectGifBtn onSelectGif={onSelectGif} disabled={!!media} />
|
||||
{!isMobile ? (
|
||||
<Button
|
||||
onPress={onEmojiButtonPress}
|
||||
style={a.p_sm}
|
||||
label={_(msg`Open emoji picker`)}
|
||||
accessibilityHint={_(msg`Opens emoji picker`)}
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="primary">
|
||||
<EmojiSmile size="lg" />
|
||||
</Button>
|
||||
) : null}
|
||||
</ToolbarWrapper>
|
||||
)}
|
||||
<LayoutAnimationConfig skipEntering skipExiting>
|
||||
{video && video.status !== 'done' ? (
|
||||
<VideoUploadToolbar state={video} />
|
||||
) : (
|
||||
<ToolbarWrapper style={[a.flex_row, a.align_center, a.gap_xs]}>
|
||||
<SelectPhotoBtn
|
||||
size={images.length}
|
||||
disabled={media?.type === 'images' ? isMaxImages : !!media}
|
||||
onAdd={onImageAdd}
|
||||
/>
|
||||
<SelectVideoBtn
|
||||
onSelectVideo={asset => onSelectVideo(post.id, asset)}
|
||||
disabled={!!media}
|
||||
setError={onError}
|
||||
/>
|
||||
<OpenCameraBtn
|
||||
disabled={media?.type === 'images' ? isMaxImages : !!media}
|
||||
onAdd={onImageAdd}
|
||||
/>
|
||||
<SelectGifBtn onSelectGif={onSelectGif} disabled={!!media} />
|
||||
{!isMobile ? (
|
||||
<Button
|
||||
onPress={onEmojiButtonPress}
|
||||
style={a.p_sm}
|
||||
label={_(msg`Open emoji picker`)}
|
||||
accessibilityHint={_(msg`Opens emoji picker`)}
|
||||
variant="ghost"
|
||||
shape="round"
|
||||
color="primary">
|
||||
<EmojiSmile size="lg" />
|
||||
</Button>
|
||||
) : null}
|
||||
</ToolbarWrapper>
|
||||
)}
|
||||
</LayoutAnimationConfig>
|
||||
</View>
|
||||
<View style={[a.flex_row, a.align_center, a.justify_between]}>
|
||||
{showAddButton && (
|
||||
@@ -1515,10 +1517,10 @@ const styles = StyleSheet.create({
|
||||
paddingVertical: 6,
|
||||
marginLeft: 12,
|
||||
},
|
||||
stickyFooterWeb: {
|
||||
stickyFooterWeb: web({
|
||||
position: 'sticky',
|
||||
bottom: 0,
|
||||
},
|
||||
}),
|
||||
errorLine: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
|
||||
@@ -15,7 +15,7 @@ import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {type ComposerOptsPostRef} from '#/state/shell/composer'
|
||||
import {MaybeQuoteEmbed} from '#/view/com/util/post-embeds/QuoteEmbed'
|
||||
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useSimpleVerificationState} from '#/components/verification'
|
||||
import {VerificationCheck} from '#/components/verification/VerificationCheck'
|
||||
@@ -76,7 +76,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
|
||||
a.mx_lg,
|
||||
a.border_b,
|
||||
t.atoms.border_contrast_medium,
|
||||
a.user_select_text,
|
||||
web(a.user_select_text),
|
||||
]}
|
||||
onPress={onPress}
|
||||
accessibilityRole="button"
|
||||
|
||||
@@ -12,7 +12,7 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {RQKEY, useProfileFeedgensQuery} from '#/state/queries/profile-feedgens'
|
||||
import {EmptyState} from '#/view/com/util/EmptyState'
|
||||
@@ -175,7 +175,7 @@ export const ProfileFeedgens = React.forwardRef<
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
if (enabled && scrollElRef.current) {
|
||||
if (isIOS && enabled && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -510,20 +510,22 @@ function LightboxImage({
|
||||
// This is a bug in Reanimated, but for now we'll work around it like this.
|
||||
dismissSwipeTranslateY.set(1)
|
||||
}
|
||||
dismissSwipeTranslateY.set(() =>
|
||||
withDecay({
|
||||
dismissSwipeTranslateY.set(() => {
|
||||
'worklet'
|
||||
return withDecay({
|
||||
velocity: e.velocityY,
|
||||
velocityFactor: Math.max(3500 / Math.abs(e.velocityY), 1), // Speed up if it's too slow.
|
||||
deceleration: 1, // Danger! This relies on the reaction below stopping it.
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
dismissSwipeTranslateY.set(() =>
|
||||
withSpring(0, {
|
||||
dismissSwipeTranslateY.set(() => {
|
||||
'worklet'
|
||||
return withSpring(0, {
|
||||
stiffness: 700,
|
||||
damping: 50,
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {RQKEY, useProfileListsQuery} from '#/state/queries/profile-lists'
|
||||
import {EmptyState} from '#/view/com/util/EmptyState'
|
||||
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
|
||||
@@ -171,7 +171,7 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
if (enabled && scrollElRef.current) {
|
||||
if (isIOS && enabled && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
import React, {ComponentProps} from 'react'
|
||||
import {type ComponentPropsWithRef} from 'react'
|
||||
import {ScrollView} from 'react-native'
|
||||
|
||||
import {useDraggableScroll} from '#/lib/hooks/useDraggableScrollView'
|
||||
import {atoms as a, web} from '#/alf'
|
||||
|
||||
export const DraggableScrollView = React.forwardRef<
|
||||
ScrollView,
|
||||
ComponentProps<typeof ScrollView>
|
||||
>(function DraggableScrollView(props, ref) {
|
||||
export function DraggableScrollView({
|
||||
ref,
|
||||
style,
|
||||
...props
|
||||
}: ComponentPropsWithRef<typeof ScrollView>) {
|
||||
const {refs} = useDraggableScroll<ScrollView>({
|
||||
outerRef: ref,
|
||||
cursor: 'grab', // optional, default
|
||||
})
|
||||
|
||||
return <ScrollView ref={refs} horizontal {...props} />
|
||||
})
|
||||
return (
|
||||
<ScrollView
|
||||
ref={refs}
|
||||
style={[style, web(a.user_select_none)]}
|
||||
horizontal
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import {useCallback} from 'react'
|
||||
import {LayoutChangeEvent, ScrollView, StyleSheet, View} from 'react-native'
|
||||
import {
|
||||
type LayoutChangeEvent,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import Animated, {
|
||||
interpolate,
|
||||
runOnJS,
|
||||
runOnUI,
|
||||
scrollTo,
|
||||
SharedValue,
|
||||
type SharedValue,
|
||||
useAnimatedReaction,
|
||||
useAnimatedRef,
|
||||
useAnimatedStyle,
|
||||
@@ -267,15 +272,27 @@ export function TabBar({
|
||||
{
|
||||
translateX: interpolate(
|
||||
dragProgress.get(),
|
||||
layoutsValue.map((l, i) => i),
|
||||
layoutsValue.map(l => l.x + l.width / 2 - contentSize.get() / 2),
|
||||
layoutsValue.map((l, i) => {
|
||||
'worklet'
|
||||
return i
|
||||
}),
|
||||
layoutsValue.map(l => {
|
||||
'worklet'
|
||||
return l.x + l.width / 2 - contentSize.get() / 2
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
scaleX: interpolate(
|
||||
dragProgress.get(),
|
||||
textLayoutsValue.map((l, i) => i),
|
||||
textLayoutsValue.map((l, i) => getScaleX(i)),
|
||||
textLayoutsValue.map((l, i) => {
|
||||
'worklet'
|
||||
return i
|
||||
}),
|
||||
textLayoutsValue.map((l, i) => {
|
||||
'worklet'
|
||||
return getScaleX(i)
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useCallback, useEffect, useRef} from 'react'
|
||||
import {ScrollView, StyleSheet, View} from 'react-native'
|
||||
import {type ScrollView, StyleSheet, View} from 'react-native'
|
||||
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {PressableWithHover} from '../util/PressableWithHover'
|
||||
import {DraggableScrollView} from './DraggableScrollView'
|
||||
@@ -161,7 +161,7 @@ const desktopStyles = StyleSheet.create({
|
||||
},
|
||||
itemInner: {
|
||||
alignItems: 'center',
|
||||
overflowX: 'hidden',
|
||||
...web({overflowX: 'hidden'}),
|
||||
},
|
||||
itemText: {
|
||||
textAlign: 'center',
|
||||
@@ -204,7 +204,7 @@ const mobileStyles = StyleSheet.create({
|
||||
itemInner: {
|
||||
flexGrow: 1,
|
||||
alignItems: 'center',
|
||||
overflowX: 'hidden',
|
||||
...web({overflowX: 'hidden'}),
|
||||
},
|
||||
itemText: {
|
||||
textAlign: 'center',
|
||||
|
||||
@@ -2,7 +2,8 @@ import React from 'react'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import Svg, {Circle, Line} from 'react-native-svg'
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {Trans} from '@lingui/macro'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
@@ -22,6 +23,7 @@ export function ViewFullThread({uri}: {uri: string}) {
|
||||
const urip = new AtUri(uri)
|
||||
return makeProfileLink({did: urip.hostname, handle: ''}, 'post', urip.rkey)
|
||||
}, [uri])
|
||||
const {_} = useLingui()
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -53,7 +55,8 @@ export function ViewFullThread({uri}: {uri: string}) {
|
||||
</View>
|
||||
|
||||
<Text type="md" style={[pal.link, {paddingTop: 18, paddingBottom: 4}]}>
|
||||
<Trans>View full thread</Trans>
|
||||
{/* HACKFIX: Trans isn't working after SDK 53 upgrade -sfn */}
|
||||
{_(msg`View full thread`)}
|
||||
</Text>
|
||||
</Link>
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ import RootSiblings from 'react-native-root-siblings'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {
|
||||
FontAwesomeIcon,
|
||||
Props as FontAwesomeProps,
|
||||
type Props as FontAwesomeProps,
|
||||
} from '@fortawesome/react-native-fontawesome'
|
||||
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
* Note: the dataSet properties are used to leverage custom CSS in public/index.html
|
||||
*/
|
||||
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Pressable, StyleSheet, Text, View} from 'react-native'
|
||||
import {
|
||||
FontAwesomeIcon,
|
||||
FontAwesomeIconStyle,
|
||||
Props as FontAwesomeProps,
|
||||
type FontAwesomeIconStyle,
|
||||
type Props as FontAwesomeProps,
|
||||
} from '@fortawesome/react-native-fontawesome'
|
||||
import type React from 'react'
|
||||
|
||||
const DURATION = 3500
|
||||
|
||||
|
||||
@@ -239,7 +239,6 @@ const getKey = (label: string, index: number, id?: string) => {
|
||||
return `${label}_${index}`
|
||||
}
|
||||
|
||||
// @ts-expect-error - web only styles. the only style that should be broken here is `outline`
|
||||
const styles = StyleSheet.create({
|
||||
separator: {
|
||||
height: 1,
|
||||
@@ -264,7 +263,6 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
columnGap: 20,
|
||||
// @ts-ignore -web
|
||||
cursor: 'pointer',
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
@@ -273,6 +271,7 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 8,
|
||||
fontFamily:
|
||||
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif',
|
||||
// @ts-expect-error web only
|
||||
outline: 0,
|
||||
border: 0,
|
||||
},
|
||||
|
||||
@@ -12,9 +12,8 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {colors} from '#/lib/styles'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useLayoutBreakpoints} from '#/alf'
|
||||
import {atoms as a, useLayoutBreakpoints} from '#/alf'
|
||||
|
||||
export function LoadLatestBtn({
|
||||
onPress,
|
||||
@@ -80,7 +79,7 @@ export function LoadLatestBtn({
|
||||
const styles = StyleSheet.create({
|
||||
loadLatest: {
|
||||
zIndex: 20,
|
||||
position: isWeb ? 'fixed' : 'absolute',
|
||||
...a.fixed,
|
||||
left: 18,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
width: 52,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {StyleSheet} from 'react-native'
|
||||
|
||||
import {colors} from '#/lib/styles'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
bottomBar: {
|
||||
@@ -13,9 +14,7 @@ export const styles = StyleSheet.create({
|
||||
paddingLeft: 5,
|
||||
paddingRight: 10,
|
||||
},
|
||||
bottomBarWeb: {
|
||||
position: 'fixed',
|
||||
},
|
||||
bottomBarWeb: a.fixed,
|
||||
ctrl: {
|
||||
flex: 1,
|
||||
paddingTop: 13,
|
||||
|
||||
@@ -32,7 +32,7 @@ import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||
import {PressableWithHover} from '#/view/com/util/PressableWithHover'
|
||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {NavSignupCard} from '#/view/shell/NavSignupCard'
|
||||
import {atoms as a, tokens, useLayoutBreakpoints, useTheme} from '#/alf'
|
||||
import {atoms as a, tokens, useLayoutBreakpoints, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import {type DialogControlProps} from '#/components/Dialog'
|
||||
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft'
|
||||
@@ -718,7 +718,7 @@ export function DesktopLeftNav() {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
leftNav: {
|
||||
position: 'fixed',
|
||||
...a.fixed,
|
||||
top: 0,
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
@@ -736,7 +736,7 @@ const styles = StyleSheet.create({
|
||||
height: '100%',
|
||||
width: 86,
|
||||
alignItems: 'center',
|
||||
overflowX: 'hidden',
|
||||
...web({overflowX: 'hidden'}),
|
||||
},
|
||||
backBtn: {
|
||||
position: 'absolute',
|
||||
|
||||
@@ -8,7 +8,7 @@ import {RemoveScrollBar} from 'react-remove-scroll-bar'
|
||||
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
||||
import {useIntentHandler} from '#/lib/hooks/useIntentHandler'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {NavigationProp} from '#/lib/routes/types'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {colors} from '#/lib/styles'
|
||||
import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
|
||||
import {useComposerKeyboardShortcut} from '#/state/shell/composer/useComposerKeyboardShortcut'
|
||||
@@ -130,7 +130,7 @@ const styles = StyleSheet.create({
|
||||
backgroundColor: colors.black, // TODO
|
||||
},
|
||||
drawerMask: {
|
||||
position: 'fixed',
|
||||
...a.fixed,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
top: 0,
|
||||
@@ -138,7 +138,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
drawerContainer: {
|
||||
display: 'flex',
|
||||
position: 'fixed',
|
||||
...a.fixed,
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: '100%',
|
||||
|
||||
Reference in New Issue
Block a user