From 6b4656b43df4879cf4630bd319159752786e5678 Mon Sep 17 00:00:00 2001 From: syui Date: Sun, 7 Dec 2025 18:41:05 +0900 Subject: [PATCH] test gemini --- .../008-social-app-ios-policy-tos-error.patch | 318 ------- ios/patching/009-social-app-ios-license.patch | 822 ++++-------------- ...2-social-app-ios-settings-about-help.patch | 130 ++- ...-social-app-ios-bypass-age-assurance.patch | 96 +- .../021-social-app-ios-clean-feed.patch | 155 ++++ ios/setup.zsh | 1 + 6 files changed, 491 insertions(+), 1031 deletions(-) create mode 100644 ios/patching/021-social-app-ios-clean-feed.patch 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 c0a98cf..e69de29 100644 --- a/ios/patching/008-social-app-ios-policy-tos-error.patch +++ b/ios/patching/008-social-app-ios-policy-tos-error.patch @@ -1,318 +0,0 @@ -diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx -index 4f25468c9..95b183dcc 100644 ---- a/src/view/com/posts/PostFeed.tsx -+++ b/src/view/com/posts/PostFeed.tsx -@@ -298,8 +298,13 @@ let PostFeed = ({ - } - } - } catch (e) { -+ const errorMsg = String(e) -+ // Skip errors for missing repos (deleted accounts) -+ if (errorMsg.includes('Could not find repo')) { -+ return -+ } - if (!isNetworkError(e)) { -- logger.error('Poll latest failed', {feed, message: String(e)}) -+ logger.error('Poll latest failed', {feed, message: errorMsg}) - } - } - }) -diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx -index a89eaadc4..c3a8b6114 100644 ---- a/src/view/screens/PrivacyPolicy.tsx -+++ b/src/view/screens/PrivacyPolicy.tsx -@@ -1,51 +1,95 @@ - import React from 'react' --import {View} from 'react-native' --import {msg, Trans} from '@lingui/macro' --import {useLingui} from '@lingui/react' --import {useFocusEffect} from '@react-navigation/native' -- --import {usePalette} from '#/lib/hooks/usePalette' --import { -- type CommonNavigatorParams, -- type NativeStackScreenProps, --} from '#/lib/routes/types' --import {s} from '#/lib/styles' --import {useSetMinimalShellMode} from '#/state/shell' --import {TextLink} from '#/view/com/util/Link' --import {Text} from '#/view/com/util/text/Text' --import {ScrollView} from '#/view/com/util/Views' -+import { ScrollView } from 'react-native' - import * as Layout from '#/components/Layout' --import {ViewHeader} from '../com/util/ViewHeader' -- --type Props = NativeStackScreenProps --export const PrivacyPolicyScreen = (_props: Props) => { -- const pal = usePalette('default') -- const {_} = useLingui() -- const setMinimalShellMode = useSetMinimalShellMode() -- -- useFocusEffect( -- React.useCallback(() => { -- setMinimalShellMode(false) -- }, [setMinimalShellMode]), -- ) -+import {useSetTitle} from '#/lib/hooks/useSetTitle' -+import {atoms as a, useTheme} from '#/alf' -+import {Text} from '#/components/Typography' -+ -+export function PrivacyPolicyScreen() { -+ useSetTitle('Privacy Policy') -+ const t = useTheme() - - return ( - -- -- -- -- -- -- The Privacy Policy has been moved to{' '} -- -- -- -- -- -+ -+ Privacy Policy -+ -+ -+ This application (hereinafter referred to as "the App") respects user privacy and is committed to protecting personal information. -+ -+ -+ 1. Information We Collect -+ -+ The App is a decentralized social network using the AT Protocol. -+ Information posted by users is stored on the selected server (PDS). -+ -+ -+ 2. Use of Information -+ -+ The collected information is used for the following purposes: -+ {'\n'}- Providing and operating the service -+ {'\n'}- User support -+ {'\n'}- Service improvement -+ -+ -+ 3. Third-Party Disclosure -+ -+ The App will not provide users' personal information to third parties without user consent, except as required by law. -+ -+ -+ 4. Security -+ -+ The App takes appropriate security measures to protect personal information. -+ -+ -+ 5. Contact -+ -+ For questions regarding this Privacy Policy, please contact us through the support link in the settings screen. -+ -+ -+ 日本語訳(参考) -+ -+ プライバシーポリシー -+ -+ -+ 本アプリケーション(以下「本アプリ」)は、ユーザーのプライバシーを尊重し、個人情報の保護に努めます。 -+ -+ -+ 1. 収集する情報 -+ -+ 本アプリは、ATプロトコルを使用した分散型ソーシャルネットワークです。 -+ ユーザーが投稿した情報は、選択したサーバー(PDS)に保存されます。 -+ -+ -+ 2. 情報の利用目的 -+ -+ 収集した情報は、以下の目的で利用されます: -+ {'\n'}- サービスの提供・運営 -+ {'\n'}- ユーザーサポート -+ {'\n'}- サービスの改善 -+ -+ -+ 3. 情報の第三者提供 -+ -+ 本アプリは、ユーザーの個人情報を、法令に基づく場合を除き、 -+ ユーザーの同意なく第三者に提供することはありません。 -+ -+ -+ 4. セキュリティ -+ -+ 本アプリは、個人情報の保護のため、適切な安全対策を講じます。 -+ -+ -+ 5. お問い合わせ -+ -+ プライバシーポリシーに関するご質問は、設定画面のサポートリンクからお問い合わせください。 -+ -+ -+ -+ Last Updated: December 7, 2025 -+ - - - ) -diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx -index d843c713c..3d2323f73 100644 ---- a/src/view/screens/TermsOfService.tsx -+++ b/src/view/screens/TermsOfService.tsx -@@ -1,49 +1,110 @@ - import React from 'react' --import {View} from 'react-native' --import {msg, Trans} from '@lingui/macro' --import {useLingui} from '@lingui/react' --import {useFocusEffect} from '@react-navigation/native' -- --import {usePalette} from '#/lib/hooks/usePalette' --import { -- type CommonNavigatorParams, -- type NativeStackScreenProps, --} from '#/lib/routes/types' --import {s} from '#/lib/styles' --import {useSetMinimalShellMode} from '#/state/shell' --import {TextLink} from '#/view/com/util/Link' --import {Text} from '#/view/com/util/text/Text' --import {ScrollView} from '#/view/com/util/Views' -+import { ScrollView } from 'react-native' - import * as Layout from '#/components/Layout' --import {ViewHeader} from '../com/util/ViewHeader' -- --type Props = NativeStackScreenProps --export const TermsOfServiceScreen = (_props: Props) => { -- const pal = usePalette('default') -- const setMinimalShellMode = useSetMinimalShellMode() -- const {_} = useLingui() -- -- useFocusEffect( -- React.useCallback(() => { -- setMinimalShellMode(false) -- }, [setMinimalShellMode]), -- ) -+import {useSetTitle} from '#/lib/hooks/useSetTitle' -+import {atoms as a, useTheme} from '#/alf' -+import {Text} from '#/components/Typography' -+ -+export function TermsOfServiceScreen() { -+ useSetTitle('Terms of Service') -+ const t = useTheme() - - return ( - -- -- -- -- -- The Terms of Service have been moved to{' '} -- -- -- -- -+ -+ Terms of Service -+ -+ -+ These Terms of Service (hereinafter referred to as "these Terms") set forth the conditions for using this application (hereinafter referred to as "the App"). -+ -+ -+ Article 1 (Application) -+ -+ These Terms shall apply to all relationships between users and the provider of the App regarding the use of the App. -+ -+ -+ Article 2 (User Registration) -+ -+ Use of the App requires an AT Protocol-compatible account. -+ Registration information must be kept accurate and up-to-date. -+ -+ -+ Article 3 (Prohibited Acts) -+ -+ Users shall not engage in the following acts when using the App: -+ {'\n'}- Acts that violate laws or public order and morals -+ {'\n'}- Acts related to criminal activity -+ {'\n'}- Acts that infringe upon the rights of other users or third parties -+ {'\n'}- Acts that interfere with the operation of the App -+ {'\n'}- Unauthorized access or attempts thereof -+ -+ -+ Article 4 (Disclaimer) -+ -+ The App is a decentralized service using the AT Protocol. -+ The provider makes no warranties, express or implied, regarding the App. -+ -+ -+ Article 5 (Changes to Terms) -+ -+ The provider may change these Terms without obtaining user consent when deemed necessary. -+ -+ -+ Article 6 (Contact) -+ -+ For questions regarding these Terms, please contact us through the support link in the settings screen. -+ -+ -+ 日本語訳(参考) -+ -+ 利用規約 -+ -+ -+ 本利用規約(以下「本規約」)は、本アプリケーション(以下「本アプリ」)の利用条件を定めるものです。 -+ -+ -+ 第1条(適用) -+ -+ 本規約は、ユーザーと本アプリの提供者との間の本アプリの利用に関わる一切の関係に適用されます。 -+ -+ -+ 第2条(利用登録) -+ -+ 本アプリの利用にあたっては、ATプロトコル対応のアカウントが必要です。 -+ 登録情報は正確かつ最新の状態に保つ必要があります。 -+ -+ -+ 第3条(禁止事項) -+ -+ ユーザーは、本アプリの利用にあたり、以下の行為をしてはなりません: -+ {'\n'}- 法令または公序良俗に違反する行為 -+ {'\n'}- 犯罪行為に関連する行為 -+ {'\n'}- 他のユーザーまたは第三者の権利を侵害する行為 -+ {'\n'}- 本アプリの運営を妨害する行為 -+ {'\n'}- 不正アクセスまたはこれを試みる行為 -+ -+ -+ 第4条(免責事項) -+ -+ 本アプリは、ATプロトコルを使用した分散型サービスです。 -+ 提供者は、本アプリに関して、明示的・黙示的を問わず、いかなる保証も行いません。 -+ -+ -+ 第5条(規約の変更) -+ -+ 提供者は、必要と判断した場合、ユーザーの承諾を得ることなく本規約を変更できるものとします。 -+ -+ -+ 第6条(お問い合わせ) -+ -+ 本規約に関するご質問は、設定画面のサポートリンクからお問い合わせください。 -+ -+ -+ -+ Last Updated: December 7, 2025 -+ - - - ) diff --git a/ios/patching/009-social-app-ios-license.patch b/ios/patching/009-social-app-ios-license.patch index bac8a82..6be1df3 100644 --- a/ios/patching/009-social-app-ios-license.patch +++ b/ios/patching/009-social-app-ios-license.patch @@ -1,681 +1,177 @@ -diff --git a/src/Navigation.tsx b/src/Navigation.tsx -index fa33a9d56..13af087c2 100644 ---- a/src/Navigation.tsx -+++ b/src/Navigation.tsx -@@ -62,6 +62,7 @@ import {NotFoundScreen} from '#/view/screens/NotFound' - import {NotificationsScreen} from '#/view/screens/Notifications' - import {PostThreadScreen} from '#/view/screens/PostThread' - import {PrivacyPolicyScreen} from '#/view/screens/PrivacyPolicy' -+import {LicenseScreen} from '#/view/screens/License' - import {ProfileScreen} from '#/view/screens/Profile' - import {ProfileFeedLikedByScreen} from '#/view/screens/ProfileFeedLikedBy' - import {Storybook} from '#/view/screens/Storybook' -@@ -335,6 +336,11 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) { - getComponent={() => TermsOfServiceScreen} - options={{title: title(msg`Terms of Service`)}} - /> -+ LicenseScreen} -+ options={{title: title(msg`License`)}} -+ /> - CommunityGuidelinesScreen} diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts -index c315a8341..9b2f50a83 100644 +index c315a8341..6d97a6928 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts -@@ -39,6 +39,7 @@ export type CommonNavigatorParams = { - Support: undefined - PrivacyPolicy: undefined +@@ -1,9 +1,9 @@ +-import {type NavigationState, type PartialState} from '@react-navigation/native' +-import {type NativeStackNavigationProp} from '@react-navigation/native-stack' ++import { type NavigationState, type PartialState } from '@react-navigation/native' ++import { type NativeStackNavigationProp } from '@react-navigation/native-stack' + +-import {type VideoFeedSourceContext} from '#/screens/VideoFeed/types' ++import { type VideoFeedSourceContext } from '#/screens/VideoFeed/types' + +-export type {NativeStackScreenProps} from '@react-navigation/native-stack' ++export type { NativeStackScreenProps } from '@react-navigation/native-stack' + + export type CommonNavigatorParams = { + NotFound: undefined +@@ -15,23 +15,23 @@ export type CommonNavigatorParams = { + ModerationInteractionSettings: undefined + ModerationVerificationSettings: undefined + Settings: undefined +- Profile: {name: string; hideBackButton?: boolean} +- ProfileFollowers: {name: string} +- ProfileFollows: {name: string} +- ProfileKnownFollowers: {name: string} +- ProfileSearch: {name: string; q?: string} +- ProfileList: {name: string; rkey: string} +- PostThread: {name: string; rkey: string} +- PostLikedBy: {name: string; rkey: string} +- PostRepostedBy: {name: string; rkey: string} +- PostQuotes: {name: string; rkey: string} ++ Profile: { name: string; hideBackButton?: boolean } ++ ProfileFollowers: { name: string } ++ ProfileFollows: { name: string } ++ ProfileKnownFollowers: { name: string } ++ ProfileSearch: { name: string; q?: string } ++ ProfileList: { name: string; rkey: string } ++ PostThread: { name: string; rkey: string } ++ PostLikedBy: { name: string; rkey: string } ++ PostRepostedBy: { name: string; rkey: string } ++ PostQuotes: { name: string; rkey: string } + ProfileFeed: { + name: string + rkey: string + feedCacheKey?: 'discover' | 'explore' | undefined + } +- ProfileFeedLikedBy: {name: string; rkey: string} +- ProfileLabelerLikedBy: {name: string} ++ ProfileFeedLikedBy: { name: string; rkey: string } ++ ProfileLabelerLikedBy: { name: string } + Debug: undefined + DebugMod: undefined + SharedPreferencesTester: undefined +@@ -41,6 +41,7 @@ export type CommonNavigatorParams = { TermsOfService: undefined -+ License: undefined CommunityGuidelines: undefined CopyrightPolicy: undefined ++ License: undefined LanguageSettings: undefined + AppPasswords: undefined + SavedFeeds: undefined +@@ -67,24 +68,24 @@ export type CommonNavigatorParams = { + InterestsSettings: undefined + AboutSettings: undefined + AppIconSettings: undefined +- Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} +- Hashtag: {tag: string; author?: string} +- Topic: {topic: string} +- MessagesConversation: {conversation: string; embed?: string; accept?: true} ++ Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } ++ Hashtag: { tag: string; author?: string } ++ Topic: { topic: string } ++ MessagesConversation: { conversation: string; embed?: string; accept?: true } + MessagesSettings: undefined + MessagesInbox: undefined +- NotificationsActivityList: {posts: string} ++ NotificationsActivityList: { posts: string } + LegacyNotificationSettings: undefined + Feeds: undefined +- Start: {name: string; rkey: string} +- StarterPack: {name: string; rkey: string; new?: boolean} +- StarterPackShort: {code: string} ++ Start: { name: string; rkey: string } ++ StarterPack: { name: string; rkey: string; new?: boolean } ++ StarterPackShort: { code: string } + StarterPackWizard: { + fromDialog?: boolean + targetDid?: string + onSuccess?: () => void + } +- StarterPackEdit: {rkey?: string} ++ StarterPackEdit: { rkey?: string } + VideoFeed: VideoFeedSourceContext + Bookmarks: undefined + } +@@ -102,7 +103,7 @@ export type HomeTabNavigatorParams = CommonNavigatorParams & { + } + + export type SearchTabNavigatorParams = CommonNavigatorParams & { +- Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} ++ Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } + } + + export type NotificationsTabNavigatorParams = CommonNavigatorParams & { +@@ -110,32 +111,32 @@ export type NotificationsTabNavigatorParams = CommonNavigatorParams & { + } + + export type MyProfileTabNavigatorParams = CommonNavigatorParams & { +- MyProfile: {name: 'me'; hideBackButton: true} ++ MyProfile: { name: 'me'; hideBackButton: true } + } + + export type MessagesTabNavigatorParams = CommonNavigatorParams & { +- Messages: {pushToConversation?: string; animation?: 'push' | 'pop'} ++ Messages: { pushToConversation?: string; animation?: 'push' | 'pop' } + } + + export type FlatNavigatorParams = CommonNavigatorParams & { + Home: undefined +- Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} ++ Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } + Feeds: undefined + Notifications: undefined +- Messages: {pushToConversation?: string; animation?: 'push' | 'pop'} ++ Messages: { pushToConversation?: string; animation?: 'push' | 'pop' } + } + + export type AllNavigatorParams = CommonNavigatorParams & { + HomeTab: undefined + Home: undefined + SearchTab: undefined +- Search: {q?: string; tab?: 'user' | 'profile' | 'feed'} ++ Search: { q?: string; tab?: 'user' | 'profile' | 'feed' } + Feeds: undefined + NotificationsTab: undefined + Notifications: undefined + MyProfileTab: undefined + MessagesTab: undefined +- Messages: {animation?: 'push' | 'pop'} ++ Messages: { animation?: 'push' | 'pop' } + } + + // NOTE +@@ -149,7 +150,7 @@ export type State = + | Omit, 'stale'> + + export type RouteParams = Record +-export type MatchResult = {params: RouteParams} ++export type MatchResult = { params: RouteParams } + export type Route = { + match: (path: string) => MatchResult | undefined + build: (params?: Record) => string diff --git a/src/routes.ts b/src/routes.ts -index 1ed913bb2..aa6fccc4e 100644 +index 77ea6deca..b57955ed2 100644 --- a/src/routes.ts +++ b/src/routes.ts +@@ -1,5 +1,5 @@ +-import {Router} from '#/lib/routes/router' +-import {type FlatNavigatorParams} from './lib/routes/types' ++import { Router } from '#/lib/routes/router' ++import { type FlatNavigatorParams } from './lib/routes/types' + + type AllNavigatableRoutes = Omit< + FlatNavigatorParams, @@ -71,8 +71,9 @@ export const router = new Router({ MiscellaneousNotificationSettings: '/settings/notifications/miscellaneous', // support Support: '/support', -- PrivacyPolicy: '/support/privacy', -- TermsOfService: '/support/tos', -+ PrivacyPolicy: 'https://syu.is/about/support/privacy-policy', -+ TermsOfService: 'https://syu.is/about/support/tos', +- PrivacyPolicy: 'https://syu.is/about/support/privacy-policy', +- TermsOfService: 'https://syu.is/about/support/tos', ++ PrivacyPolicy: '/support/privacy', ++ TermsOfService: '/support/tos', + License: '/support/license', CommunityGuidelines: '/support/community-guidelines', CopyrightPolicy: '/support/copyright', // hashtags -diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx -index ed2a6cfb7..982c40b55 100644 ---- a/src/view/shell/Drawer.tsx -+++ b/src/view/shell/Drawer.tsx -@@ -1,60 +1,50 @@ --import React, {type ComponentProps, type JSX} from 'react' --import {Linking, ScrollView, TouchableOpacity, View} from 'react-native' --import {useSafeAreaInsets} from 'react-native-safe-area-context' --import {msg, Plural, plural, Trans} from '@lingui/macro' --import {useLingui} from '@lingui/react' --import {StackActions, useNavigation} from '@react-navigation/native' -- --import {useActorStatus} from '#/lib/actor-status' --import {FEEDBACK_FORM_URL, HELP_DESK_URL} from '#/lib/constants' --import {type PressableScale} from '#/lib/custom-animations/PressableScale' --import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState' --import {getTabState, TabState} from '#/lib/routes/helpers' --import {type NavigationProp} from '#/lib/routes/types' --import {sanitizeHandle} from '#/lib/strings/handles' --import {colors} from '#/lib/styles' --import {isWeb} from '#/platform/detection' --import {emitSoftReset} from '#/state/events' --import {useKawaiiMode} from '#/state/preferences/kawaii' --import {useUnreadNotifications} from '#/state/queries/notifications/unread' --import {useProfileQuery} from '#/state/queries/profile' --import {type SessionAccount, useSession} from '#/state/session' --import {useSetDrawerOpen} from '#/state/shell' --import {formatCount} from '#/view/com/util/numeric/format' --import {UserAvatar} from '#/view/com/util/UserAvatar' --import {NavSignupCard} from '#/view/shell/NavSignupCard' --import {atoms as a, tokens, useTheme, web} from '#/alf' --import {Button, ButtonIcon, ButtonText} from '#/components/Button' --import {Divider} from '#/components/Divider' -+import React, { type ComponentProps, type JSX } from 'react' -+import { Linking, ScrollView, TouchableOpacity, View } from 'react-native' -+import { useSafeAreaInsets } from 'react-native-safe-area-context' -+import { msg, Plural, plural, Trans } from '@lingui/macro' -+import { useLingui } from '@lingui/react' -+import { StackActions, useNavigation } from '@react-navigation/native' -+ -+import { useActorStatus } from '#/lib/actor-status' -+import { FEEDBACK_FORM_URL, HELP_DESK_URL } from '#/lib/constants' -+import { type PressableScale } from '#/lib/custom-animations/PressableScale' -+import { useNavigationTabState } from '#/lib/hooks/useNavigationTabState' -+import { getTabState, TabState } from '#/lib/routes/helpers' -+import { type NavigationProp } from '#/lib/routes/types' -+import { sanitizeHandle } from '#/lib/strings/handles' -+import { colors } from '#/lib/styles' -+import { isWeb } from '#/platform/detection' -+import { emitSoftReset } from '#/state/events' -+import { useKawaiiMode } from '#/state/preferences/kawaii' -+import { useUnreadNotifications } from '#/state/queries/notifications/unread' -+import { useProfileQuery } from '#/state/queries/profile' -+import { type SessionAccount, useSession } from '#/state/session' -+import { useSetDrawerOpen } from '#/state/shell' -+import { formatCount } from '#/view/com/util/numeric/format' -+import { UserAvatar } from '#/view/com/util/UserAvatar' -+import { NavSignupCard } from '#/view/shell/NavSignupCard' -+import { atoms as a, tokens, useTheme, web } from '#/alf' -+import { Button } from '#/components/Button' -+import { Divider } from '#/components/Divider' - import { - Bell_Filled_Corner0_Rounded as BellFilled, - Bell_Stroke2_Corner0_Rounded as Bell, - } from '#/components/icons/Bell' --import {Bookmark, BookmarkFilled} from '#/components/icons/Bookmark' --import {BulletList_Stroke2_Corner0_Rounded as List} from '#/components/icons/BulletList' --import { -- Hashtag_Filled_Corner0_Rounded as HashtagFilled, -- Hashtag_Stroke2_Corner0_Rounded as Hashtag, --} from '#/components/icons/Hashtag' - import { - HomeOpen_Filled_Corner0_Rounded as HomeFilled, - HomeOpen_Stoke2_Corner0_Rounded as Home, - } from '#/components/icons/HomeOpen' --import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass' --import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2' --import { -- Message_Stroke2_Corner0_Rounded as Message, -- Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, --} from '#/components/icons/Message' --import {SettingsGear2_Stroke2_Corner0_Rounded as Settings} from '#/components/icons/SettingsGear2' -+import { MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled } from '#/components/icons/MagnifyingGlass' -+import { MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass } from '#/components/icons/MagnifyingGlass2' -+import { SettingsGear2_Stroke2_Corner0_Rounded as Settings } from '#/components/icons/SettingsGear2' - import { - UserCircle_Filled_Corner0_Rounded as UserCircleFilled, - UserCircle_Stroke2_Corner0_Rounded as UserCircle, - } from '#/components/icons/UserCircle' --import {InlineLinkText} from '#/components/Link' --import {Text} from '#/components/Typography' --import {useSimpleVerificationState} from '#/components/verification' --import {VerificationCheck} from '#/components/verification/VerificationCheck' -+import { InlineLinkText } from '#/components/Link' -+import { Text } from '#/components/Typography' -+import { useSimpleVerificationState } from '#/components/verification' -+import { VerificationCheck } from '#/components/verification/VerificationCheck' - - const iconWidth = 26 - -@@ -65,11 +55,11 @@ let DrawerProfileCard = ({ - account: SessionAccount - onPressProfile: () => void - }): React.ReactNode => { -- const {_, i18n} = useLingui() -+ const { _, i18n } = useLingui() - const t = useTheme() -- const {data: profile} = useProfileQuery({did: account.did}) -- const verification = useSimpleVerificationState({profile}) -- const {isActive: live} = useActorStatus(profile) -+ const { data: profile } = useProfileQuery({ did: account.did }) -+ const verification = useSimpleVerificationState({ profile }) -+ const { isActive: live } = useActorStatus(profile) - - return ( - ): React.ReactNode => { -+let DrawerContent = ({ }: React.PropsWithoutRef<{}>): React.ReactNode => { - const t = useTheme() - const insets = useSafeAreaInsets() - const setDrawerOpen = useSetDrawerOpen() -@@ -150,27 +139,20 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { - const { - isAtHome, - isAtSearch, -- isAtFeeds, -- isAtBookmarks, - isAtNotifications, - isAtMyProfile, -- isAtMessages, - } = useNavigationTabState() -- const {hasSession, currentAccount} = useSession() -- -- // events -- // = -+ const { hasSession, currentAccount } = useSession() - - const onPressTab = React.useCallback( - (tab: 'Home' | 'Search' | 'Messages' | 'Notifications' | 'MyProfile') => { - const state = navigation.getState() - setDrawerOpen(false) - if (isWeb) { -- // hack because we have flat navigator for web and MyProfile does not exist on the web navigator -ansh - if (tab === 'MyProfile') { -- navigation.navigate('Profile', {name: currentAccount!.handle}) -+ navigation.navigate('Profile', { name: currentAccount!.handle }) - } else { -- // @ts-expect-error struggles with string unions, apparently -+ // @ts-expect-error struggles with string unions - navigation.navigate(tab) - } - } else { -@@ -178,21 +160,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { - if (tabState === TabState.InsideAtRoot) { - emitSoftReset() - } else if (tabState === TabState.Inside) { -- // find the correct navigator in which to pop-to-top -- const target = state.routes.find(route => route.name === `${tab}Tab`) -- ?.state?.key -+ const target = state.routes.find(route => route.name === `${tab}Tab`)?.state?.key - if (target) { -- // if we found it, trigger pop-to-top -- navigation.dispatch({ -- ...StackActions.popToTop(), -- target, -- }) -+ navigation.dispatch({ ...StackActions.popToTop(), target }) - } else { -- // fallback: reset navigation -- navigation.reset({ -- index: 0, -- routes: [{name: `${tab}Tab`}], -- }) -+ navigation.reset({ index: 0, routes: [{ name: `${tab}Tab` }] }) - } - } else { - navigation.navigate(`${tab}Tab`) -@@ -203,76 +175,21 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { - ) - - const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab]) -- -- const onPressSearch = React.useCallback( -- () => onPressTab('Search'), -- [onPressTab], -- ) -- -- const onPressMessages = React.useCallback( -- () => onPressTab('Messages'), -- [onPressTab], -- ) -- -- const onPressNotifications = React.useCallback( -- () => onPressTab('Notifications'), -- [onPressTab], -- ) -- -- const onPressProfile = React.useCallback(() => { -- onPressTab('MyProfile') -- }, [onPressTab]) -- -- const onPressMyFeeds = React.useCallback(() => { -- navigation.navigate('Feeds') -- setDrawerOpen(false) -- }, [navigation, setDrawerOpen]) -- -- const onPressLists = React.useCallback(() => { -- navigation.navigate('Lists') -- setDrawerOpen(false) -- }, [navigation, setDrawerOpen]) -- -- const onPressBookmarks = React.useCallback(() => { -- navigation.navigate('Bookmarks') -- setDrawerOpen(false) -- }, [navigation, setDrawerOpen]) -- -+ const onPressSearch = React.useCallback(() => onPressTab('Search'), [onPressTab]) -+ const onPressNotifications = React.useCallback(() => onPressTab('Notifications'), [onPressTab]) -+ const onPressProfile = React.useCallback(() => { onPressTab('MyProfile') }, [onPressTab]) - const onPressSettings = React.useCallback(() => { - navigation.navigate('Settings') - setDrawerOpen(false) - }, [navigation, setDrawerOpen]) - -- const onPressFeedback = React.useCallback(() => { -- Linking.openURL( -- FEEDBACK_FORM_URL({ -- email: currentAccount?.email, -- handle: currentAccount?.handle, -- }), -- ) -- }, [currentAccount]) -- -- const onPressHelp = React.useCallback(() => { -- Linking.openURL(HELP_DESK_URL) -- }, []) -- -- // rendering -- // = -- - return ( - - -+ contentContainerStyle={[{ paddingTop: Math.max(insets.top + a.pt_xl.paddingTop, a.pt_xl.paddingTop) }]}> - - {hasSession && currentAccount ? ( - ): React.ReactNode => { - - - )} -- - - - -@@ -292,17 +208,10 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { - <> - - -- - -- -- -- - ): React.ReactNode => { - ) : ( - <> - -- - - - )} -@@ -322,69 +230,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { - - - -- -- - - ) - } - DrawerContent = React.memo(DrawerContent) --export {DrawerContent} -- --let DrawerFooter = ({ -- onPressFeedback, -- onPressHelp, --}: { -- onPressFeedback: () => void -- onPressHelp: () => void --}): React.ReactNode => { -- const {_} = useLingui() -- const insets = useSafeAreaInsets() -- return ( -- -- -- -- -- ) --} --DrawerFooter = React.memo(DrawerFooter) -+export { DrawerContent } - - interface MenuItemProps extends ComponentProps { - icon: JSX.Element -@@ -400,7 +250,7 @@ let SearchMenuItem = ({ - isActive: boolean - onPress: () => void - }): React.ReactNode => { -- const {_} = useLingui() -+ const { _ } = useLingui() - const t = useTheme() - return ( - void - }): React.ReactNode => { -- const {_} = useLingui() -+ const { _ } = useLingui() - const t = useTheme() - return ( - void --}): React.ReactNode => { -- const {_} = useLingui() -- const t = useTheme() -- return ( -- -- ) : ( -- -- ) -- } -- label={_(msg`Chat`)} -- bold={isActive} -- onPress={onPress} -- /> -- ) --} --ChatMenuItem = React.memo(ChatMenuItem) -- - let NotificationsMenuItem = ({ - isActive, - onPress, -@@ -478,7 +302,7 @@ let NotificationsMenuItem = ({ - isActive: boolean - onPress: () => void - }): React.ReactNode => { -- const {_} = useLingui() -+ const { _ } = useLingui() - const t = useTheme() - const numUnreadNotifications = useUnreadNotifications() - return ( -@@ -495,11 +319,11 @@ let NotificationsMenuItem = ({ - numUnreadNotifications === '' - ? '' - : _( -- msg`${plural(numUnreadNotifications ?? 0, { -- one: '# unread item', -- other: '# unread items', -- })}` || '', -- ) -+ msg`${plural(numUnreadNotifications ?? 0, { -+ one: '# unread item', -+ other: '# unread items', -+ })}` || '', -+ ) - } - count={numUnreadNotifications} - bold={isActive} -@@ -509,72 +333,6 @@ let NotificationsMenuItem = ({ - } - NotificationsMenuItem = React.memo(NotificationsMenuItem) - --let FeedsMenuItem = ({ -- isActive, -- onPress, --}: { -- isActive: boolean -- onPress: () => void --}): React.ReactNode => { -- const {_} = useLingui() -- const t = useTheme() -- return ( -- -- ) : ( -- -- ) -- } -- label={_(msg`Feeds`)} -- bold={isActive} -- onPress={onPress} -- /> -- ) --} --FeedsMenuItem = React.memo(FeedsMenuItem) -- --let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => { -- const {_} = useLingui() -- const t = useTheme() -- -- return ( -- } -- label={_(msg`Lists`)} -- onPress={onPress} -- /> -- ) --} --ListsMenuItem = React.memo(ListsMenuItem) -- --let BookmarksMenuItem = ({ -- isActive, -- onPress, --}: { -- isActive: boolean -- onPress: () => void --}): React.ReactNode => { -- const {_} = useLingui() -- const t = useTheme() -- -- return ( -- -- ) : ( -- -- ) -- } -- label={_(msg({message: 'Saved', context: 'link to bookmarks screen'}))} -- onPress={onPress} -- /> -- ) --} --BookmarksMenuItem = React.memo(BookmarksMenuItem) -- - let ProfileMenuItem = ({ - isActive, - onPress, -@@ -582,7 +340,7 @@ let ProfileMenuItem = ({ - isActive: boolean - onPress: () => void - }): React.ReactNode => { -- const {_} = useLingui() -+ const { _ } = useLingui() - const t = useTheme() - return ( - void}): React.ReactNode => { -- const {_} = useLingui() -+let SettingsMenuItem = ({ onPress }: { onPress: () => void }): React.ReactNode => { -+ const { _ } = useLingui() - const t = useTheme() - return ( - void}): React.ReactNode => { - } - SettingsMenuItem = React.memo(SettingsMenuItem) - --function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) { -+function MenuItem({ icon, label, count, bold, onPress }: MenuItemProps) { - const t = useTheme() - return ( - +- +- +- 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..86de5f747 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') +@@ -33,49 +33,9 @@ export function FollowingEndOfFeed() { + }, [navigation]) + + return ( +- ++ + +- +- +- You've reached the end of your feed! Find some more accounts to +- follow. +- +- +- +- +- +- You can also discover new Custom Feeds to follow. +- +- ++ {/* User requested strict cleanup: Remove all Discover/Find Accounts buttons */} + + + ) diff --git a/ios/setup.zsh b/ios/setup.zsh index ac08a9e..79e40c7 100755 --- a/ios/setup.zsh +++ b/ios/setup.zsh @@ -26,6 +26,7 @@ PATCH_FILES_IOS=( "013-social-app-ios-settings-remove-help.patch" "019-social-app-ios-entitlements-plugin.patch" "020-social-app-ios-bypass-age-assurance.patch" + "021-social-app-ios-clean-feed.patch" ) function ios-env() {