From b812857be1c4509e0d541043d9f0e9a08c514ffe Mon Sep 17 00:00:00 2001 From: syui Date: Thu, 8 Jan 2026 08:43:57 +0900 Subject: [PATCH] fix ios build scpt --- ios/build.zsh | 11 +- .../005-social-app-ios-screens.patch.bak | 593 ++++++++++++++++++ 2 files changed, 602 insertions(+), 2 deletions(-) create mode 100644 ios/patching/005-social-app-ios-screens.patch.bak diff --git a/ios/build.zsh b/ios/build.zsh index a379cff..cf8d281 100755 --- a/ios/build.zsh +++ b/ios/build.zsh @@ -167,8 +167,15 @@ cp -R ${APP_NAME}.xcarchive/Products/Applications/${APP_NAME}.app Payload/ # store.mobileprovisionの存在確認とコピー # https://developer.apple.com/account/resources/profiles/list if [ ! -f "$MOBILEPROVISION" ]; then - echo "Error: store.mobileprovision not found at $MOBILEPROVISION" - exit 1 + # 親ディレクトリからコピーを試みる + PARENT_MOBILEPROVISION="$SCRIPT_DIR/../embedded.mobileprovision" + if [ -f "$PARENT_MOBILEPROVISION" ]; then + echo "Copying mobileprovision from $PARENT_MOBILEPROVISION to $MOBILEPROVISION" + cp "$PARENT_MOBILEPROVISION" "$MOBILEPROVISION" + else + echo "Error: store.mobileprovision not found at $MOBILEPROVISION or $PARENT_MOBILEPROVISION" + exit 1 + fi fi cp "$MOBILEPROVISION" Payload/${APP_NAME}.app/embedded.mobileprovision diff --git a/ios/patching/005-social-app-ios-screens.patch.bak b/ios/patching/005-social-app-ios-screens.patch.bak new file mode 100644 index 0000000..492e263 --- /dev/null +++ b/ios/patching/005-social-app-ios-screens.patch.bak @@ -0,0 +1,593 @@ +diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx +index 6b8257b91..48ba7909e 100644 +--- a/src/screens/Settings/AboutSettings.tsx ++++ b/src/screens/Settings/AboutSettings.tsx +@@ -80,7 +80,7 @@ export function AboutSettingsScreen({}: Props) { + + + + + +@@ -88,7 +88,7 @@ export function AboutSettingsScreen({}: Props) { + + + + + +diff --git a/src/screens/Takendown.tsx b/src/screens/Takendown.tsx +index 77f219e55..53f5e0cc0 100644 +--- a/src/screens/Takendown.tsx ++++ b/src/screens/Takendown.tsx +@@ -217,10 +217,10 @@ export function Takendown() { + + Your account was found to be in violation of the{' '} + +- Bluesky Social Terms of Service ++ syu.is Terms of Service + + . You have been sent an email outlining the specific violation + and suspension period, if applicable. You can appeal this +diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx +index e058e2883..8daf41089 100644 +--- a/src/view/screens/Home.tsx ++++ b/src/view/screens/Home.tsx +@@ -1,23 +1,16 @@ + import React from 'react' + import {ActivityIndicator, StyleSheet} from 'react-native' + import {useFocusEffect} from '@react-navigation/native' +- + import {PROD_DEFAULT_FEED} from '#/lib/constants' + import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' + import {useOTAUpdates} from '#/lib/hooks/useOTAUpdates' + import {useSetTitle} from '#/lib/hooks/useSetTitle' + import {useRequestNotificationsPermission} from '#/lib/notifications/notifications' +-import { +- type HomeTabNavigatorParams, +- type NativeStackScreenProps, +-} from '#/lib/routes/types' ++import {type HomeTabNavigatorParams, type NativeStackScreenProps} from '#/lib/routes/types' + import {logEvent} from '#/lib/statsig/statsig' + import {isWeb} from '#/platform/detection' + import {emitSoftReset} from '#/state/events' +-import { +- type SavedFeedSourceInfo, +- usePinnedFeedsInfos, +-} from '#/state/queries/feed' ++import {type SavedFeedSourceInfo, usePinnedFeedsInfos} from '#/state/queries/feed' + import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' + import {usePreferencesQuery} from '#/state/queries/preferences' + import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' +@@ -27,11 +20,7 @@ import {useLoggedOutViewControls} from '#/state/shell/logged-out' + import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed' + import {FeedPage} from '#/view/com/feeds/FeedPage' + import {HomeHeader} from '#/view/com/home/HomeHeader' +-import { +- Pager, +- type PagerRef, +- type RenderTabBarFnProps, +-} from '#/view/com/pager/Pager' ++import {Pager, type PagerRef, type RenderTabBarFnProps} from '#/view/com/pager/Pager' + import {CustomFeedEmptyState} from '#/view/com/posts/CustomFeedEmptyState' + import {FollowingEmptyState} from '#/view/com/posts/FollowingEmptyState' + import {FollowingEndOfFeed} from '#/view/com/posts/FollowingEndOfFeed' +@@ -39,97 +28,90 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned' + import * as Layout from '#/components/Layout' + import {useDemoMode} from '#/storage/hooks/demo-mode' + ++const SYU_IS_FEED_URI = 'at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.generator/app' ++ ++const DEFAULT_PINNED_FEEDS: any[] = [{ ++ feedDescriptor: 'following', ++ displayName: 'Following', ++ id: 'following', ++ uri: 'following', ++ type: 'feed', ++ savedFeed: undefined, ++ pinned: true, ++ route: { href: '/', name: 'Home', params: {} }, ++ cid: '', ++ avatar: '', ++ creatorDid: '', ++ creatorHandle: '', ++}, { ++ feedDescriptor: `feedgen|${SYU_IS_FEED_URI}`, ++ displayName: 'Feeds', ++ id: SYU_IS_FEED_URI, ++ uri: SYU_IS_FEED_URI, ++ type: 'feed', ++ savedFeed: { ++ type: 'feed', ++ value: SYU_IS_FEED_URI, ++ pinned: true, ++ }, ++ pinned: true, ++ route: { href: '/', name: 'Home', params: {} }, ++ cid: '', ++ avatar: '', ++ creatorDid: '', ++ creatorHandle: '', ++}] ++ + type Props = NativeStackScreenProps + export function HomeScreen(props: Props) { + const {setShowLoggedOut} = useLoggedOutViewControls() + const {data: preferences} = usePreferencesQuery() + const {currentAccount} = useSession() +- const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} = +- usePinnedFeedsInfos() ++ const {data: pinnedFeedInfos} = usePinnedFeedsInfos() ++ ++ const safePreferences = preferences || { feedViewPrefs: { lab_mergeFeedEnabled: false }, savedFeeds: [] } as any ++ // Use user's pinned feeds when logged in and available, otherwise use defaults ++ const safePinnedFeedInfos = !currentAccount ++ ? DEFAULT_PINNED_FEEDS.filter(f => f.feedDescriptor !== 'following') ++ : (pinnedFeedInfos && pinnedFeedInfos.length > 0) ++ ? pinnedFeedInfos ++ : DEFAULT_PINNED_FEEDS + + React.useEffect(() => { + if (isWeb && !currentAccount) { + const getParams = new URLSearchParams(window.location.search) + const splash = getParams.get('splash') +- if (splash === 'true') { +- setShowLoggedOut(true) +- return +- } ++ if (splash === 'true') { setShowLoggedOut(true); return } + } +- + const params = props.route.params +- if ( +- currentAccount && +- props.route.name === 'Start' && +- params?.name && +- params?.rkey +- ) { +- props.navigation.navigate('StarterPack', { +- rkey: params.rkey, +- name: params.name, +- }) ++ if (currentAccount && props.route.name === 'Start' && params?.name && params?.rkey) { ++ props.navigation.navigate('StarterPack', { rkey: params.rkey, name: params.name }) + } +- }, [ +- currentAccount, +- props.navigation, +- props.route.name, +- props.route.params, +- setShowLoggedOut, +- ]) ++ }, [currentAccount, props.navigation, props.route.name, props.route.params, setShowLoggedOut]) + +- if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) { +- return ( +- +- +- +- ) +- } else { +- return ( +- +- +- +- +- +- ) +- } ++ return ( ++ ++ ++ ++ ) + } + +-function HomeScreenReady({ +- preferences, +- pinnedFeedInfos, +-}: Props & { +- preferences: UsePreferencesQueryResponse +- pinnedFeedInfos: SavedFeedSourceInfo[] +-}) { +- const allFeeds = React.useMemo( +- () => pinnedFeedInfos.map(f => f.feedDescriptor), +- [pinnedFeedInfos], +- ) +- const maybeRawSelectedFeed: FeedDescriptor | undefined = +- useSelectedFeed() ?? allFeeds[0] ++function HomeScreenReady({preferences, pinnedFeedInfos}: any) { ++ const allFeeds = React.useMemo(() => pinnedFeedInfos.map(f => f.feedDescriptor), [pinnedFeedInfos]) ++ const maybeRawSelectedFeed = useSelectedFeed() ?? allFeeds[0] + const setSelectedFeed = useSetSelectedFeed() + const maybeFoundIndex = allFeeds.indexOf(maybeRawSelectedFeed) + const selectedIndex = Math.max(0, maybeFoundIndex) +- const maybeSelectedFeed: FeedDescriptor | undefined = allFeeds[selectedIndex] ++ const maybeSelectedFeed = allFeeds[selectedIndex] + const requestNotificationsPermission = useRequestNotificationsPermission() + + useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName) + useOTAUpdates() +- +- React.useEffect(() => { +- requestNotificationsPermission('Home') +- }, [requestNotificationsPermission]) ++ React.useEffect(() => { requestNotificationsPermission('Home') }, [requestNotificationsPermission]) + + const pagerRef = React.useRef(null) + const lastPagerReportedIndexRef = React.useRef(selectedIndex) + React.useLayoutEffect(() => { +- // Since the pager is not a controlled component, adjust it imperatively +- // if the selected index gets out of sync with what it last reported. +- // This is supposed to only happen on the web when you use the right nav. + if (selectedIndex !== lastPagerReportedIndexRef.current) { + lastPagerReportedIndexRef.current = selectedIndex + pagerRef.current?.setPage(selectedIndex) +@@ -138,205 +120,43 @@ function HomeScreenReady({ + + const {hasSession} = useSession() + const setMinimalShellMode = useSetMinimalShellMode() +- useFocusEffect( +- React.useCallback(() => { +- setMinimalShellMode(false) +- }, [setMinimalShellMode]), +- ) ++ useFocusEffect(React.useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode])) + +- useFocusEffect( +- useNonReactiveCallback(() => { +- if (maybeSelectedFeed) { +- logEvent('home:feedDisplayed', { +- index: selectedIndex, +- feedType: maybeSelectedFeed.split('|')[0], +- feedUrl: maybeSelectedFeed, +- reason: 'focus', +- }) +- } +- }), +- ) +- +- const onPageSelected = React.useCallback( +- (index: number) => { +- setMinimalShellMode(false) +- const maybeFeed = allFeeds[index] ++ const onPageSelected = React.useCallback((index) => { ++ setMinimalShellMode(false) ++ const maybeFeed = allFeeds[index] ++ lastPagerReportedIndexRef.current = index ++ setSelectedFeed(maybeFeed) ++ }, [setSelectedFeed, setMinimalShellMode, allFeeds]) + +- // Mutate the ref before setting state to avoid the imperative syncing effect +- // above from starting a loop on Android when swiping back and forth. +- lastPagerReportedIndexRef.current = index +- setSelectedFeed(maybeFeed) +- +- if (maybeFeed) { +- logEvent('home:feedDisplayed', { +- index, +- feedType: maybeFeed.split('|')[0], +- feedUrl: maybeFeed, +- }) +- } +- }, +- [setSelectedFeed, setMinimalShellMode, allFeeds], +- ) +- +- const onPressSelected = React.useCallback(() => { +- emitSoftReset() +- }, []) +- +- const onPageScrollStateChanged = React.useCallback( +- (state: 'idle' | 'dragging' | 'settling') => { +- 'worklet' +- if (state === 'dragging') { +- setMinimalShellMode(false) +- } +- }, +- [setMinimalShellMode], +- ) ++ const onPressSelected = React.useCallback(() => { emitSoftReset() }, []) ++ const onPageScrollStateChanged = React.useCallback((state) => { ++ 'worklet' ++ if (state === 'dragging') setMinimalShellMode(false) ++ }, [setMinimalShellMode]) + + const [demoMode] = useDemoMode() ++ const renderTabBar = React.useCallback((props) => { ++ return ++ }, [onPressSelected, pinnedFeedInfos]) + +- const renderTabBar = React.useCallback( +- (props: RenderTabBarFnProps) => { +- if (demoMode) { +- return ( +- +- ) +- } +- return ( +- +- ) +- }, +- [onPressSelected, pinnedFeedInfos, demoMode], +- ) +- +- const renderFollowingEmptyState = React.useCallback(() => { +- return +- }, []) ++ const renderFollowingEmptyState = React.useCallback(() => , []) ++ const renderCustomFeedEmptyState = React.useCallback(() => , []) + +- const renderCustomFeedEmptyState = React.useCallback(() => { +- return +- }, []) ++ const homeFeedParams = React.useMemo(() => ({ ++ mergeFeedEnabled: false, mergeFeedSources: [] ++ }), [preferences]) + +- const homeFeedParams = React.useMemo(() => { +- return { +- mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled), +- mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled +- ? preferences.savedFeeds +- .filter(f => f.type === 'feed' || f.type === 'list') +- .map(f => f.value) +- : [], +- } +- }, [preferences]) +- +- if (demoMode) { +- return ( +- +- +- +- +- ) +- } +- +- return hasSession ? ( +- +- {pinnedFeedInfos.length ? ( +- pinnedFeedInfos.map((feedInfo, index) => { ++ return ( ++ ++ {pinnedFeedInfos.map((feedInfo, index) => { + const feed = feedInfo.feedDescriptor + if (feed === 'following') { +- return ( +- +- ) ++ return + } +- const savedFeedConfig = feedInfo.savedFeed +- return ( +- +- ) +- }) +- ) : ( +- +- )} +- +- ) : ( +- +- ++ return ++ })} + + ) + } +- +-const styles = StyleSheet.create({ +- loading: { +- height: '100%', +- alignContent: 'center', +- justifyContent: 'center', +- paddingBottom: 100, +- }, +-}) ++const styles = StyleSheet.create({ loading: { height: '100%', alignContent: 'center', justifyContent: 'center', paddingBottom: 100 } }) +diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx +index a89eaadc4..1da393f03 100644 +--- a/src/view/screens/PrivacyPolicy.tsx ++++ b/src/view/screens/PrivacyPolicy.tsx +@@ -1,52 +1,13 @@ + 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 { WebView } from 'react-native-webview' + 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' + ++export function PrivacyPolicyScreen() { ++ useSetTitle('Privacy Policy') + return ( + +- +- +- +- +- +- The Privacy Policy has been moved to{' '} +- +- +- +- +- +- ++ + + ) + } +diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx +index d843c713c..b81767bd5 100644 +--- a/src/view/screens/TermsOfService.tsx ++++ b/src/view/screens/TermsOfService.tsx +@@ -1,50 +1,13 @@ + 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 { WebView } from 'react-native-webview' + 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' + ++export function TermsOfServiceScreen() { ++ useSetTitle('Terms of Service') + return ( + +- +- +- +- +- The Terms of Service have been moved to{' '} +- +- +- +- +- ++ + + ) + }