diff --git a/ios/patching/001-social-app-ios-config.patch b/ios/patching/001-social-app-ios-config.patch index eae281c..7e0bc52 100644 --- a/ios/patching/001-social-app-ios-config.patch +++ b/ios/patching/001-social-app-ios-config.patch @@ -12,7 +12,17 @@ // When testing local services, enter an ngrok (et al) domain here. It must use a standard HTTP/HTTPS port. ...(IS_DEV || IS_TESTFLIGHT ? [] : []), ] -@@ -38,27 +35,25 @@ +@@ -35,34 +32,28 @@ + + const USE_SENTRY = Boolean(process.env.SENTRY_AUTH_TOKEN) + +- const IOS_ICON_FILE = +- PLATFORM === 'web' // web build doesn't like .icon files +- ? './assets/app-icons/ios_icon_default_next.png' +- : IS_TESTFLIGHT +- ? './assets/app-icons/ios_icon_testflight.icon' +- : './assets/app-icons/ios_icon_default.icon' +- return { expo: { version: VERSION, @@ -39,15 +49,12 @@ config: { usesNonExemptEncryption: false, }, -- icon: -- PLATFORM === 'web' // web build doesn't like .icon files -- ? './assets/app-icons/ios_icon_default_next.png' -- : './assets/app-icons/ios_icon_default.icon', +- icon: IOS_ICON_FILE, + icon: './assets/app-icon.png', infoPlist: { UIBackgroundModes: ['remote-notification'], NSCameraUsageDescription: -@@ -118,7 +113,7 @@ +@@ -121,7 +112,7 @@ entitlements: { 'com.apple.developer.kernel.increased-memory-limit': true, 'com.apple.developer.kernel.extended-virtual-addressing': true, @@ -56,7 +63,7 @@ // 'com.apple.developer.device-information.user-assigned-device-name': true, }, privacyManifests: { -@@ -181,14 +176,14 @@ +@@ -184,14 +175,14 @@ barStyle: 'light-content', }, android: { @@ -73,7 +80,7 @@ intentFilters: [ { action: 'VIEW', -@@ -196,7 +191,7 @@ +@@ -199,7 +190,7 @@ data: [ { scheme: 'https', @@ -82,7 +89,7 @@ }, ...(IS_DEV ? [ -@@ -280,7 +275,6 @@ +@@ -290,7 +281,6 @@ networkInstrumentation: true, }, ], @@ -90,7 +97,7 @@ './plugins/withGradleJVMHeapSizeIncrease.js', './plugins/withAndroidManifestLargeHeapPlugin.js', './plugins/withAndroidManifestFCMIconPlugin.js', -@@ -288,8 +282,6 @@ +@@ -298,8 +288,6 @@ './plugins/withAndroidStylesAccentColorPlugin.js', './plugins/withAndroidDayNightThemePlugin.js', './plugins/withAndroidNoJitpackPlugin.js', @@ -99,7 +106,7 @@ [ 'expo-font', { -@@ -417,30 +409,7 @@ +@@ -427,30 +415,7 @@ build: { experimental: { ios: { diff --git a/ios/patching/003-social-app-ios-view.patch b/ios/patching/003-social-app-ios-view.patch index aa0cc29..264e08d 100644 --- a/ios/patching/003-social-app-ios-view.patch +++ b/ios/patching/003-social-app-ios-view.patch @@ -1,8 +1,6 @@ -diff --git a/src/Splash.tsx b/src/Splash.tsx -index 47e70b375..616f351ed 100644 --- a/src/Splash.tsx +++ b/src/Splash.tsx -@@ -15,8 +15,8 @@ import Animated, { +@@ -15,8 +15,8 @@ withTiming, } from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' @@ -12,14 +10,14 @@ index 47e70b375..616f351ed 100644 import * as SplashScreen from 'expo-splash-screen' import {Logotype} from '#/view/icons/Logotype' -@@ -29,21 +29,18 @@ const darkSplashImageUri = RNImage.resolveAssetSource( +@@ -29,21 +29,18 @@ darkSplashImagePointer, ).uri --export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) { +-export const Logo = forwardRef(function LogoImpl(props: SvgProps, ref) { - const width = 1000 - const height = width * (67 / 64) -+export const Logo = React.forwardRef(function LogoImpl(props: SvgProps & {fill?: string}, ref) { ++export const Logo = forwardRef(function LogoImpl(props: SvgProps & {fill?: string}, ref) { + const size = 1000 + // @ts-ignore return ( @@ -44,12 +42,10 @@ index 47e70b375..616f351ed 100644 ) }) -diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx -index 8a9e51a33..65d643b89 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx -@@ -444,7 +444,7 @@ let EditableUserAvatar = ({ - ) : ( -@@ -618,9 +618,8 @@ export {PreviewableUserAvatar} +@@ -617,7 +617,8 @@ // manually string-replace to use the smaller ones // -prf function hackModifyThumbnailPath(uri: string, isEnabled: boolean): string { -- return isEnabled -- ? uri.replace('/img/avatar/plain/', '/img/avatar_thumbnail/plain/') -- : uri +- return isEnabled ? convertCdnPreset(uri, 'avatar_thumbnail') : uri + // syu.is: avatars are served directly from bsky.syu.is, no CDN transformation needed + return uri } const styles = StyleSheet.create({ -diff --git a/src/view/icons/Logo.tsx b/src/view/icons/Logo.tsx -index d7208df13..2763800ac 100644 ---- a/src/view/icons/Logo.tsx -+++ b/src/view/icons/Logo.tsx -@@ -1,75 +1,17 @@ - import React from 'react' --import {type TextProps} from 'react-native' --import Svg, { -- Defs, -- LinearGradient, -- Path, -- type PathProps, -- Stop, -- type SvgProps, --} from 'react-native-svg' - import {Image} from 'expo-image' -+import {flatten} from '#/alf' - --import {useKawaiiMode} from '#/state/preferences/kawaii' --import {flatten, useTheme} from '#/alf' -- --const ratio = 57 / 64 -- --type Props = { -- fill?: PathProps['fill'] -- style?: TextProps['style'] --} & Omit -- --export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { -- const t = useTheme() -- const {fill, ...rest} = props -- const gradient = fill === 'sky' -- const styles = flatten(props.style) -- const _fill = gradient -- ? 'url(#sky)' -- : fill || styles?.color || t.palette.primary_500 -- // @ts-ignore it's fiiiiine -- const size = parseInt(rest.width || 32, 10) -- -- const isKawaii = useKawaiiMode() -- -- if (isKawaii) { -- return ( -- 100 -- ? require('../../../assets/kawaii.png') -- : require('../../../assets/kawaii_smol.png') -- } -- accessibilityLabel="Bluesky" -- accessibilityHint="" -- accessibilityIgnoresInvertColors -- style={[{height: size, aspectRatio: 1.4}]} -- /> -- ) -- } -- -+export const Logo = React.forwardRef(function LogoImpl(props: any, ref) { -+ const {width, style} = props -+ // @ts-ignore -+ const size = parseInt(width || 32, 10) - return ( -- -- {gradient && ( -- -- -- -- -- -- -- )} -- -- -- -+ - ) - }) -diff --git a/src/view/icons/Logotype.tsx b/src/view/icons/Logotype.tsx -index 270c913fc..a60ffe07c 100644 ---- a/src/view/icons/Logotype.tsx -+++ b/src/view/icons/Logotype.tsx -@@ -1,28 +1,22 @@ --import Svg, {Path, type PathProps, type SvgProps} from 'react-native-svg' -- --import {usePalette} from '#/lib/hooks/usePalette' -- --const ratio = 17 / 64 -- --export function Logotype({ -- fill, -- ...rest --}: {fill?: PathProps['fill']} & SvgProps) { -- const pal = usePalette('default') -- // @ts-ignore it's fiiiiine -- const size = parseInt(rest.width || 32) -+import React from 'react' -+import {Text} from 'react-native' -+import {useTheme, atoms as a} from '#/alf' - -+export function Logotype({width, fill, style}: any) { -+ const t = useTheme() -+ const fontSize = width ? parseInt(width) / 3.5 : 22 -+ - return ( -- -- -- -+ -+ Aiat -+ - ) - } diff --git a/ios/patching/005-social-app-ios-screens.patch b/ios/patching/005-social-app-ios-screens.patch index 762aace..4a712c1 100644 --- a/ios/patching/005-social-app-ios-screens.patch +++ b/ios/patching/005-social-app-ios-screens.patch @@ -34,191 +34,22 @@ . You have been sent an email outlining the specific violation and suspension period, if applicable. You can appeal this ---- a/src/view/screens/PrivacyPolicy.tsx -+++ b/src/view/screens/PrivacyPolicy.tsx -@@ -1,52 +1,49 @@ - import React from 'react' --import {View} from 'react-native' --import {msg} from '@lingui/core/macro' --import {useLingui} from '@lingui/react' --import {Trans} from '@lingui/react/macro' --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' -+import {useSetTitle} from '#/lib/hooks/useSetTitle' -+import {atoms as a, useTheme} from '#/alf' -+import {Text} from '#/components/Typography' - --type Props = NativeStackScreenProps --export const PrivacyPolicyScreen = (_props: Props) => { -- const pal = usePalette('default') -- const {_} = useLingui() -- const setMinimalShellMode = useSetMinimalShellMode() -+export function PrivacyPolicyScreen() { -+ useSetTitle('Privacy Policy') -+ const t = useTheme() - -- useFocusEffect( -- React.useCallback(() => { -- setMinimalShellMode(false) -- }, [setMinimalShellMode]), -- ) -- - return ( - -- -- -- -- -- -- The Privacy Policy has been moved to{' '} -- -- -- -- -- -+ -+ Privacy Policy -+ -+ Data Collection -+ -+ syu.is collects minimal data necessary to provide the service. This includes your account information, posts, and interactions on the AT Protocol network. -+ -+ -+ Data Storage -+ -+ Your data is stored on the AT Protocol network. Posts and profile information are public by default as part of the decentralized social network. -+ -+ -+ Third Parties -+ -+ We do not sell your personal information to third parties. Your data may be visible to other users and services on the AT Protocol network. -+ -+ -+ Contact -+ -+ For privacy-related questions, please contact the administrator. -+ -+ -+ 日本語 -+ -+ syu.isはサービス提供に必要な最小限のデータのみを収集します。投稿やプロフィール情報はAT Protocolネットワーク上で公開されます。個人情報を第三者に販売することはありません。 -+ -+ -+ -+ Last updated: 2026 -+ - - - ) ---- a/src/view/screens/TermsOfService.tsx -+++ b/src/view/screens/TermsOfService.tsx -@@ -1,50 +1,49 @@ - import React from 'react' --import {View} from 'react-native' --import {msg} from '@lingui/core/macro' --import {useLingui} from '@lingui/react' --import {Trans} from '@lingui/react/macro' --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' -+import {useSetTitle} from '#/lib/hooks/useSetTitle' -+import {atoms as a, useTheme} from '#/alf' -+import {Text} from '#/components/Typography' - --type Props = NativeStackScreenProps --export const TermsOfServiceScreen = (_props: Props) => { -- const pal = usePalette('default') -- const setMinimalShellMode = useSetMinimalShellMode() -- const {_} = useLingui() -+export function TermsOfServiceScreen() { -+ useSetTitle('Terms of Service') -+ const t = useTheme() - -- useFocusEffect( -- React.useCallback(() => { -- setMinimalShellMode(false) -- }, [setMinimalShellMode]), -- ) -- - return ( - -- -- -- -- -- The Terms of Service have been moved to{' '} -- -- -- -- -+ -+ Terms of Service -+ -+ Acceptance -+ -+ By using syu.is, you agree to these terms. If you do not agree, please do not use the service. -+ -+ -+ Prohibited Content -+ -+ Do not post illegal content, spam, or harass others. Do not impersonate others or spread misinformation. -+ -+ -+ Account Termination -+ -+ The administrator reserves the right to suspend or terminate accounts that violate these terms. -+ -+ -+ Disclaimer -+ -+ This service is provided "as is" without warranty of any kind. -+ -+ -+ 日本語 -+ -+ syu.isを利用することで、これらの利用規約に同意したものとみなします。違法なコンテンツの投稿、スパム、他者への嫌がらせは禁止です。管理者は規約違反のアカウントを停止する権利を有します。本サービスは現状のまま提供され、いかなる保証もありません。 -+ -+ -+ -+ Last updated: 2026 -+ - - - ) +--- a/src/view/shell/desktop/RightNav.tsx ++++ b/src/view/shell/desktop/RightNav.tsx +@@ -112,14 +112,14 @@ + + )} + + {_(msg`Privacy`)} + + {' ∙ '} + + {_(msg`Terms`)} diff --git a/ios/patching/021-social-app-ios-clean-feed.patch b/ios/patching/021-social-app-ios-clean-feed.patch index 220f5a5..211a45c 100644 --- a/ios/patching/021-social-app-ios-clean-feed.patch +++ b/ios/patching/021-social-app-ios-clean-feed.patch @@ -42,7 +42,7 @@ --- a/src/view/com/posts/FollowingEmptyState.tsx +++ b/src/view/com/posts/FollowingEmptyState.tsx @@ -1,38 +1,15 @@ - import React from 'react' + import {useCallback} from 'react' import {StyleSheet, View} from 'react-native' -import { - FontAwesomeIcon, @@ -64,7 +64,7 @@ - const palInverted = usePalette('inverted') - const navigation = useNavigation() -- const onPressFindAccounts = React.useCallback(() => { +- const onPressFindAccounts = useCallback(() => { - if (IS_WEB) { - navigation.navigate('Search', {}) - } else { @@ -73,7 +73,7 @@ - } - }, [navigation]) - -- const onPressDiscoverFeeds = React.useCallback(() => { +- const onPressDiscoverFeeds = useCallback(() => { - navigation.navigate('Feeds') - }, [navigation]) - @@ -134,7 +134,7 @@ --- a/src/view/com/posts/FollowingEndOfFeed.tsx +++ b/src/view/com/posts/FollowingEndOfFeed.tsx @@ -1,37 +1,14 @@ - import React from 'react' + import {useCallback} from 'react' import {Dimensions, StyleSheet, View} from 'react-native' -import { - FontAwesomeIcon, @@ -155,7 +155,7 @@ - const palInverted = usePalette('inverted') - const navigation = useNavigation() -- const onPressFindAccounts = React.useCallback(() => { +- const onPressFindAccounts = useCallback(() => { - if (IS_WEB) { - navigation.navigate('Search', {}) - } else { @@ -164,7 +164,7 @@ - } - }, [navigation]) - -- const onPressDiscoverFeeds = React.useCallback(() => { +- const onPressDiscoverFeeds = useCallback(() => { - navigation.navigate('Feeds') - }, [navigation]) - @@ -230,7 +230,55 @@ }) --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx -@@ -765,7 +765,7 @@ +@@ -520,16 +520,17 @@ + key: 'liveEventFeedsAndTrendingBanner-' + sliceIndex, + }) + // Show composer prompt for Discover and Following feeds +- if ( +- hasSession && +- (feedUriOrActorDid === DISCOVER_FEED_URI || +- feed === 'following') +- ) { +- arr.push({ +- type: 'composerPrompt', +- key: 'composerPrompt-' + sliceIndex, +- }) +- } ++ // Disabled: hide composer prompt ++ // if ( ++ // hasSession && ++ // (feedUriOrActorDid === DISCOVER_FEED_URI || ++ // feed === 'following') ++ // ) { ++ // arr.push({ ++ // type: 'composerPrompt', ++ // key: 'composerPrompt-' + sliceIndex, ++ // }) ++ // } + } else if (sliceIndex === 15) { + if (areVideoFeedsEnabled && !trendingVideoDisabled) { + arr.push({ +@@ -546,12 +547,13 @@ + } else if (feedKind === 'following') { + if (sliceIndex === 0) { + // Show composer prompt for Following feed +- if (hasSession) { +- arr.push({ +- type: 'composerPrompt', +- key: 'composerPrompt-' + sliceIndex, +- }) +- } ++ // Disabled: hide composer prompt ++ // if (hasSession) { ++ // arr.push({ ++ // type: 'composerPrompt', ++ // key: 'composerPrompt-' + sliceIndex, ++ // }) ++ // } + } + } else if (feedKind === 'profile') { + if (sliceIndex === 5) { +@@ -771,7 +773,7 @@ } else if (row.type === 'feedShutdownMsg') { return } else if (row.type === 'interstitialFollows') { diff --git a/ios/patching/022-social-app-ios-bskyweb-support-pages.patch b/ios/patching/022-social-app-ios-bskyweb-support-pages.patch deleted file mode 100644 index a7e1774..0000000 --- a/ios/patching/022-social-app-ios-bskyweb-support-pages.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/bskyweb/cmd/bskyweb/server.go -+++ b/bskyweb/cmd/bskyweb/server.go -@@ -317,6 +317,14 @@ func serve(cctx *cli.Context) error { - e.GET("/support/tos", server.WebGeneric) - e.GET("/support/community-guidelines", server.WebGeneric) - e.GET("/support/copyright", server.WebGeneric) -+ e.GET("/support/privacy-policy", server.WebGeneric) -+ e.GET("/support/license", server.WebGeneric) -+ e.GET("/support/app", server.WebGeneric) -+ e.GET("/support/help", server.WebGeneric) -+ // /about/support/ paths (for web compatibility) -+ e.GET("/about/support/tos", server.WebGeneric) -+ e.GET("/about/support/privacy-policy", server.WebGeneric) -+ e.GET("/about/support/license", server.WebGeneric) - e.GET("/intent/compose", server.WebGeneric) - e.GET("/intent/verify-email", server.WebGeneric) - e.GET("/intent/age-assurance", server.WebGeneric) diff --git a/ios/patching/025-social-app-ios-bskyweb-title.patch b/ios/patching/022-social-app-ios-bskyweb.patch similarity index 79% rename from ios/patching/025-social-app-ios-bskyweb-title.patch rename to ios/patching/022-social-app-ios-bskyweb.patch index 9b674e6..763a088 100644 --- a/ios/patching/025-social-app-ios-bskyweb-title.patch +++ b/ios/patching/022-social-app-ios-bskyweb.patch @@ -1,4 +1,20 @@ -diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html +--- a/bskyweb/cmd/bskyweb/server.go ++++ b/bskyweb/cmd/bskyweb/server.go +@@ -317,6 +317,14 @@ + e.GET("/support/tos", server.WebGeneric) + e.GET("/support/community-guidelines", server.WebGeneric) + e.GET("/support/copyright", server.WebGeneric) ++ e.GET("/support/privacy-policy", server.WebGeneric) ++ e.GET("/support/license", server.WebGeneric) ++ e.GET("/support/app", server.WebGeneric) ++ e.GET("/support/help", server.WebGeneric) ++ // /about/support/ paths (for web compatibility) ++ e.GET("/about/support/tos", server.WebGeneric) ++ e.GET("/about/support/privacy-policy", server.WebGeneric) ++ e.GET("/about/support/license", server.WebGeneric) + e.GET("/intent/compose", server.WebGeneric) + e.GET("/intent/verify-email", server.WebGeneric) + e.GET("/intent/age-assurance", server.WebGeneric) --- a/bskyweb/templates/base.html +++ b/bskyweb/templates/base.html @@ -7,9 +7,9 @@ @@ -11,10 +27,10 @@ diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html + + + {%- block head_title -%}syu.is{%- endblock -%} - + - -@@ -121,7 +121,7 @@ + +@@ -158,7 +158,7 @@