Merge branch 'bluesky-social:main' into zh
commit
7548c23f19
|
@ -1,3 +1,29 @@
|
||||||
|
diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
|
||||||
|
index b0d71dc..9974932 100644
|
||||||
|
--- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
|
||||||
|
+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
|
||||||
|
@@ -377,10 +377,6 @@ - (void)textInputDidBeginEditing
|
||||||
|
self.backedTextInputView.attributedText = [NSAttributedString new];
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (_selectTextOnFocus) {
|
||||||
|
- [self.backedTextInputView selectAll:nil];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
|
||||||
|
reactTag:self.reactTag
|
||||||
|
text:[self.backedTextInputView.attributedText.string copy]
|
||||||
|
@@ -611,6 +607,10 @@ - (UIView *)reactAccessibilityElement
|
||||||
|
- (void)reactFocus
|
||||||
|
{
|
||||||
|
[self.backedTextInputView reactFocus];
|
||||||
|
+
|
||||||
|
+ if (_selectTextOnFocus) {
|
||||||
|
+ [self.backedTextInputView selectAll:nil];
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reactBlur
|
||||||
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
||||||
index e9b330f..1ecdf0a 100644
|
index e9b330f..1ecdf0a 100644
|
||||||
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
||||||
|
@ -5,7 +31,7 @@ index e9b330f..1ecdf0a 100644
|
||||||
@@ -16,4 +16,6 @@
|
@@ -16,4 +16,6 @@
|
||||||
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
|
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
|
||||||
@property (nonatomic, weak) UIScrollView *scrollView;
|
@property (nonatomic, weak) UIScrollView *scrollView;
|
||||||
|
|
||||||
+- (void)forwarderBeginRefreshing;
|
+- (void)forwarderBeginRefreshing;
|
||||||
+
|
+
|
||||||
@end
|
@end
|
||||||
|
@ -16,7 +42,7 @@ index b09e653..4c32b31 100644
|
||||||
@@ -198,9 +198,53 @@ - (void)refreshControlValueChanged
|
@@ -198,9 +198,53 @@ - (void)refreshControlValueChanged
|
||||||
[self setCurrentRefreshingState:super.refreshing];
|
[self setCurrentRefreshingState:super.refreshing];
|
||||||
_refreshingProgrammatically = NO;
|
_refreshingProgrammatically = NO;
|
||||||
|
|
||||||
+ if (@available(iOS 17.4, *)) {
|
+ if (@available(iOS 17.4, *)) {
|
||||||
+ if (_currentRefreshingState) {
|
+ if (_currentRefreshingState) {
|
||||||
+ UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
|
+ UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
|
||||||
|
@ -29,7 +55,7 @@ index b09e653..4c32b31 100644
|
||||||
_onRefresh(nil);
|
_onRefresh(nil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+/*
|
+/*
|
||||||
+ This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native
|
+ This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native
|
||||||
+ libraries to perform a refresh of a scrollview and access the refresh control's onRefresh
|
+ libraries to perform a refresh of a scrollview and access the refresh control's onRefresh
|
||||||
|
@ -38,15 +64,15 @@ index b09e653..4c32b31 100644
|
||||||
+- (void)forwarderBeginRefreshing
|
+- (void)forwarderBeginRefreshing
|
||||||
+{
|
+{
|
||||||
+ _refreshingProgrammatically = NO;
|
+ _refreshingProgrammatically = NO;
|
||||||
+
|
+
|
||||||
+ [self sizeToFit];
|
+ [self sizeToFit];
|
||||||
+
|
+
|
||||||
+ if (!self.scrollView) {
|
+ if (!self.scrollView) {
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView;
|
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView;
|
||||||
+
|
+
|
||||||
+ [UIView animateWithDuration:0.3
|
+ [UIView animateWithDuration:0.3
|
||||||
+ delay:0
|
+ delay:0
|
||||||
+ options:UIViewAnimationOptionBeginFromCurrentState
|
+ options:UIViewAnimationOptionBeginFromCurrentState
|
||||||
|
@ -58,7 +84,7 @@ index b09e653..4c32b31 100644
|
||||||
+ completion:^(__unused BOOL finished) {
|
+ completion:^(__unused BOOL finished) {
|
||||||
+ [super beginRefreshing];
|
+ [super beginRefreshing];
|
||||||
+ [self setCurrentRefreshingState:super.refreshing];
|
+ [self setCurrentRefreshingState:super.refreshing];
|
||||||
+
|
+
|
||||||
+ if (self->_onRefresh) {
|
+ if (self->_onRefresh) {
|
||||||
+ self->_onRefresh(nil);
|
+ self->_onRefresh(nil);
|
||||||
+ }
|
+ }
|
||||||
|
@ -73,7 +99,7 @@ index 5f5e1ab..aac00b6 100644
|
||||||
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java
|
||||||
@@ -99,8 +99,9 @@ public class JavaTimerManager {
|
@@ -99,8 +99,9 @@ public class JavaTimerManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the JS thread is busy for multiple frames we cancel any other pending runnable.
|
// If the JS thread is busy for multiple frames we cancel any other pending runnable.
|
||||||
- if (mCurrentIdleCallbackRunnable != null) {
|
- if (mCurrentIdleCallbackRunnable != null) {
|
||||||
- mCurrentIdleCallbackRunnable.cancel();
|
- mCurrentIdleCallbackRunnable.cancel();
|
||||||
|
@ -81,5 +107,5 @@ index 5f5e1ab..aac00b6 100644
|
||||||
+ if (currentRunnable != null) {
|
+ if (currentRunnable != null) {
|
||||||
+ currentRunnable.cancel();
|
+ currentRunnable.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);
|
mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);
|
||||||
|
|
|
@ -11,3 +11,10 @@ in the RN repo: https://github.com/facebook/react-native/issues/43388
|
||||||
Patching `RCTRefreshControl.m` and `RCTRefreshControl.h` to add a new `forwarderBeginRefreshing` method to the class.
|
Patching `RCTRefreshControl.m` and `RCTRefreshControl.h` to add a new `forwarderBeginRefreshing` method to the class.
|
||||||
This method is used by `ExpoScrollForwarder` to initiate a refresh of the underlying `UIScrollView` from inside that
|
This method is used by `ExpoScrollForwarder` to initiate a refresh of the underlying `UIScrollView` from inside that
|
||||||
module.
|
module.
|
||||||
|
|
||||||
|
|
||||||
|
## TextInput Patch - `selectTextOnFocus` fix
|
||||||
|
|
||||||
|
Patching `RCTBaseTextInputView.m` to fix an issue where `selectTextOnFocus` does not work as expected on iOS 17. This
|
||||||
|
patch _only_ fixes the Paper version of `TextInput`. If we migrate to Fabric and the fix has not been made upstream,
|
||||||
|
we can apply the same fix. See https://github.com/facebook/react-native/pull/44307.
|
||||||
|
|
|
@ -14,7 +14,11 @@ import * as SplashScreen from 'expo-splash-screen'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
|
import {
|
||||||
|
initialize,
|
||||||
|
Provider as StatsigProvider,
|
||||||
|
tryFetchGates,
|
||||||
|
} from '#/lib/statsig/statsig'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {MessagesProvider} from '#/state/messages'
|
import {MessagesProvider} from '#/state/messages'
|
||||||
import {init as initPersistedState} from '#/state/persisted'
|
import {init as initPersistedState} from '#/state/persisted'
|
||||||
|
@ -69,6 +73,9 @@ function InnerApp() {
|
||||||
try {
|
try {
|
||||||
if (account) {
|
if (account) {
|
||||||
await resumeSession(account)
|
await resumeSession(account)
|
||||||
|
} else {
|
||||||
|
await initialize()
|
||||||
|
await tryFetchGates(undefined, 'prefer-fresh-gates')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(`session: resume failed`, {message: e})
|
logger.error(`session: resume failed`, {message: e})
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
useRemoveFeedMutation,
|
useRemoveFeedMutation,
|
||||||
} from '#/state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {sanitizeHandle} from 'lib/strings/handles'
|
import {sanitizeHandle} from 'lib/strings/handles'
|
||||||
|
import {useSession} from 'state/session'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import * as Toast from 'view/com/util/Toast'
|
import * as Toast from 'view/com/util/Toast'
|
||||||
import {useTheme} from '#/alf'
|
import {useTheme} from '#/alf'
|
||||||
|
@ -116,6 +117,12 @@ export function Likes({count}: {count: number}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Action({uri, pin}: {uri: string; pin?: boolean}) {
|
export function Action({uri, pin}: {uri: string; pin?: boolean}) {
|
||||||
|
const {hasSession} = useSession()
|
||||||
|
if (!hasSession) return null
|
||||||
|
return <ActionInner uri={uri} pin={pin} />
|
||||||
|
}
|
||||||
|
|
||||||
|
function ActionInner({uri, pin}: {uri: string; pin?: boolean}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {data: preferences} = usePreferencesQuery()
|
const {data: preferences} = usePreferencesQuery()
|
||||||
const {isPending: isAddSavedFeedPending, mutateAsync: saveFeeds} =
|
const {isPending: isAddSavedFeedPending, mutateAsync: saveFeeds} =
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export type Gate =
|
export type Gate =
|
||||||
// Keep this alphabetic please.
|
// Keep this alphabetic please.
|
||||||
|
| 'native_pwi_disabled'
|
||||||
| 'request_notifications_permission_after_onboarding_v2'
|
| 'request_notifications_permission_after_onboarding_v2'
|
||||||
| 'show_avi_follow_button'
|
| 'show_avi_follow_button'
|
||||||
| 'show_follow_back_label_v2'
|
| 'show_follow_back_label_v2'
|
||||||
|
|
|
@ -14,6 +14,8 @@ import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback'
|
||||||
import {LogEvents} from './events'
|
import {LogEvents} from './events'
|
||||||
import {Gate} from './gates'
|
import {Gate} from './gates'
|
||||||
|
|
||||||
|
const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV'
|
||||||
|
|
||||||
type StatsigUser = {
|
type StatsigUser = {
|
||||||
userID: string | undefined
|
userID: string | undefined
|
||||||
// TODO: Remove when enough users have custom.platform:
|
// TODO: Remove when enough users have custom.platform:
|
||||||
|
@ -251,7 +253,7 @@ AppState.addEventListener('change', (state: AppStateStatus) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
export async function tryFetchGates(
|
export async function tryFetchGates(
|
||||||
did: string,
|
did: string | undefined,
|
||||||
strategy: 'prefer-low-latency' | 'prefer-fresh-gates',
|
strategy: 'prefer-low-latency' | 'prefer-fresh-gates',
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
@ -275,6 +277,10 @@ export async function tryFetchGates(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function initialize() {
|
||||||
|
return Statsig.initialize(SDK_KEY, null, createStatsigOptions([]))
|
||||||
|
}
|
||||||
|
|
||||||
export function Provider({children}: {children: React.ReactNode}) {
|
export function Provider({children}: {children: React.ReactNode}) {
|
||||||
const {currentAccount, accounts} = useSession()
|
const {currentAccount, accounts} = useSession()
|
||||||
const did = currentAccount?.did
|
const did = currentAccount?.did
|
||||||
|
@ -320,7 +326,7 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||||
<GateCache.Provider value={gateCache}>
|
<GateCache.Provider value={gateCache}>
|
||||||
<StatsigProvider
|
<StatsigProvider
|
||||||
key={did}
|
key={did}
|
||||||
sdkKey="client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV"
|
sdkKey={SDK_KEY}
|
||||||
mountKey={currentStatsigUser.userID}
|
mountKey={currentStatsigUser.userID}
|
||||||
user={currentStatsigUser}
|
user={currentStatsigUser}
|
||||||
// This isn't really blocking due to short initTimeoutMs above.
|
// This isn't really blocking due to short initTimeoutMs above.
|
||||||
|
|
|
@ -152,7 +152,7 @@ export function Layout({children}: React.PropsWithChildren<{}>) {
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{height: 200}} />
|
<View style={{height: 400}} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import ViewShot from 'react-native-view-shot'
|
||||||
import {useAvatar} from '#/screens/Onboarding/StepProfile/index'
|
import {useAvatar} from '#/screens/Onboarding/StepProfile/index'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
|
|
||||||
const SIZE_MULTIPLIER = 1.5
|
const SIZE_MULTIPLIER = 5
|
||||||
|
|
||||||
export interface PlaceholderCanvasRef {
|
export interface PlaceholderCanvasRef {
|
||||||
capture: () => Promise<string>
|
capture: () => Promise<string>
|
||||||
|
|
|
@ -234,26 +234,28 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
|
||||||
data: InfiniteData<AppBskyUnspeccedGetPopularFeedGenerators.OutputSchema>,
|
data: InfiniteData<AppBskyUnspeccedGetPopularFeedGenerators.OutputSchema>,
|
||||||
) => {
|
) => {
|
||||||
const {savedFeeds, hasSession: hasSessionInner} = selectArgs
|
const {savedFeeds, hasSession: hasSessionInner} = selectArgs
|
||||||
data?.pages.map(page => {
|
return {
|
||||||
page.feeds = page.feeds.filter(feed => {
|
...data,
|
||||||
if (
|
pages: data.pages.map(page => {
|
||||||
!hasSessionInner &&
|
return {
|
||||||
KNOWN_AUTHED_ONLY_FEEDS.includes(feed.uri)
|
...page,
|
||||||
) {
|
feeds: page.feeds.filter(feed => {
|
||||||
return false
|
if (
|
||||||
}
|
!hasSessionInner &&
|
||||||
const alreadySaved = Boolean(
|
KNOWN_AUTHED_ONLY_FEEDS.includes(feed.uri)
|
||||||
savedFeeds?.find(f => {
|
) {
|
||||||
return f.value === feed.uri
|
return false
|
||||||
|
}
|
||||||
|
const alreadySaved = Boolean(
|
||||||
|
savedFeeds?.find(f => {
|
||||||
|
return f.value === feed.uri
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
return !alreadySaved
|
||||||
}),
|
}),
|
||||||
)
|
}
|
||||||
return !alreadySaved
|
}),
|
||||||
})
|
}
|
||||||
|
|
||||||
return page
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
},
|
},
|
||||||
[selectArgs /* Don't change. Everything needs to go into selectArgs. */],
|
[selectArgs /* Don't change. Everything needs to go into selectArgs. */],
|
||||||
),
|
),
|
||||||
|
|
|
@ -16,18 +16,17 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
||||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||||
import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
|
import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
|
||||||
import {useSession} from '#/state/session'
|
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
|
import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
|
||||||
import {List} from '#/view/com/util/List'
|
import {List} from '#/view/com/util/List'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
|
|
||||||
import {
|
import {
|
||||||
FeedFeedLoadingPlaceholder,
|
FeedFeedLoadingPlaceholder,
|
||||||
ProfileCardFeedLoadingPlaceholder,
|
ProfileCardFeedLoadingPlaceholder,
|
||||||
} from 'view/com/util/LoadingPlaceholder'
|
} from 'view/com/util/LoadingPlaceholder'
|
||||||
import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
|
import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {ArrowBottom_Stroke2_Corner0_Rounded as ArrowBottom} from '#/components/icons/Arrow'
|
import {ArrowBottom_Stroke2_Corner0_Rounded as ArrowBottom} from '#/components/icons/Arrow'
|
||||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
@ -271,7 +270,6 @@ type ExploreScreenItems =
|
||||||
export function Explore() {
|
export function Explore() {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {hasSession} = useSession()
|
|
||||||
const {data: preferences, error: preferencesError} = usePreferencesQuery()
|
const {data: preferences, error: preferencesError} = usePreferencesQuery()
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const {
|
const {
|
||||||
|
@ -480,15 +478,14 @@ export function Explore() {
|
||||||
}
|
}
|
||||||
case 'feed': {
|
case 'feed': {
|
||||||
return (
|
return (
|
||||||
<View style={[a.border_b, t.atoms.border_contrast_low]}>
|
<View
|
||||||
<FeedSourceCard
|
style={[
|
||||||
feedUri={item.feed.uri}
|
a.border_b,
|
||||||
showSaveBtn={hasSession}
|
t.atoms.border_contrast_low,
|
||||||
showDescription
|
a.px_lg,
|
||||||
showLikes
|
a.py_lg,
|
||||||
pinOnSave
|
]}>
|
||||||
hideTopBorder
|
<FeedCard.Default feed={item.feed} />
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -538,7 +535,7 @@ export function Explore() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[t, hasSession, moderationOpts],
|
[t, moderationOpts],
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -30,7 +30,7 @@ import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {NavigationProp} from '#/lib/routes/types'
|
import {NavigationProp} from '#/lib/routes/types'
|
||||||
import {augmentSearchQuery} from '#/lib/strings/helpers'
|
import {augmentSearchQuery} from '#/lib/strings/helpers'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
import {isNative, isWeb} from '#/platform/detection'
|
||||||
import {listenSoftReset} from '#/state/events'
|
import {listenSoftReset} from '#/state/events'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||||
|
@ -57,8 +57,8 @@ import {Text} from '#/view/com/util/text/Text'
|
||||||
import {CenteredView, ScrollView} from '#/view/com/util/Views'
|
import {CenteredView, ScrollView} from '#/view/com/util/Views'
|
||||||
import {Explore} from '#/view/screens/Search/Explore'
|
import {Explore} from '#/view/screens/Search/Explore'
|
||||||
import {SearchLinkCard, SearchProfileCard} from '#/view/shell/desktop/Search'
|
import {SearchLinkCard, SearchProfileCard} from '#/view/shell/desktop/Search'
|
||||||
import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
|
import {atoms as a, useTheme as useThemeNew} from '#/alf'
|
||||||
import {atoms as a} from '#/alf'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
|
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
|
||||||
|
|
||||||
function Loader() {
|
function Loader() {
|
||||||
|
@ -285,8 +285,8 @@ let SearchScreenFeedsResults = ({
|
||||||
query: string
|
query: string
|
||||||
active: boolean
|
active: boolean
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
|
const t = useThemeNew()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {hasSession} = useSession()
|
|
||||||
|
|
||||||
const {data: results, isFetched} = usePopularFeedsSearch({
|
const {data: results, isFetched} = usePopularFeedsSearch({
|
||||||
query,
|
query,
|
||||||
|
@ -299,13 +299,15 @@ let SearchScreenFeedsResults = ({
|
||||||
<List
|
<List
|
||||||
data={results}
|
data={results}
|
||||||
renderItem={({item}) => (
|
renderItem={({item}) => (
|
||||||
<FeedSourceCard
|
<View
|
||||||
feedUri={item.uri}
|
style={[
|
||||||
showSaveBtn={hasSession}
|
a.border_b,
|
||||||
showDescription
|
t.atoms.border_contrast_low,
|
||||||
showLikes
|
a.px_lg,
|
||||||
pinOnSave
|
a.py_lg,
|
||||||
/>
|
]}>
|
||||||
|
<FeedCard.Default feed={item} />
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
keyExtractor={item => item.uri}
|
keyExtractor={item => item.uri}
|
||||||
// @ts-ignore web only -prf
|
// @ts-ignore web only -prf
|
||||||
|
@ -802,12 +804,6 @@ let SearchInputBox = ({
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setShowAutocomplete(true)
|
setShowAutocomplete(true)
|
||||||
if (isIOS) {
|
|
||||||
// We rely on selectTextOnFocus, but it's broken on iOS:
|
|
||||||
// https://github.com/facebook/react-native/issues/41988
|
|
||||||
textInput.current?.setSelection(0, searchText.length)
|
|
||||||
// We still rely on selectTextOnFocus for it to be instant on Android.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChangeText={onChangeText}
|
onChangeText={onChangeText}
|
||||||
|
|
|
@ -29,7 +29,8 @@ import {
|
||||||
useLoggedOutView,
|
useLoggedOutView,
|
||||||
useLoggedOutViewControls,
|
useLoggedOutViewControls,
|
||||||
} from '#/state/shell/logged-out'
|
} from '#/state/shell/logged-out'
|
||||||
import {isWeb} from 'platform/detection'
|
import {useGate} from 'lib/statsig/statsig'
|
||||||
|
import {isNative, isWeb} from 'platform/detection'
|
||||||
import {Deactivated} from '#/screens/Deactivated'
|
import {Deactivated} from '#/screens/Deactivated'
|
||||||
import {Onboarding} from '#/screens/Onboarding'
|
import {Onboarding} from '#/screens/Onboarding'
|
||||||
import {SignupQueued} from '#/screens/SignupQueued'
|
import {SignupQueued} from '#/screens/SignupQueued'
|
||||||
|
@ -50,6 +51,7 @@ function NativeStackNavigator({
|
||||||
screenOptions,
|
screenOptions,
|
||||||
...rest
|
...rest
|
||||||
}: NativeStackNavigatorProps) {
|
}: NativeStackNavigatorProps) {
|
||||||
|
const gate = useGate()
|
||||||
// --- this is copy and pasted from the original native stack navigator ---
|
// --- this is copy and pasted from the original native stack navigator ---
|
||||||
const {state, descriptors, navigation, NavigationContent} =
|
const {state, descriptors, navigation, NavigationContent} =
|
||||||
useNavigationBuilder<
|
useNavigationBuilder<
|
||||||
|
@ -100,7 +102,11 @@ function NativeStackNavigator({
|
||||||
const {showLoggedOut} = useLoggedOutView()
|
const {showLoggedOut} = useLoggedOutView()
|
||||||
const {setShowLoggedOut} = useLoggedOutViewControls()
|
const {setShowLoggedOut} = useLoggedOutViewControls()
|
||||||
const {isMobile, isTabletOrMobile} = useWebMediaQueries()
|
const {isMobile, isTabletOrMobile} = useWebMediaQueries()
|
||||||
if ((!PWI_ENABLED || activeRouteRequiresAuth) && !hasSession) {
|
const isNativePWIDisabled = isNative && gate('native_pwi_disabled')
|
||||||
|
if (
|
||||||
|
(!PWI_ENABLED || isNativePWIDisabled || activeRouteRequiresAuth) &&
|
||||||
|
!hasSession
|
||||||
|
) {
|
||||||
return <LoggedOut />
|
return <LoggedOut />
|
||||||
}
|
}
|
||||||
if (hasSession && currentAccount?.signupQueued) {
|
if (hasSession && currentAccount?.signupQueued) {
|
||||||
|
|
Loading…
Reference in New Issue