diff --git a/ios/patching/008-social-app-ios-policy-tos-error.patch b/ios/patching/008-social-app-ios-policy-tos-error.patch index 83015ec..9fa76b9 100644 --- a/ios/patching/008-social-app-ios-policy-tos-error.patch +++ b/ios/patching/008-social-app-ios-policy-tos-error.patch @@ -1,8 +1,8 @@ diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx -index a89eaadc4..1da393f03 100644 +index a89eaadc4..787a1409b 100644 --- a/src/view/screens/PrivacyPolicy.tsx +++ b/src/view/screens/PrivacyPolicy.tsx -@@ -1,52 +1,13 @@ +@@ -1,51 +1,28 @@ import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' @@ -19,7 +19,7 @@ index a89eaadc4..1da393f03 100644 -import {TextLink} from '#/view/com/util/Link' -import {Text} from '#/view/com/util/text/Text' -import {ScrollView} from '#/view/com/util/Views' -+import { WebView } from 'react-native-webview' ++import { ScrollView } from 'react-native' import * as Layout from '#/components/Layout' -import {ViewHeader} from '../com/util/ViewHeader' - @@ -28,16 +28,19 @@ index a89eaadc4..1da393f03 100644 - const pal = usePalette('default') - const {_} = useLingui() - const setMinimalShellMode = useSetMinimalShellMode() -- ++import { useSetTitle } from '#/lib/hooks/useSetTitle' ++import { atoms as a, useTheme } from '#/alf' ++import { Text } from '#/components/Typography' + - useFocusEffect( - React.useCallback(() => { - setMinimalShellMode(false) - }, [setMinimalShellMode]), - ) -+import {useSetTitle} from '#/lib/hooks/useSetTitle' - +export function PrivacyPolicyScreen() { + useSetTitle('Privacy Policy') ++ const t = useTheme() + return ( - @@ -55,16 +58,26 @@ index a89eaadc4..1da393f03 100644 - - - -- -+ ++ ++ Privacy Policy ++ ++ ++ Please refer to the following page for the Privacy Policy. ++ ++ ++ ++ https://syu.is/about/support/privacy-policy ++ + ) - } diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx -index d843c713c..b81767bd5 100644 +index d843c713c..28333cc5b 100644 --- a/src/view/screens/TermsOfService.tsx +++ b/src/view/screens/TermsOfService.tsx -@@ -1,50 +1,13 @@ +@@ -1,49 +1,28 @@ import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' @@ -81,7 +94,7 @@ index d843c713c..b81767bd5 100644 -import {TextLink} from '#/view/com/util/Link' -import {Text} from '#/view/com/util/text/Text' -import {ScrollView} from '#/view/com/util/Views' -+import { WebView } from 'react-native-webview' ++import { ScrollView } from 'react-native' import * as Layout from '#/components/Layout' -import {ViewHeader} from '../com/util/ViewHeader' - @@ -90,16 +103,19 @@ index d843c713c..b81767bd5 100644 - const pal = usePalette('default') - const setMinimalShellMode = useSetMinimalShellMode() - const {_} = useLingui() -- ++import { useSetTitle } from '#/lib/hooks/useSetTitle' ++import { atoms as a, useTheme } from '#/alf' ++import { Text } from '#/components/Typography' + - useFocusEffect( - React.useCallback(() => { - setMinimalShellMode(false) - }, [setMinimalShellMode]), - ) -+import {useSetTitle} from '#/lib/hooks/useSetTitle' - +export function TermsOfServiceScreen() { + useSetTitle('Terms of Service') ++ const t = useTheme() + return ( - @@ -115,8 +131,18 @@ index d843c713c..b81767bd5 100644 - - - -- -+ ++ ++ Terms of Service ++ ++ ++ Please refer to the following page for the Terms of Service. ++ ++ ++ ++ https://syu.is/about/support/tos ++ + ) - } diff --git a/ios/patching/021-social-app-ios-clean-feed.patch b/ios/patching/021-social-app-ios-clean-feed.patch index b1be019..a288fbf 100644 --- a/ios/patching/021-social-app-ios-clean-feed.patch +++ b/ios/patching/021-social-app-ios-clean-feed.patch @@ -1,21 +1,554 @@ -diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx -index e058e2883..e762b1418 100644 ---- a/src/view/screens/Home.tsx -+++ b/src/view/screens/Home.tsx -@@ -39,6 +39,16 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned' - import * as Layout from '#/components/Layout' - import {useDemoMode} from '#/storage/hooks/demo-mode' +diff --git a/src/view/com/posts/FollowingEmptyState.tsx b/src/view/com/posts/FollowingEmptyState.tsx +index 352cc1dc0..a1bae1b05 100644 +--- a/src/view/com/posts/FollowingEmptyState.tsx ++++ b/src/view/com/posts/FollowingEmptyState.tsx +@@ -1,19 +1,19 @@ + import React from 'react' +-import {StyleSheet, View} from 'react-native' ++import { StyleSheet, View } from 'react-native' + import { + FontAwesomeIcon, + type FontAwesomeIconStyle, + } from '@fortawesome/react-native-fontawesome' +-import {Trans} from '@lingui/macro' +-import {useNavigation} from '@react-navigation/native' ++import { Trans } from '@lingui/macro' ++import { useNavigation } from '@react-navigation/native' -+const DEFAULT_PINNED_FEEDS = [{ -+ feedDescriptor: 'following', -+ displayName: 'Following', -+ id: 'following', -+ type: 'feed', -+ savedFeed: undefined, -+ pinned: true, -+}] +-import {usePalette} from '#/lib/hooks/usePalette' +-import {MagnifyingGlassIcon} from '#/lib/icons' +-import {type NavigationProp} from '#/lib/routes/types' +-import {s} from '#/lib/styles' +-import {isWeb} from '#/platform/detection' +-import {Button} from '../util/forms/Button' +-import {Text} from '../util/text/Text' ++import { usePalette } from '#/lib/hooks/usePalette' ++import { MagnifyingGlassIcon } from '#/lib/icons' ++import { type NavigationProp } from '#/lib/routes/types' ++import { s } from '#/lib/styles' ++import { isWeb } from '#/platform/detection' ++import { Button } from '../util/forms/Button' ++import { Text } from '../util/text/Text' + + export function FollowingEmptyState() { + const pal = usePalette('default') +@@ -45,36 +45,6 @@ export function FollowingEmptyState() { + happening. + + +- +- +- +- You can also discover new Custom Feeds to follow. +- +- + + + ) +diff --git a/src/view/com/posts/FollowingEndOfFeed.tsx b/src/view/com/posts/FollowingEndOfFeed.tsx +index e3c84d782..362ff1ed2 100644 +--- a/src/view/com/posts/FollowingEndOfFeed.tsx ++++ b/src/view/com/posts/FollowingEndOfFeed.tsx +@@ -1,18 +1,18 @@ + import React from 'react' +-import {Dimensions, StyleSheet, View} from 'react-native' ++import { Dimensions, StyleSheet, View } from 'react-native' + import { + FontAwesomeIcon, + type FontAwesomeIconStyle, + } from '@fortawesome/react-native-fontawesome' +-import {Trans} from '@lingui/macro' +-import {useNavigation} from '@react-navigation/native' ++import { Trans } from '@lingui/macro' ++import { useNavigation } from '@react-navigation/native' + +-import {usePalette} from '#/lib/hooks/usePalette' +-import {type NavigationProp} from '#/lib/routes/types' +-import {s} from '#/lib/styles' +-import {isWeb} from '#/platform/detection' +-import {Button} from '../util/forms/Button' +-import {Text} from '../util/text/Text' ++import { usePalette } from '#/lib/hooks/usePalette' ++import { type NavigationProp } from '#/lib/routes/types' ++import { s } from '#/lib/styles' ++import { isWeb } from '#/platform/detection' ++import { Button } from '../util/forms/Button' ++import { Text } from '../util/text/Text' + + export function FollowingEndOfFeed() { + const pal = usePalette('default') +@@ -37,45 +37,14 @@ export function FollowingEndOfFeed() { + style={[ + styles.container, + pal.border, +- {minHeight: Dimensions.get('window').height * 0.75}, ++ { minHeight: Dimensions.get('window').height * 0.75 }, + ]}> + + + +- You've reached the end of your feed! Find some more accounts to +- follow. ++ You've reached the end of your feed! + + +- +- +- +- You can also discover new Custom Feeds to follow. +- +- + + + ) +diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx +index 4f25468c9..2699a0844 100644 +--- a/src/view/com/posts/PostFeed.tsx ++++ b/src/view/com/posts/PostFeed.tsx +@@ -23,23 +23,23 @@ import { + AppBskyEmbedVideo, + type AppBskyFeedDefs, + } from '@atproto/api' +-import {msg} from '@lingui/macro' +-import {useLingui} from '@lingui/react' +-import {useQueryClient} from '@tanstack/react-query' ++import { msg } from '@lingui/macro' ++import { useLingui } from '@lingui/react' ++import { useQueryClient } from '@tanstack/react-query' + +-import {isStatusStillActive, validateStatus} from '#/lib/actor-status' +-import {DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS} from '#/lib/constants' +-import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' +-import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' +-import {logEvent, useGate} from '#/lib/statsig/statsig' +-import {isNetworkError} from '#/lib/strings/errors' +-import {logger} from '#/logger' +-import {isIOS, isNative, isWeb} from '#/platform/detection' +-import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow' +-import {listenPostCreated} from '#/state/events' +-import {useFeedFeedbackContext} from '#/state/feed-feedback' +-import {useTrendingSettings} from '#/state/preferences/trending' +-import {STALE} from '#/state/queries' ++import { isStatusStillActive, validateStatus } from '#/lib/actor-status' ++import { DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS } from '#/lib/constants' ++import { useInitialNumToRender } from '#/lib/hooks/useInitialNumToRender' ++import { useNonReactiveCallback } from '#/lib/hooks/useNonReactiveCallback' ++import { logEvent, useGate } from '#/lib/statsig/statsig' ++import { isNetworkError } from '#/lib/strings/errors' ++import { logger } from '#/logger' ++import { isIOS, isNative, isWeb } from '#/platform/detection' ++import { usePostAuthorShadowFilter } from '#/state/cache/profile-shadow' ++import { listenPostCreated } from '#/state/events' ++import { useFeedFeedbackContext } from '#/state/feed-feedback' ++import { useTrendingSettings } from '#/state/preferences/trending' ++import { STALE } from '#/state/queries' + import { + type AuthorFilter, + type FeedDescriptor, +@@ -50,111 +50,111 @@ import { + RQKEY, + usePostFeedQuery, + } from '#/state/queries/post-feed' +-import {useLiveNowConfig} from '#/state/service-config' +-import {useSession} from '#/state/session' +-import {useProgressGuide} from '#/state/shell/progress-guide' +-import {useSelectedFeed} from '#/state/shell/selected-feed' +-import {List, type ListRef} from '#/view/com/util/List' +-import {PostFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' +-import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn' +-import {type VideoFeedSourceContext} from '#/screens/VideoFeed/types' +-import {useBreakpoints, useLayoutBreakpoints} from '#/alf' ++import { useLiveNowConfig } from '#/state/service-config' ++import { useSession } from '#/state/session' ++import { useProgressGuide } from '#/state/shell/progress-guide' ++import { useSelectedFeed } from '#/state/shell/selected-feed' ++import { List, type ListRef } from '#/view/com/util/List' ++import { PostFeedLoadingPlaceholder } from '#/view/com/util/LoadingPlaceholder' ++import { LoadMoreRetryBtn } from '#/view/com/util/LoadMoreRetryBtn' ++import { type VideoFeedSourceContext } from '#/screens/VideoFeed/types' ++import { useBreakpoints, useLayoutBreakpoints } from '#/alf' + import { + AgeAssuranceDismissibleFeedBanner, + useInternalState as useAgeAssuranceBannerState, + } from '#/components/ageAssurance/AgeAssuranceDismissibleFeedBanner' +-import {ProgressGuide, SuggestedFollows} from '#/components/FeedInterstitials' ++import { ProgressGuide, SuggestedFollows } from '#/components/FeedInterstitials' + import { + PostFeedVideoGridRow, + PostFeedVideoGridRowPlaceholder, + } from '#/components/feeds/PostFeedVideoGridRow' +-import {TrendingInterstitial} from '#/components/interstitials/Trending' +-import {TrendingVideos as TrendingVideosInterstitial} from '#/components/interstitials/TrendingVideos' +-import {ComposerPrompt} from '../feeds/ComposerPrompt' +-import {DiscoverFallbackHeader} from './DiscoverFallbackHeader' +-import {FeedShutdownMsg} from './FeedShutdownMsg' +-import {PostFeedErrorMessage} from './PostFeedErrorMessage' +-import {PostFeedItem} from './PostFeedItem' +-import {ShowLessFollowup} from './ShowLessFollowup' +-import {ViewFullThread} from './ViewFullThread' ++import { TrendingInterstitial } from '#/components/interstitials/Trending' ++import { TrendingVideos as TrendingVideosInterstitial } from '#/components/interstitials/TrendingVideos' ++import { ComposerPrompt } from '../feeds/ComposerPrompt' ++import { DiscoverFallbackHeader } from './DiscoverFallbackHeader' ++import { FeedShutdownMsg } from './FeedShutdownMsg' ++import { PostFeedErrorMessage } from './PostFeedErrorMessage' ++import { PostFeedItem } from './PostFeedItem' ++import { ShowLessFollowup } from './ShowLessFollowup' ++import { ViewFullThread } from './ViewFullThread' + + type FeedRow = + | { +- type: 'loading' +- key: string +- } ++ type: 'loading' ++ key: string ++ } + | { +- type: 'empty' +- key: string +- } ++ type: 'empty' ++ key: string ++ } + | { +- type: 'error' +- key: string +- } ++ type: 'error' ++ key: string ++ } + | { +- type: 'loadMoreError' +- key: string +- } ++ type: 'loadMoreError' ++ key: string ++ } + | { +- type: 'feedShutdownMsg' +- key: string +- } ++ type: 'feedShutdownMsg' ++ key: string ++ } + | { +- type: 'fallbackMarker' +- key: string +- } ++ type: 'fallbackMarker' ++ key: string ++ } + | { +- type: 'sliceItem' +- key: string +- slice: FeedPostSlice +- indexInSlice: number +- showReplyTo: boolean +- } ++ type: 'sliceItem' ++ key: string ++ slice: FeedPostSlice ++ indexInSlice: number ++ showReplyTo: boolean ++ } + | { +- type: 'videoGridRowPlaceholder' +- key: string +- } ++ type: 'videoGridRowPlaceholder' ++ key: string ++ } + | { +- type: 'videoGridRow' +- key: string +- items: FeedPostSliceItem[] +- sourceFeedUri: string +- feedContexts: (string | undefined)[] +- reqIds: (string | undefined)[] +- } ++ type: 'videoGridRow' ++ key: string ++ items: FeedPostSliceItem[] ++ sourceFeedUri: string ++ feedContexts: (string | undefined)[] ++ reqIds: (string | undefined)[] ++ } + | { +- type: 'sliceViewFullThread' +- key: string +- uri: string +- } ++ type: 'sliceViewFullThread' ++ key: string ++ uri: string ++ } + | { +- type: 'interstitialFollows' +- key: string +- } ++ type: 'interstitialFollows' ++ key: string ++ } + | { +- type: 'interstitialProgressGuide' +- key: string +- } ++ type: 'interstitialProgressGuide' ++ key: string ++ } + | { +- type: 'interstitialTrending' +- key: string +- } ++ type: 'interstitialTrending' ++ key: string ++ } + | { +- type: 'interstitialTrendingVideos' +- key: string +- } ++ type: 'interstitialTrendingVideos' ++ key: string ++ } + | { +- type: 'showLessFollowup' +- key: string +- } ++ type: 'showLessFollowup' ++ key: string ++ } + | { +- type: 'ageAssuranceBanner' +- key: string +- } ++ type: 'ageAssuranceBanner' ++ key: string ++ } + | { +- type: 'composerPrompt' +- key: string +- } ++ type: 'composerPrompt' ++ key: string ++ } + + export function getItemsForFeedback(feedRow: FeedRow): { + item: FeedPostSliceItem +@@ -227,17 +227,17 @@ let PostFeed = ({ + initialNumToRender?: number + isVideoFeed?: boolean + }): React.ReactNode => { +- const {_} = useLingui() ++ const { _ } = useLingui() + const queryClient = useQueryClient() +- const {currentAccount, hasSession} = useSession() ++ const { currentAccount, hasSession } = useSession() + const gate = useGate() + const initialNumToRender = useInitialNumToRender() + const feedFeedback = useFeedFeedbackContext() + const [isPTRing, setIsPTRing] = useState(false) + const lastFetchRef = useRef(Date.now()) + const [feedType, feedUriOrActorDid, feedTab] = feed.split('|') +- const {gtMobile} = useBreakpoints() +- const {rightNavVisible} = useLayoutBreakpoints() ++ const { gtMobile } = useBreakpoints() ++ const { rightNavVisible } = useLayoutBreakpoints() + const areVideoFeedsEnabled = isNative + + const [hasPressedShowLessUris, setHasPressedShowLessUris] = useState( +@@ -256,7 +256,7 @@ let PostFeed = ({ + + const feedCacheKey = feedParams?.feedCacheKey + const opts = useMemo( +- () => ({enabled, ignoreFilterFor}), ++ () => ({ enabled, ignoreFilterFor }), + [enabled, ignoreFilterFor], + ) + const { +@@ -299,7 +299,7 @@ let PostFeed = ({ + } + } catch (e) { + if (!isNetworkError(e)) { +- logger.error('Poll latest failed', {feed, message: String(e)}) ++ logger.error('Poll latest failed', { feed, message: String(e) }) + } + } + }) +@@ -315,7 +315,7 @@ let PostFeed = ({ + (feed === 'following' || + feed === `author|${myDid}|posts_and_author_threads`) + ) { +- queryClient.invalidateQueries({queryKey: RQKEY(feed)}) ++ queryClient.invalidateQueries({ queryKey: RQKEY(feed) }) + } + }, [queryClient, feed, data, myDid]) + useEffect(() => { +@@ -360,7 +360,7 @@ let PostFeed = ({ + const showProgressIntersitial = + (followProgressGuide || followAndLikeProgressGuide) && !rightNavVisible + +- const {trendingDisabled, trendingVideoDisabled} = useTrendingSettings() ++ const { trendingDisabled, trendingVideoDisabled } = useTrendingSettings() + + const ageAssuranceBannerState = useAgeAssuranceBannerState() + const selectedFeed = useSelectedFeed() +@@ -378,7 +378,7 @@ let PostFeed = ({ + const feedItems: FeedRow[] = useMemo(() => { + // wraps a slice item, and replaces it with a showLessFollowup item + // if the user has pressed show less on it +- const sliceItem = (row: Extract) => { ++ const sliceItem = (row: Extract) => { + if (hasPressedShowLessUris.has(row.slice.items[row.indexInSlice]?.uri)) { + return { + type: 'showLessFollowup', +@@ -543,16 +543,8 @@ let PostFeed = ({ + }) + } + } else if (feedKind === 'following') { +- if (sliceIndex === 0) { +- // Show composer prompt for Following feed +- if (hasSession && gate('show_composer_prompt')) { +- arr.push({ +- type: 'composerPrompt', +- key: 'composerPrompt-' + sliceIndex, +- }) +- } +- } +- } else if (feedKind === 'profile') { ++ } else if (feedKind === 'following') { + -+ - type Props = NativeStackScreenProps - export function HomeScreen(props: Props) { - const {setShowLoggedOut} = useLoggedOutViewControls() + if (sliceIndex === 5) { + arr.push({ + type: 'interstitialFollows', +@@ -699,7 +691,7 @@ let PostFeed = ({ + await refetch() + onHasNew?.(false) + } catch (err) { +- logger.error('Failed to refresh posts feed', {message: err}) ++ logger.error('Failed to refresh posts feed', { message: err }) + } + setIsPTRing(false) + }, [refetch, setIsPTRing, onHasNew, feed, feedType]) +@@ -715,7 +707,7 @@ let PostFeed = ({ + try { + await fetchNextPage() + } catch (err) { +- logger.error('Failed to load more posts', {message: err}) ++ logger.error('Failed to load more posts', { message: err }) + } + }, [ + isFetching, +@@ -740,7 +732,7 @@ let PostFeed = ({ + // = + + const renderItem = useCallback( +- ({item: row, index: rowIndex}: ListRenderItemInfo) => { ++ ({ item: row, index: rowIndex }: ListRenderItemInfo) => { + if (row.type === 'empty') { + return renderEmptyState() + } else if (row.type === 'error') { +@@ -877,12 +869,12 @@ let PostFeed = ({ + return isFetchingNextPage ? ( + + +- ++ + + ) : shouldRenderEndOfFeed ? ( +- {renderEndOfFeed()} ++ {renderEndOfFeed()} + ) : ( +- ++ + ) + }, [isFetchingNextPage, shouldRenderEndOfFeed, renderEndOfFeed, headerOffset]) + +@@ -944,7 +936,7 @@ let PostFeed = ({ + feedDescriptor: feedFeedback.feedDescriptor || feed, + position, + }, +- {statsig: false}, ++ { statsig: false }, + ) + } + +@@ -963,7 +955,7 @@ let PostFeed = ({ + subject: actor.did, + feed, + }, +- {statsig: false}, ++ { statsig: false }, + ) + } + } +@@ -987,7 +979,7 @@ let PostFeed = ({ + feedDescriptor: feedFeedback.feedDescriptor || feed, + position, + }, +- {statsig: false}, ++ { statsig: false }, + ) + } + } +@@ -1031,10 +1023,10 @@ let PostFeed = ({ + ) + } + PostFeed = memo(PostFeed) +-export {PostFeed} ++export { PostFeed } + + const styles = StyleSheet.create({ +- feedFooter: {paddingTop: 20}, ++ feedFooter: { paddingTop: 20 }, + }) + + export function isThreadParentAt(arr: Array, i: number) {