ai/at
1
0

Compare commits

..

1 Commits

Author SHA1 Message Date
1ae9890981 fix ignore 2026-02-20 07:30:40 +09:00
51 changed files with 151 additions and 256 deletions

View File

@@ -1,6 +1,5 @@
# at # at
- https://github.com/bluesky-social/atproto
- https://github.com/bluesky-social/social-app - https://github.com/bluesky-social/social-app
|name|type|example| |name|type|example|

32
icon.svg Normal file
View File

@@ -0,0 +1,32 @@
<svg
viewBox="0 0 2821.6379 794.29016"
preserveAspectRatio="xMidYMid"
xmlns:svg="http://www.w3.org/2000/svg">
<g
transform="matrix(0.1,0,0,-0.1,-282.80153,1445)"
fill="#000000"
stroke="none"
>
<path
d="m 24787,14443 c -4,-3 -7,-224 -7,-490 v -483 h 545 545 v 490 490 h -538 c -296,0 -542,-3 -545,-7 z"
/>
<path
d="m 5190,13285 c -8,-3 -96,-12 -195,-20 -199,-16 -296,-32 -430,-70 -49,-14 -115,-32 -145,-40 -153,-39 -504,-198 -662,-301 -21,-13 -57,-36 -80,-51 -24,-16 -72,-50 -109,-78 -241,-182 -377,-315 -528,-517 -119,-158 -120,-160 -106,-188 23,-45 140,-140 560,-457 110,-84 319,-242 465,-353 146,-110 369,-279 495,-375 791,-600 723,-549 1049,-799 269,-207 398,-307 524,-403 l 114,-86 -49,-49 c -128,-131 -378,-258 -588,-299 -66,-13 -357,-13 -420,0 -115,23 -172,39 -202,54 -18,10 -37,17 -43,17 -24,0 -171,81 -255,141 -50,35 -146,121 -215,192 -69,70 -133,127 -142,127 -19,0 -153,-63 -177,-83 -9,-7 -54,-35 -101,-62 -47,-26 -110,-64 -140,-85 -30,-20 -97,-61 -148,-91 -51,-30 -107,-62 -124,-72 -18,-10 -57,-38 -87,-61 -70,-53 -252,-168 -446,-281 -82,-49 -158,-95 -168,-104 -16,-16 -14,-21 34,-106 165,-289 544,-666 867,-860 9,-6 35,-22 58,-37 36,-23 267,-138 349,-173 108,-47 160,-67 240,-93 150,-48 201,-62 228,-62 14,0 64,-9 109,-19 197,-46 302,-56 573,-56 197,1 281,5 345,17 47,9 110,19 141,22 31,3 75,13 99,21 23,8 56,15 72,15 17,0 51,7 77,15 25,8 80,24 121,36 41,12 125,41 185,66 61,25 124,50 140,56 17,7 89,42 160,78 113,58 177,98 395,246 82,56 273,232 403,371 127,136 237,271 237,291 0,12 -208,179 -425,342 -186,140 -1121,843 -1720,1294 -264,199 -589,444 -723,546 -134,101 -274,208 -312,237 -39,29 -70,58 -70,66 0,21 107,115 203,179 95,64 237,133 295,143 20,4 49,12 63,20 96,48 519,48 619,-1 14,-7 41,-16 60,-20 65,-13 262,-118 360,-191 99,-74 250,-230 372,-384 34,-44 70,-80 80,-80 9,0 39,15 67,33 28,17 70,44 94,58 23,15 121,76 217,136 96,60 254,156 350,213 96,56 272,160 390,230 118,70 230,135 248,144 41,21 41,45 -3,116 -18,30 -46,75 -61,100 -64,106 -252,348 -352,454 -106,112 -169,171 -293,274 -197,164 -310,235 -594,376 -215,106 -519,205 -735,240 -137,22 -574,51 -610,41 z"
/>
<path
d="m 29095,12736 c -421,-44 -744,-157 -975,-342 -259,-207 -396,-446 -465,-809 -16,-84 -23,-301 -14,-425 36,-518 257,-859 694,-1070 166,-80 284,-116 716,-215 449,-103 514,-121 646,-186 218,-107 308,-253 306,-494 -2,-303 -188,-477 -588,-551 -140,-26 -640,-27 -825,-1 -275,38 -486,94 -776,203 -94,35 -174,64 -178,64 -3,0 -6,-175 -6,-389 v -388 l 88,-41 c 404,-187 905,-282 1486,-282 675,0 1154,150 1465,459 196,194 311,434 362,756 20,121 17,476 -5,600 -89,517 -358,800 -945,994 -130,43 -241,71 -616,156 -137,31 -299,73 -360,92 -331,106 -455,246 -455,511 1,249 127,412 387,501 272,92 801,76 1269,-39 116,-28 326,-96 432,-138 l 52,-22 -2,406 -3,406 -66,28 c -154,66 -413,140 -604,174 -279,49 -756,69 -1020,42 z"
/>
<path
d="m 9630,12676 c 0,-2 403,-996 896,-2208 493,-1211 898,-2211 901,-2220 6,-21 -135,-386 -193,-499 -104,-202 -256,-324 -471,-380 -118,-30 -340,-43 -516,-29 -84,6 -185,17 -225,24 -40,7 -75,10 -77,7 -3,-2 -5,-163 -5,-357 v -353 l 63,-30 c 194,-93 493,-138 801,-120 414,23 683,115 937,319 174,140 357,402 474,680 26,62 1945,5159 1945,5167 0,2 -232,2 -516,1 l -517,-3 -556,-1550 c -485,-1350 -560,-1550 -578,-1553 -18,-3 -26,11 -62,105 -23,59 -295,758 -605,1553 l -562,1445 -567,3 c -312,1 -567,0 -567,-2 z"
/>
<path
d="m 15690,10867 c 0,-1970 -1,-1936 56,-2153 128,-497 461,-787 1014,-885 147,-26 440,-36 605,-20 413,40 834,200 1181,447 35,25 73,44 88,44 14,0 26,-1 26,-3 0,-2 20,-94 45,-205 25,-111 45,-204 45,-207 0,-3 209,-5 465,-5 h 465 v 2400 2400 h -535 -535 l -2,-1866 -3,-1866 -115,-50 c -425,-185 -743,-252 -1088,-227 -302,21 -472,109 -562,293 -79,161 -74,11 -77,1969 l -3,1747 h -535 -535 z"
/>
<path
d="m 24785,12668 c -3,-7 -4,-1086 -3,-2398 l 3,-2385 538,-3 537,-2 v 2400 2400 h -535 c -419,0 -537,-3 -540,-12 z"
/>
<path
d="m 21660,8275 v -545 h 565 565 v 545 545 h -565 -565 z"
/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -76,6 +76,7 @@ PATCH_FILES=(
"130-atproto-ozone-enable-daemon-v2.patch" "130-atproto-ozone-enable-daemon-v2.patch"
"200-feed-generator-custom.patch" "200-feed-generator-custom.patch"
"210-bgs-since-empty-fix.patch" "210-bgs-since-empty-fix.patch"
"220-atproto-dockerfile-copy-services.patch"
) )
function at-repos-clone() { function at-repos-clone() {
@@ -120,10 +121,6 @@ function at-repos-pull() {
cd .. cd ..
fi fi
done done
# Copy feed-generator Dockerfile if missing (removed by git checkout)
if [ ! -f $d/repos/feed-generator/Dockerfile ] && [ -f $d/docker/feed/Dockerfile ];then
cp -rf $d/docker/feed/Dockerfile $d/repos/feed-generator/
fi
cd $d cd $d
} }
@@ -334,41 +331,6 @@ export const SOCIAL_APP_DOMAIN =\
}' lib/constants.ts 2>/dev/null || true }' lib/constants.ts 2>/dev/null || true
# Fix parseInt() to handle undefined by adding || '' # Fix parseInt() to handle undefined by adding || ''
sediment "s/parseInt(env('\([^']*\)'))/parseInt(env('\1') || '0')/g" lib/constants.ts 2>/dev/null || true sediment "s/parseInt(env('\([^']*\)'))/parseInt(env('\1') || '0')/g" lib/constants.ts 2>/dev/null || true
# Add next-runtime-env to package.json if missing (used by lib/constants.ts)
if ! grep -q 'next-runtime-env' package.json 2>/dev/null; then
echo "📦 Adding next-runtime-env to package.json..."
python3 -c "
import json
with open('package.json') as f:
d = json.load(f)
d.setdefault('dependencies', {})['next-runtime-env'] = '^1.6.2'
with open('package.json', 'w') as f:
json.dump(d, f, indent=2)
f.write('\n')
"
echo "✅ Added next-runtime-env"
fi
# Update @atproto/ozone in service/package.json to latest
echo "📦 Updating @atproto/ozone in service/package.json..."
local latest_ozone_ver
latest_ozone_ver=$(npm view @atproto/ozone version 2>/dev/null)
if [ -n "$latest_ozone_ver" ] && [ -f service/package.json ]; then
python3 -c "
import json, sys
ver = sys.argv[1]
with open('service/package.json') as f:
d = json.load(f)
old = d.get('dependencies', {}).get('@atproto/ozone', '')
d.setdefault('dependencies', {})['@atproto/ozone'] = ver
with open('service/package.json', 'w') as f:
json.dump(d, f, indent=2)
f.write('\n')
print(f'✅ @atproto/ozone: {old} -> {ver}')
" "$latest_ozone_ver"
fi
popd > /dev/null popd > /dev/null
} }
@@ -417,12 +379,6 @@ export const handler = async (ctx: AppContext, params: QueryParams) => {
EOF EOF
echo "✅ Created src/algos/app.ts" echo "✅ Created src/algos/app.ts"
# Restore Dockerfile (removed during patch apply to avoid conflicts)
if [ ! -f $d/repos/feed-generator/Dockerfile ] && [ -f $d/docker/feed/Dockerfile ];then
cp -rf $d/docker/feed/Dockerfile $d/repos/feed-generator/
echo "✅ Restored Dockerfile"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
} }
@@ -434,25 +390,14 @@ function at-repos-docker-verify() {
pds) check_file="/app/services/pds/index.js" ;; pds) check_file="/app/services/pds/index.js" ;;
bsky) check_file="/app/services/bsky/api.js" ;; bsky) check_file="/app/services/bsky/api.js" ;;
ozone) check_file="/app/services/ozone/api.js" ;; ozone) check_file="/app/services/ozone/api.js" ;;
bgs) check_file="/relay" ;; bgs) check_file="/bigsky" ;;
plc) check_file="/app/packages/server/dist/index.js" ;; plc) check_file="/app/packages/server/dist/index.js" ;;
*) return 0 ;; *) return 0 ;;
esac esac
local cid if docker run --rm "$image" test -f "$check_file" 2>/dev/null; then
cid=$(docker create --entrypoint "" "$image" true 2>&1)
if [ $? -ne 0 ]; then
echo " ❌ FAILED: cannot create container from $image"
echo " $cid"
return 1
fi
if docker cp "$cid:$check_file" /tmp/.docker-verify-tmp 2>/dev/null; then
rm -f /tmp/.docker-verify-tmp
docker rm "$cid" > /dev/null 2>&1
echo " ✅ Verified: $check_file exists" echo " ✅ Verified: $check_file exists"
return 0 return 0
else else
rm -f /tmp/.docker-verify-tmp
docker rm "$cid" > /dev/null 2>&1
echo " ❌ FAILED: $check_file not found in $image" echo " ❌ FAILED: $check_file not found in $image"
return 1 return 1
fi fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 536 B

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -27,7 +27,7 @@
policy: 'appVersion', policy: 'appVersion',
}, },
- icon: './assets/app-icons/ios_icon_default_next.png', - icon: './assets/app-icons/ios_icon_default_next.png',
+ icon: './assets/app-icon.png', + icon: './assets/logo.png',
userInterfaceStyle: 'automatic', userInterfaceStyle: 'automatic',
primaryColor: '#1083fe', primaryColor: '#1083fe',
newArchEnabled: false, newArchEnabled: false,
@@ -43,7 +43,7 @@
- PLATFORM === 'web' // web build doesn't like .icon files - PLATFORM === 'web' // web build doesn't like .icon files
- ? './assets/app-icons/ios_icon_default_next.png' - ? './assets/app-icons/ios_icon_default_next.png'
- : './assets/app-icons/ios_icon_default.icon', - : './assets/app-icons/ios_icon_default.icon',
+ icon: './assets/app-icon.png', + icon: './assets/logo.png',
infoPlist: { infoPlist: {
UIBackgroundModes: ['remote-notification'], UIBackgroundModes: ['remote-notification'],
NSCameraUsageDescription: NSCameraUsageDescription:
@@ -61,7 +61,7 @@
}, },
android: { android: {
- icon: './assets/app-icons/android_icon_default_next.png', - icon: './assets/app-icons/android_icon_default_next.png',
+ icon: './assets/app-icon.png', + icon: './assets/logo.png',
adaptiveIcon: { adaptiveIcon: {
foregroundImage: './assets/icon-android-foreground.png', foregroundImage: './assets/icon-android-foreground.png',
monochromeImage: './assets/icon-android-monochrome.png', monochromeImage: './assets/icon-android-monochrome.png',

View File

@@ -1,6 +1,8 @@
diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx
index 9ba067a2f..e34b9f9b0 100644
--- a/src/screens/Settings/AboutSettings.tsx --- a/src/screens/Settings/AboutSettings.tsx
+++ b/src/screens/Settings/AboutSettings.tsx +++ b/src/screens/Settings/AboutSettings.tsx
@@ -79,7 +79,7 @@ @@ -78,7 +78,7 @@ export function AboutSettingsScreen({}: Props) {
<Layout.Content> <Layout.Content>
<SettingsList.Container> <SettingsList.Container>
<SettingsList.LinkItem <SettingsList.LinkItem
@@ -9,7 +11,7 @@
label={_(msg`Terms of Service`)}> label={_(msg`Terms of Service`)}>
<SettingsList.ItemIcon icon={NewspaperIcon} /> <SettingsList.ItemIcon icon={NewspaperIcon} />
<SettingsList.ItemText> <SettingsList.ItemText>
@@ -87,7 +87,7 @@ @@ -86,7 +86,7 @@ export function AboutSettingsScreen({}: Props) {
</SettingsList.ItemText> </SettingsList.ItemText>
</SettingsList.LinkItem> </SettingsList.LinkItem>
<SettingsList.LinkItem <SettingsList.LinkItem
@@ -18,9 +20,11 @@
label={_(msg`Privacy Policy`)}> label={_(msg`Privacy Policy`)}>
<SettingsList.ItemIcon icon={NewspaperIcon} /> <SettingsList.ItemIcon icon={NewspaperIcon} />
<SettingsList.ItemText> <SettingsList.ItemText>
diff --git a/src/screens/Takendown.tsx b/src/screens/Takendown.tsx
index 660aecf1a..f19a62c0f 100644
--- a/src/screens/Takendown.tsx --- a/src/screens/Takendown.tsx
+++ b/src/screens/Takendown.tsx +++ b/src/screens/Takendown.tsx
@@ -210,10 +210,10 @@ @@ -212,10 +212,10 @@ export function Takendown() {
<Trans> <Trans>
Your account was found to be in violation of the{' '} Your account was found to be in violation of the{' '}
<SimpleInlineLinkText <SimpleInlineLinkText
@@ -34,14 +38,15 @@
</SimpleInlineLinkText> </SimpleInlineLinkText>
. You have been sent an email outlining the specific violation . You have been sent an email outlining the specific violation
and suspension period, if applicable. You can appeal this and suspension period, if applicable. You can appeal this
diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx
index a89eaadc4..71ce7c81f 100644
--- a/src/view/screens/PrivacyPolicy.tsx --- a/src/view/screens/PrivacyPolicy.tsx
+++ b/src/view/screens/PrivacyPolicy.tsx +++ b/src/view/screens/PrivacyPolicy.tsx
@@ -1,52 +1,49 @@ @@ -1,51 +1,49 @@
import React from 'react' import React from 'react'
-import {View} from 'react-native' -import {View} from 'react-native'
-import {msg} from '@lingui/core/macro' -import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react' -import {useLingui} from '@lingui/react'
-import {Trans} from '@lingui/react/macro'
-import {useFocusEffect} from '@react-navigation/native' -import {useFocusEffect} from '@react-navigation/native'
- -
-import {usePalette} from '#/lib/hooks/usePalette' -import {usePalette} from '#/lib/hooks/usePalette'
@@ -57,25 +62,26 @@
+import {ScrollView} from 'react-native' +import {ScrollView} from 'react-native'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
-import {ViewHeader} from '../com/util/ViewHeader' -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<CommonNavigatorParams, 'PrivacyPolicy'> -type Props = NativeStackScreenProps<CommonNavigatorParams, 'PrivacyPolicy'>
-export const PrivacyPolicyScreen = (_props: Props) => { -export const PrivacyPolicyScreen = (_props: Props) => {
- const pal = usePalette('default') - const pal = usePalette('default')
- const {_} = useLingui() - const {_} = useLingui()
- const setMinimalShellMode = useSetMinimalShellMode() - const setMinimalShellMode = useSetMinimalShellMode()
+export function PrivacyPolicyScreen() { -
+ useSetTitle('Privacy Policy')
+ const t = useTheme()
- useFocusEffect( - useFocusEffect(
- React.useCallback(() => { - React.useCallback(() => {
- setMinimalShellMode(false) - setMinimalShellMode(false)
- }, [setMinimalShellMode]), - }, [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 ( return (
<Layout.Screen> <Layout.Screen>
- <ViewHeader title={_(msg`Privacy Policy`)} /> - <ViewHeader title={_(msg`Privacy Policy`)} />
@@ -124,19 +130,20 @@
+ </Text> + </Text>
+ +
+ <Text style={[a.text_sm, a.mt_xl, {color: t.palette.contrast_500}]}> + <Text style={[a.text_sm, a.mt_xl, {color: t.palette.contrast_500}]}>
+ Last updated: 2026 + Last updated: 2025
+ </Text> + </Text>
</ScrollView> </ScrollView>
</Layout.Screen> </Layout.Screen>
) )
diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx
index d843c713c..c6a36268b 100644
--- a/src/view/screens/TermsOfService.tsx --- a/src/view/screens/TermsOfService.tsx
+++ b/src/view/screens/TermsOfService.tsx +++ b/src/view/screens/TermsOfService.tsx
@@ -1,50 +1,49 @@ @@ -1,49 +1,49 @@
import React from 'react' import React from 'react'
-import {View} from 'react-native' -import {View} from 'react-native'
-import {msg} from '@lingui/core/macro' -import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react' -import {useLingui} from '@lingui/react'
-import {Trans} from '@lingui/react/macro'
-import {useFocusEffect} from '@react-navigation/native' -import {useFocusEffect} from '@react-navigation/native'
- -
-import {usePalette} from '#/lib/hooks/usePalette' -import {usePalette} from '#/lib/hooks/usePalette'
@@ -152,25 +159,26 @@
+import {ScrollView} from 'react-native' +import {ScrollView} from 'react-native'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
-import {ViewHeader} from '../com/util/ViewHeader' -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<CommonNavigatorParams, 'TermsOfService'> -type Props = NativeStackScreenProps<CommonNavigatorParams, 'TermsOfService'>
-export const TermsOfServiceScreen = (_props: Props) => { -export const TermsOfServiceScreen = (_props: Props) => {
- const pal = usePalette('default') - const pal = usePalette('default')
- const setMinimalShellMode = useSetMinimalShellMode() - const setMinimalShellMode = useSetMinimalShellMode()
- const {_} = useLingui() - const {_} = useLingui()
+export function TermsOfServiceScreen() { -
+ useSetTitle('Terms of Service')
+ const t = useTheme()
- useFocusEffect( - useFocusEffect(
- React.useCallback(() => { - React.useCallback(() => {
- setMinimalShellMode(false) - setMinimalShellMode(false)
- }, [setMinimalShellMode]), - }, [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 ( return (
<Layout.Screen> <Layout.Screen>
- <ViewHeader title={_(msg`Terms of Service`)} /> - <ViewHeader title={_(msg`Terms of Service`)} />
@@ -217,7 +225,7 @@
+ </Text> + </Text>
+ +
+ <Text style={[a.text_sm, a.mt_xl, {color: t.palette.contrast_500}]}> + <Text style={[a.text_sm, a.mt_xl, {color: t.palette.contrast_500}]}>
+ Last updated: 2026 + Last updated: 2025
+ </Text> + </Text>
</ScrollView> </ScrollView>
</Layout.Screen> </Layout.Screen>

View File

@@ -1,6 +1,8 @@
diff --git a/src/view/com/posts/DiscoverFallbackHeader.tsx b/src/view/com/posts/DiscoverFallbackHeader.tsx
index e35a33aaf..a36f84ae0 100644
--- a/src/view/com/posts/DiscoverFallbackHeader.tsx --- a/src/view/com/posts/DiscoverFallbackHeader.tsx
+++ b/src/view/com/posts/DiscoverFallbackHeader.tsx +++ b/src/view/com/posts/DiscoverFallbackHeader.tsx
@@ -7,37 +7,5 @@ @@ -7,37 +7,5 @@ import {TextLink} from '../util/Link'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
export function DiscoverFallbackHeader() { export function DiscoverFallbackHeader() {
@@ -39,16 +41,18 @@
- ) - )
+ return null + return null
} }
diff --git a/src/view/com/posts/FollowingEmptyState.tsx b/src/view/com/posts/FollowingEmptyState.tsx
index 352cc1dc0..f477521af 100644
--- a/src/view/com/posts/FollowingEmptyState.tsx --- a/src/view/com/posts/FollowingEmptyState.tsx
+++ b/src/view/com/posts/FollowingEmptyState.tsx +++ b/src/view/com/posts/FollowingEmptyState.tsx
@@ -1,38 +1,15 @@ @@ -1,37 +1,14 @@
import React from 'react' import React from 'react'
import {StyleSheet, View} from 'react-native' import {StyleSheet, View} from 'react-native'
-import { -import {
- FontAwesomeIcon, - FontAwesomeIcon,
- type FontAwesomeIconStyle, - type FontAwesomeIconStyle,
-} from '@fortawesome/react-native-fontawesome' -} from '@fortawesome/react-native-fontawesome'
import {Trans} from '@lingui/react/macro' import {Trans} from '@lingui/macro'
-import {useNavigation} from '@react-navigation/native' -import {useNavigation} from '@react-navigation/native'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
@@ -63,7 +67,7 @@
const pal = usePalette('default') const pal = usePalette('default')
- const palInverted = usePalette('inverted') - const palInverted = usePalette('inverted')
- const navigation = useNavigation<NavigationProp>() - const navigation = useNavigation<NavigationProp>()
-
- const onPressFindAccounts = React.useCallback(() => { - const onPressFindAccounts = React.useCallback(() => {
- if (IS_WEB) { - if (IS_WEB) {
- navigation.navigate('Search', {}) - navigation.navigate('Search', {})
@@ -76,11 +80,10 @@
- const onPressDiscoverFeeds = React.useCallback(() => { - const onPressDiscoverFeeds = React.useCallback(() => {
- navigation.navigate('Feeds') - navigation.navigate('Feeds')
- }, [navigation]) - }, [navigation])
-
return ( return (
<View style={styles.container}> <View style={styles.container}>
<View style={styles.inner}> @@ -45,36 +22,6 @@ export function FollowingEmptyState() {
@@ -45,36 +22,6 @@
happening. happening.
</Trans> </Trans>
</Text> </Text>
@@ -117,7 +120,7 @@
</View> </View>
</View> </View>
) )
@@ -98,13 +45,4 @@ @@ -98,13 +45,4 @@ const styles = StyleSheet.create({
marginLeft: 'auto', marginLeft: 'auto',
marginRight: 'auto', marginRight: 'auto',
}, },
@@ -131,16 +134,18 @@
- borderRadius: 30, - borderRadius: 30,
- }, - },
}) })
diff --git a/src/view/com/posts/FollowingEndOfFeed.tsx b/src/view/com/posts/FollowingEndOfFeed.tsx
index e3c84d782..efb55d406 100644
--- a/src/view/com/posts/FollowingEndOfFeed.tsx --- a/src/view/com/posts/FollowingEndOfFeed.tsx
+++ b/src/view/com/posts/FollowingEndOfFeed.tsx +++ b/src/view/com/posts/FollowingEndOfFeed.tsx
@@ -1,37 +1,14 @@ @@ -1,36 +1,13 @@
import React from 'react' import React from 'react'
import {Dimensions, StyleSheet, View} from 'react-native' import {Dimensions, StyleSheet, View} from 'react-native'
-import { -import {
- FontAwesomeIcon, - FontAwesomeIcon,
- type FontAwesomeIconStyle, - type FontAwesomeIconStyle,
-} from '@fortawesome/react-native-fontawesome' -} from '@fortawesome/react-native-fontawesome'
import {Trans} from '@lingui/react/macro' import {Trans} from '@lingui/macro'
-import {useNavigation} from '@react-navigation/native' -import {useNavigation} from '@react-navigation/native'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
@@ -154,7 +159,7 @@
const pal = usePalette('default') const pal = usePalette('default')
- const palInverted = usePalette('inverted') - const palInverted = usePalette('inverted')
- const navigation = useNavigation<NavigationProp>() - const navigation = useNavigation<NavigationProp>()
-
- const onPressFindAccounts = React.useCallback(() => { - const onPressFindAccounts = React.useCallback(() => {
- if (IS_WEB) { - if (IS_WEB) {
- navigation.navigate('Search', {}) - navigation.navigate('Search', {})
@@ -167,11 +172,10 @@
- const onPressDiscoverFeeds = React.useCallback(() => { - const onPressDiscoverFeeds = React.useCallback(() => {
- navigation.navigate('Feeds') - navigation.navigate('Feeds')
- }, [navigation]) - }, [navigation])
-
return ( return (
<View <View
style={[ @@ -41,41 +18,8 @@ export function FollowingEndOfFeed() {
@@ -41,41 +18,8 @@
]}> ]}>
<View style={styles.inner}> <View style={styles.inner}>
<Text type="xl-medium" style={[s.textCenter, pal.text]}> <Text type="xl-medium" style={[s.textCenter, pal.text]}>
@@ -179,8 +183,7 @@
- You've reached the end of your feed! Find some more accounts to - You've reached the end of your feed! Find some more accounts to
- follow. - follow.
- </Trans> - </Trans>
+ <Trans>You've reached the end of your feed!</Trans> - </Text>
</Text>
- <Button - <Button
- type="inverted" - type="inverted"
- style={styles.emptyBtn} - style={styles.emptyBtn}
@@ -197,7 +200,8 @@
- -
- <Text type="xl-medium" style={[s.textCenter, pal.text, s.mt20]}> - <Text type="xl-medium" style={[s.textCenter, pal.text, s.mt20]}>
- <Trans>You can also discover new Custom Feeds to follow.</Trans> - <Trans>You can also discover new Custom Feeds to follow.</Trans>
- </Text> + <Trans>You've reached the end of your feed!</Trans>
</Text>
- <Button - <Button
- type="inverted" - type="inverted"
- style={[styles.emptyBtn, s.mt10]} - style={[styles.emptyBtn, s.mt10]}
@@ -214,7 +218,7 @@
</View> </View>
</View> </View>
) )
@@ -93,13 +37,4 @@ @@ -93,13 +37,4 @@ const styles = StyleSheet.create({
width: '100%', width: '100%',
maxWidth: 460, maxWidth: 460,
}, },
@@ -228,9 +232,11 @@
- borderRadius: 30, - borderRadius: 30,
- }, - },
}) })
diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx
index 4f25468c9..a72a10b80 100644
--- a/src/view/com/posts/PostFeed.tsx --- a/src/view/com/posts/PostFeed.tsx
+++ b/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx
@@ -765,7 +765,7 @@ @@ -766,7 +766,7 @@ let PostFeed = ({
} else if (row.type === 'feedShutdownMsg') { } else if (row.type === 'feedShutdownMsg') {
return <FeedShutdownMsg feedUri={feedUriOrActorDid} /> return <FeedShutdownMsg feedUri={feedUriOrActorDid} />
} else if (row.type === 'interstitialFollows') { } else if (row.type === 'interstitialFollows') {

View File

@@ -1,14 +1,5 @@
--- a/src/env/common.ts --- a/src/env/common.ts
+++ b/src/env/common.ts +++ b/src/env/common.ts
@@ -88,7 +88,7 @@
* Metrics API host
*/
export const METRICS_API_HOST: string =
- process.env.EXPO_PUBLIC_METRICS_API_HOST || 'https://events.bsky.app'
+ process.env.EXPO_PUBLIC_METRICS_API_HOST || ''
/**
* Growthbook API host
@@ -128,9 +128,7 @@ @@ -128,9 +128,7 @@
*/ */
export const GEOLOCATION_DEV_URL = process.env.GEOLOCATION_DEV_URL export const GEOLOCATION_DEV_URL = process.env.GEOLOCATION_DEV_URL
@@ -31,11 +22,3 @@
/** /**
* URLs for the app-config web worker. Can be a * URLs for the app-config web worker. Can be a
@@ -148,6 +144,4 @@
*/
export const APP_CONFIG_DEV_URL = process.env.APP_CONFIG_DEV_URL
export const APP_CONFIG_PROD_URL = `https://app-config.workers.bsky.app`
-export const APP_CONFIG_URL = IS_DEV
- ? (APP_CONFIG_DEV_URL ?? APP_CONFIG_PROD_URL)
- : APP_CONFIG_PROD_URL
+export const APP_CONFIG_URL = null

View File

@@ -7,21 +7,22 @@
import { import {
type AppBskyActorDefs, type AppBskyActorDefs,
moderateProfile, moderateProfile,
@@ -11,7 +11,10 @@ @@ -9,8 +9,10 @@
} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
+import {useQuery} from '@tanstack/react-query' +import {useQuery} from '@tanstack/react-query'
+
import {useHaptics} from '#/lib/haptics' import {useHaptics} from '#/lib/haptics'
+import {useOpenLink} from '#/lib/hooks/useOpenLink' +import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {logger} from '#/logger' import {logger} from '#/logger'
@@ -47,6 +50,103 @@ @@ -45,6 +47,103 @@
import {ProfileHeaderMetrics} from './Metrics'
import {ProfileHeaderShell} from './Shell' import {ProfileHeaderShell} from './Shell'
import {ProfileHeaderSuggestedFollows} from './SuggestedFollows' import {ProfileHeaderSuggestedFollows} from './SuggestedFollows'
+
+const SERVICE_FAVICONS: Record<string, any> = { +const SERVICE_FAVICONS: Record<string, any> = {
+ 'syui.ai': require('../../../../assets/favicons/syui.ai.png'), + 'syui.ai': require('../../../../assets/favicons/syui.ai.png'),
+ 'bsky.app': require('../../../../assets/favicons/bsky.app.png'), + 'bsky.app': require('../../../../assets/favicons/bsky.app.png'),
@@ -118,11 +119,10 @@
+ </View> + </View>
+ ) + )
+} +}
+
interface Props { interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed profile: AppBskyActorDefs.ProfileViewDetailed
descriptionRT: RichTextAPI | null @@ -151,6 +250,7 @@
@@ -152,6 +252,7 @@
{!isPlaceholderProfile && !isBlockedUser && ( {!isPlaceholderProfile && !isBlockedUser && (
<View style={a.gap_md}> <View style={a.gap_md}>
<ProfileHeaderMetrics profile={profile} /> <ProfileHeaderMetrics profile={profile} />

View File

@@ -1,6 +1,6 @@
--- a/src/screens/Profile/Header/ProfileHeaderStandard.tsx --- a/src/screens/Profile/Header/ProfileHeaderStandard.tsx
+++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx +++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx
@@ -48,6 +48,7 @@ @@ -46,6 +46,7 @@
import {ProfileHeaderHandle} from './Handle' import {ProfileHeaderHandle} from './Handle'
import {ProfileHeaderMetrics} from './Metrics' import {ProfileHeaderMetrics} from './Metrics'
import {ProfileHeaderShell} from './Shell' import {ProfileHeaderShell} from './Shell'
@@ -8,7 +8,7 @@
import {ProfileHeaderSuggestedFollows} from './SuggestedFollows' import {ProfileHeaderSuggestedFollows} from './SuggestedFollows'
const SERVICE_FAVICONS: Record<string, any> = { const SERVICE_FAVICONS: Record<string, any> = {
@@ -253,6 +254,7 @@ @@ -251,6 +252,7 @@
<View style={a.gap_md}> <View style={a.gap_md}>
<ProfileHeaderMetrics profile={profile} /> <ProfileHeaderMetrics profile={profile} />
<ProfileServiceLinks profile={profile} /> <ProfileServiceLinks profile={profile} />

View File

@@ -5,10 +5,10 @@
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
import {Image} from 'expo-image' import {Image} from 'expo-image'
+import {useVideoPlayer, VideoView} from 'expo-video' +import {useVideoPlayer, VideoView} from 'expo-video'
import {msg} from '@lingui/core/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -15,10 +16,13 @@ @@ -14,10 +15,13 @@
import splashImagePointer from '../../../../assets/splash/illustration-mobile.png' import splashImagePointer from '../../../../assets/splash/illustration-mobile.png'
// @ts-ignore // @ts-ignore
import darkSplashImagePointer from '../../../../assets/splash/illustration-mobile-dark.png' import darkSplashImagePointer from '../../../../assets/splash/illustration-mobile-dark.png'
@@ -22,7 +22,7 @@
export const SplashScreen = ({ export const SplashScreen = ({
onPressSignin, onPressSignin,
@@ -53,13 +57,30 @@ @@ -52,13 +56,30 @@
} }
}, [t, isDarkMode]) }, [t, isDarkMode])

View File

@@ -1,40 +0,0 @@
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -717,16 +717,7 @@
post.shortenedGraphemeLength > 0 || post.embed.media || post.embed.link,
)
- // Show discard prompt if there's content AND either:
- // - No draft is loaded (new composition)
- // - Draft is loaded but has been modified
- if (hasContent && (!composerState.draftId || composerState.isDirty)) {
- closeAllDialogs()
- Keyboard.dismiss()
- discardPromptControl.open()
- } else {
- onClose()
- }
+ onClose()
}, [
thread,
composerState.draftId,
@@ -1551,18 +1542,7 @@
</>
) : (
<>
- {!isReply && (
- <DraftsButton
- onSelectDraft={onSelectDraft}
- onSaveDraft={onSaveDraft}
- onDiscard={onDiscard}
- isEmpty={isEmpty}
- isDirty={isDirty}
- isEditingDraft={isEditingDraft}
- canSaveDraft={canSaveDraft}
- textLength={textLength}
- />
- )}
+ {/* DraftsButton removed */}
<Button
testID="composerPublishBtn"
label={

View File

@@ -1,55 +0,0 @@
diff --git a/src/features/liveEvents/context.tsx b/src/features/liveEvents/context.tsx
index 3de2534a8..e11955f57 100644
--- a/src/features/liveEvents/context.tsx
+++ b/src/features/liveEvents/context.tsx
@@ -24,6 +24,7 @@ export const DEFAULT_LIVE_EVENTS = {
async function fetchLiveEvents(): Promise<LiveEventsWorkerResponse | null> {
try {
+ if (!LIVE_EVENTS_URL) return null
const res = await fetch(`${LIVE_EVENTS_URL}/config`)
if (!res.ok) return null
const data = await res.json()
diff --git a/src/geolocation/const.ts b/src/geolocation/const.ts
index 653e829ba..4992cc870 100644
--- a/src/geolocation/const.ts
+++ b/src/geolocation/const.ts
@@ -1,7 +1,9 @@
import {GEOLOCATION_URL} from '#/env'
import {type Geolocation} from '#/geolocation/types'
-export const GEOLOCATION_SERVICE_URL = `${GEOLOCATION_URL}/geolocation`
+export const GEOLOCATION_SERVICE_URL = GEOLOCATION_URL
+ ? `${GEOLOCATION_URL}/geolocation`
+ : null
/**
* Default geolocation config.
diff --git a/src/geolocation/service.ts b/src/geolocation/service.ts
index 2d9285b67..c7c3d02c0 100644
--- a/src/geolocation/service.ts
+++ b/src/geolocation/service.ts
@@ -26,9 +26,10 @@ const onGeolocationServiceResponseUpdate = (
}
async function fetchGeolocationServiceData(
- url: string,
+ url: string | null,
): Promise<Geolocation | undefined> {
if (debug.enabled) return debug.resolve(debug.geolocation)
+ if (!url) throw new Error('geolocation service disabled')
const res = await fetch(url)
if (!res.ok) {
throw new Error(`fetchGeolocationServiceData failed ${res.status}`)
diff --git a/src/state/appConfig.tsx b/src/state/appConfig.tsx
index 67b0e553e..9eacf7ead 100644
--- a/src/state/appConfig.tsx
+++ b/src/state/appConfig.tsx
@@ -30,6 +30,7 @@ let fetchAppConfigPromise: Promise<AppConfigResponse> | undefined
async function fetchAppConfig(): Promise<AppConfigResponse | null> {
try {
+ if (!APP_CONFIG_URL) return null
if (!fetchAppConfigPromise) {
fetchAppConfigPromise = (async () => {
const r = await fetch(`${APP_CONFIG_URL}/config`)

View File

@@ -27,7 +27,7 @@ export function LicenseScreen() {
<Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>MIT License</Text> <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>MIT License</Text>
<Text style={[a.mb_md, {fontFamily: 'monospace'}]}> <Text style={[a.mb_md, {fontFamily: 'monospace'}]}>
Copyright (c) 2022-2026 Bluesky PBC Copyright (c) 2022-2025 Bluesky PBC
</Text> </Text>
<Text style={[a.mb_md]}> <Text style={[a.mb_md]}>

View File

@@ -52,8 +52,6 @@ PATCH_FILES_IOS=(
"042-social-app-ios-at-links.patch" "042-social-app-ios-at-links.patch"
"043-social-app-ios-rightnav-links.patch" "043-social-app-ios-rightnav-links.patch"
"044-social-app-ios-splash-video.patch" "044-social-app-ios-splash-video.patch"
"045-social-app-ios-composer-cancel.patch"
"046-social-app-ios-null-url-guards.patch"
) )
function ios-env() { function ios-env() {
@@ -175,17 +173,6 @@ function ios-copy-new-files() {
echo "✅ Copied all assets (including logo.png, app-icons)" echo "✅ Copied all assets (including logo.png, app-icons)"
fi fi
# Generate app-icon.png (logo on #333 background) for app icon
if [ -f "$d/ios/assets/logo.png" ]; then
if command -v magick >/dev/null 2>&1; then
magick -size 1024x1024 "xc:#333333" "$d/ios/assets/logo.png" -gravity center -composite "$target_dir/assets/app-icon.png"
echo "✅ Generated app-icon.png (logo + #333 bg)"
else
echo "⚠️ ImageMagick not found, copying logo.png as app-icon.png fallback"
cp "$d/ios/assets/logo.png" "$target_dir/assets/app-icon.png"
fi
fi
# Copy License.tsx # Copy License.tsx
if [ -f "$patching_dir/License.tsx" ]; then if [ -f "$patching_dir/License.tsx" ]; then
mkdir -p "$target_dir/src/view/screens" mkdir -p "$target_dir/src/view/screens"

View File

@@ -0,0 +1,30 @@
--- a/services/pds/Dockerfile
+++ b/services/pds/Dockerfile
@@ -46,6 +46,7 @@
COPY ./packages/ws-client ./packages/ws-client
COPY ./packages/xrpc-server ./packages/xrpc-server
COPY ./packages/xrpc ./packages/xrpc
+COPY ./services/pds ./services/pds
# install all deps
RUN PUPPETEER_SKIP_DOWNLOAD=true pnpm install --frozen-lockfile
--- a/services/bsky/Dockerfile
+++ b/services/bsky/Dockerfile
@@ -45,6 +45,7 @@
COPY ./packages/ws-client ./packages/ws-client
COPY ./packages/xrpc-server ./packages/xrpc-server
COPY ./packages/xrpc ./packages/xrpc
+COPY ./services/bsky ./services/bsky
# install all deps
RUN PUPPETEER_SKIP_DOWNLOAD=true pnpm install --frozen-lockfile
--- a/services/ozone/Dockerfile
+++ b/services/ozone/Dockerfile
@@ -46,6 +46,7 @@
COPY ./packages/ws-client ./packages/ws-client
COPY ./packages/xrpc ./packages/xrpc
COPY ./packages/xrpc-server ./packages/xrpc-server
+COPY ./services/ozone ./services/ozone
# install all deps
RUN PUPPETEER_SKIP_DOWNLOAD=true pnpm install --frozen-lockfile