add ios social-app
68
install.zsh
@@ -1,5 +1,23 @@
|
|||||||
#!/bin/zsh
|
#!/bin/zsh
|
||||||
|
|
||||||
|
# Sed compatibility wrapper
|
||||||
|
function sediment() {
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
sed -i '' "$@"
|
||||||
|
else
|
||||||
|
sed -i "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Patch compatibility wrapper
|
||||||
|
function patchment() {
|
||||||
|
# -f : Force. Do not ask questions. (Standard in GNU and BSD patch)
|
||||||
|
# -N : Ignore patches that seem to be reversed or already applied (Forward)
|
||||||
|
# But we control these flags in the caller.
|
||||||
|
patch "$@"
|
||||||
|
}
|
||||||
|
|
||||||
function at-repos-env() {
|
function at-repos-env() {
|
||||||
APP_PASSWORD=xxx
|
APP_PASSWORD=xxx
|
||||||
host=syu.is
|
host=syu.is
|
||||||
@@ -102,26 +120,23 @@ function at-repos-social-app-avatar-write() {
|
|||||||
did_admin=did:plc:6qyecktefllvenje24fcxnie
|
did_admin=did:plc:6qyecktefllvenje24fcxnie
|
||||||
dt=$d/repos/social-app/src
|
dt=$d/repos/social-app/src
|
||||||
cd $dt
|
cd $dt
|
||||||
grep -R syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/syu.is/${host}/g"
|
grep -R syu.is .|cut -d : -f 1|sort -u|xargs sediment "s/syu.is/${host}/g"
|
||||||
grep -R web.syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/web.syu.is/web.${host}/g"
|
grep -R web.syu.is .|cut -d : -f 1|sort -u|xargs sediment "s/web.syu.is/web.${host}/g"
|
||||||
f=$dt/lib/constants.ts
|
f=$dt/lib/constants.ts
|
||||||
sed -i "s#export const BSKY_SERVICE = 'https://bsky.social'#export const BSKY_SERVICE = 'https://${host}'#g" $f
|
sediment "s#export const BSKY_SERVICE = 'https://bsky.social'#export const BSKY_SERVICE = 'https://${host}'#g" $f
|
||||||
sed -i "s#export const BSKY_SERVICE_DID = 'did:web:bsky.social'#export const BSKY_SERVICE_DID = 'did:web:${host}'#g" $f
|
sediment "s#export const BSKY_SERVICE_DID = 'did:web:bsky.social'#export const BSKY_SERVICE_DID = 'did:web:${host}'#g" $f
|
||||||
sed -i "s#export const PUBLIC_BSKY_SERVICE = 'https://public.api.bsky.app'#export const PUBLIC_BSKY_SERVICE = 'https://bsky.${host}'#g" $f
|
sediment "s#export const PUBLIC_BSKY_SERVICE = 'https://public.api.bsky.app'#export const PUBLIC_BSKY_SERVICE = 'https://bsky.${host}'#g" $f
|
||||||
sed -i "s#export const PUBLIC_APPVIEW = 'https://api.bsky.app'#export const PUBLIC_APPVIEW = 'https://bsky.${host}'#g" $f
|
sediment "s#export const PUBLIC_APPVIEW = 'https://api.bsky.app'#export const PUBLIC_APPVIEW = 'https://bsky.${host}'#g" $f
|
||||||
sed -i "s#export const PUBLIC_APPVIEW_DID = 'did:web:api.bsky.app'#export const PUBLIC_APPVIEW_DID = 'did:web:bsky.${host}'#g" $f
|
sediment "s#export const PUBLIC_APPVIEW_DID = 'did:web:api.bsky.app'#export const PUBLIC_APPVIEW_DID = 'did:web:bsky.${host}'#g" $f
|
||||||
|
|
||||||
f=$dt/view/icons/Logotype.tsx
|
|
||||||
o=$d/icons/Logotype.tsx
|
|
||||||
cp -rf $o $f
|
|
||||||
f=$dt/view/com/util/UserAvatar.tsx
|
f=$dt/view/com/util/UserAvatar.tsx
|
||||||
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/view/com/util/UserAvatar.tsx -o $f
|
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/view/com/util/UserAvatar.tsx -o $f
|
||||||
sed -i "s#/img/avatar/plain/#https://cdn.web.syu.is/img/avatar/plain/#g" $f
|
sediment "s#/img/avatar/plain/#https://cdn.web.syu.is/img/avatar/plain/#g" $f
|
||||||
sed -i "s#/img/avatar_thumbnail/plain/#https://bsky.${host}/img/avatar/plain/#g" $f
|
sediment "s#/img/avatar_thumbnail/plain/#https://bsky.${host}/img/avatar/plain/#g" $f
|
||||||
sed -i "s#source={{uri: avatar}}#source={{ uri: hackModifyThumbnailPath(avatar, 1 > 0), }}#g" $f
|
sediment "s#source={{uri: avatar}}#source={{ uri: hackModifyThumbnailPath(avatar, 1 > 0), }}#g" $f
|
||||||
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/lib/strings/url-helpers.ts -o $dt/lib/strings/url-helpers.ts
|
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/lib/strings/url-helpers.ts -o $dt/lib/strings/url-helpers.ts
|
||||||
sed -i "s#https://go.web.syu.is/redirect?u=\${encodeURIComponent(url)}#\${url}#g" $dt/lib/strings/url-helpers.ts
|
sediment "s#https://go.web.syu.is/redirect?u=\${encodeURIComponent(url)}#\${url}#g" $dt/lib/strings/url-helpers.ts
|
||||||
grep -R $did_admin .|cut -d : -f 1|sort -u|xargs sed -i "s/${did_admin}/${did}/g"
|
grep -R $did_admin .|cut -d : -f 1|sort -u|xargs sediment "s/${did_admin}/${did}/g"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -139,7 +154,8 @@ function apply-patch() {
|
|||||||
pushd ${target_dir} > /dev/null
|
pushd ${target_dir} > /dev/null
|
||||||
|
|
||||||
# Check if patch is already applied (reverse dry-run succeeds)
|
# Check if patch is already applied (reverse dry-run succeeds)
|
||||||
if patch --dry-run -p1 -R < ${patch_file} > /dev/null 2>&1; then
|
# Use -f to force dry-run to fail instead of asking questions if unapplied
|
||||||
|
if patch -f --dry-run -p1 -R < ${patch_file} > /dev/null 2>&1; then
|
||||||
echo "✅ Already applied - skipping"
|
echo "✅ Already applied - skipping"
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
echo ""
|
echo ""
|
||||||
@@ -147,9 +163,9 @@ function apply-patch() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if patch can be applied (forward dry-run succeeds)
|
# Check if patch can be applied (forward dry-run succeeds)
|
||||||
if patch --dry-run -p1 < ${patch_file} > /dev/null 2>&1; then
|
if patch -f --dry-run -p1 < ${patch_file} > /dev/null 2>&1; then
|
||||||
echo "🔧 Applying patch..."
|
echo "🔧 Applying patch..."
|
||||||
if patch -p1 < ${patch_file}; then
|
if patch -f -p1 < ${patch_file}; then
|
||||||
echo "✅ Applied successfully"
|
echo "✅ Applied successfully"
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
echo ""
|
echo ""
|
||||||
@@ -284,29 +300,29 @@ function at-repos-ozone-patch() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Replace process.env with env()
|
# Replace process.env with env()
|
||||||
sed -i 's/process\.env\.\(NEXT_PUBLIC_[A-Z_]*\)/env('\''\1'\'')/g' lib/constants.ts 2>/dev/null || true
|
sediment 's/process\.env\.\(NEXT_PUBLIC_[A-Z_]*\)/env('\''\1'\'')/g' lib/constants.ts 2>/dev/null || true
|
||||||
sed -i 's/process\.env\.NODE_ENV/env('\''NODE_ENV'\'')/g' lib/constants.ts 2>/dev/null || true
|
sediment 's/process\.env\.NODE_ENV/env('\''NODE_ENV'\'')/g' lib/constants.ts 2>/dev/null || true
|
||||||
# Add missing SOCIAL_APP_DOMAIN constant after SOCIAL_APP_URL
|
# Add missing SOCIAL_APP_DOMAIN constant after SOCIAL_APP_URL
|
||||||
sed -i '/^export const SOCIAL_APP_URL =/,/^$/{ /^$/a\
|
sediment '/^export const SOCIAL_APP_URL =/,/^$/{ /^$/a\
|
||||||
export const SOCIAL_APP_DOMAIN =\
|
export const SOCIAL_APP_DOMAIN =\
|
||||||
env('\''NEXT_PUBLIC_SOCIAL_APP_DOMAIN'\'') || '\''bsky.app'\''\
|
env('\''NEXT_PUBLIC_SOCIAL_APP_DOMAIN'\'') || '\''bsky.app'\''\
|
||||||
|
|
||||||
}' lib/constants.ts 2>/dev/null || true
|
}' lib/constants.ts 2>/dev/null || true
|
||||||
# Fix multiline process.env patterns
|
# Fix multiline process.env patterns
|
||||||
sed -i '/^export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/,/^ : 7$/ {
|
sediment '/^export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/,/^ : 7$/ {
|
||||||
s/^export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = env('\''NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS'\'')/
|
s/^export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = env('\''NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS'\'')/
|
||||||
/^ \.NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS$/d
|
/^ \.NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS$/d
|
||||||
}' lib/constants.ts 2>/dev/null || true
|
}' lib/constants.ts 2>/dev/null || true
|
||||||
sed -i '/^export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/,/^ : 30$/ {
|
sediment '/^export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/,/^ : 30$/ {
|
||||||
s/^export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = env('\''NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS'\'')/
|
s/^export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process\.env$/export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = env('\''NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS'\'')/
|
||||||
/^ \.NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS$/d
|
/^ \.NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS$/d
|
||||||
}' lib/constants.ts 2>/dev/null || true
|
}' lib/constants.ts 2>/dev/null || true
|
||||||
sed -i '/^export const HIGH_PROFILE_FOLLOWER_THRESHOLD = process\.env$/,/^ : Infinity$/ {
|
sediment '/^export const HIGH_PROFILE_FOLLOWER_THRESHOLD = process\.env$/,/^ : Infinity$/ {
|
||||||
s/^export const HIGH_PROFILE_FOLLOWER_THRESHOLD = process\.env$/export const HIGH_PROFILE_FOLLOWER_THRESHOLD = env('\''NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD'\'')/
|
s/^export const HIGH_PROFILE_FOLLOWER_THRESHOLD = process\.env$/export const HIGH_PROFILE_FOLLOWER_THRESHOLD = env('\''NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD'\'')/
|
||||||
/^ \.NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD$/d
|
/^ \.NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD$/d
|
||||||
}' 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 || ''
|
||||||
sed -i "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
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
50
ios/README.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
今回の./ios (social-app)開発の要点をまとめます。
|
||||||
|
|
||||||
|
1. MITのライセンスを遵守すること、iosアプリとして出品しても問題ないようにすること
|
||||||
|
https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/LICENSE
|
||||||
|
|
||||||
|
2. "Bluesky"という名称を使用しないこと。アイコンの変更。リンクの変更
|
||||||
|
|
||||||
|
3. selfhostでも動くこと。本来のsocial-appは動きませんので、これは不便なのでiosアプリに出品することにしました。なお、これはすでにpatchで実現しています。
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./install.zsh pull
|
||||||
|
$ ./install.zsh patch
|
||||||
|
$ ./ios/setup.zsh
|
||||||
|
$ ./ios/preview.zsh
|
||||||
|
```
|
||||||
|
|
||||||
|
## issue
|
||||||
|
|
||||||
|
1. 最初の画面で、webではちゃんと私のサイトのロゴが表示されていますが、ios モバイル版では、未だにBluesky (icon)です。アカウント作成、サインイン、が表示されています。
|
||||||
|
|
||||||
|
2. 上のメニューバーにもBlueskyのロゴが表示されています。
|
||||||
|
|
||||||
|
3. サインイン後のホスティングプロバイダーで中身はsyu.isですが、表示は"Bluesky Social"になっています。これをsyu.isに変更してください。ios/webでコードは異なります。
|
||||||
|
|
||||||
|
4. チャット機能
|
||||||
|
チャット機能は今回無効化するので、下メニューバーやプロフィール、設定画面に表示しないでください。
|
||||||
|
|
||||||
|
5. 設定ボタン(左カラム)を押すと、フィードバック、ヘルプが表示されますが、非表示にしてください。
|
||||||
|
|
||||||
|
6. 設定ボタン(左カラム)を押すと、フィード、リスト、保存済みの項目がありますが、これを削除してください。
|
||||||
|
|
||||||
|
7. 設定ボタン(左カラム)を押すと、下に利用規約、プライバシーポリシーが表示されますが、リンクがbsky.socialです。
|
||||||
|
- /about/support/privacy-policy
|
||||||
|
- /about/support/tos
|
||||||
|
このページを独自に作って表示してください。
|
||||||
|
|
||||||
|
8. LOG 09:52:20 (logger) Poll latest failed {
|
||||||
|
"feed": "following",
|
||||||
|
"message": "Error: Could not find repo: did:plc:z72i7hdynmk6r22z27h6tvur"
|
||||||
|
}
|
||||||
|
|
||||||
|
## 壊れた実装
|
||||||
|
|
||||||
|
1. ログイン後のメイン画面、"Following"の項目(フィード)に表示されるものをシンプルにします。表示するのはFollowingのみで、以下のものを削除してください。
|
||||||
|
- おすすめの削除
|
||||||
|
- Discoverの削除
|
||||||
|
- アカウントを探すの削除
|
||||||
|
|
||||||
|
2. 誕生日を入力する画面を省略。配布国は限定します。
|
||||||
BIN
ios/app-icons/android_icon_core_aurora.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_bonfire.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_classic.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_flat_black.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_flat_blue.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_flat_white.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_midnight.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_sunrise.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_core_sunset.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_default_next.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_legacy_dark.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/android_icon_legacy_light.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_aurora.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_bonfire.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_classic.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_flat_black.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_flat_blue.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_flat_white.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_midnight.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_sunrise.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_core_sunset.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_default.icon/Assets/iOS transparent.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
31
ios/app-icons/ios_icon_default.icon/icon.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"fill" : {
|
||||||
|
"automatic-gradient" : "srgb:0.00000,0.41569,1.00000,1.00000"
|
||||||
|
},
|
||||||
|
"groups" : [
|
||||||
|
{
|
||||||
|
"layers" : [
|
||||||
|
{
|
||||||
|
"fill" : "none",
|
||||||
|
"glass" : false,
|
||||||
|
"image-name" : "iOS transparent.png",
|
||||||
|
"name" : "iOS transparent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shadow" : {
|
||||||
|
"kind" : "neutral",
|
||||||
|
"opacity" : 0.5
|
||||||
|
},
|
||||||
|
"translucency" : {
|
||||||
|
"enabled" : true,
|
||||||
|
"value" : 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"supported-platforms" : {
|
||||||
|
"circles" : [
|
||||||
|
"watchOS"
|
||||||
|
],
|
||||||
|
"squares" : "shared"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
ios/app-icons/ios_icon_default.icon/icon.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
ios/app-icons/ios_icon_default_next.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_legacy_dark.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
ios/app-icons/ios_icon_legacy_light.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
@@ -3,7 +3,6 @@ module.exports = {
|
|||||||
name: 'Aiat',
|
name: 'Aiat',
|
||||||
slug: 'aiat',
|
slug: 'aiat',
|
||||||
scheme: 'aiat',
|
scheme: 'aiat',
|
||||||
owner: 'syui', // Your Expo account
|
owner: 'syui',
|
||||||
bundleIdentifier: 'ai.syui.at',
|
bundleIdentifier: 'ai.syui.at'
|
||||||
// Icon will be set separately
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
#!/bin/zsh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
d=~/ai/at/repos/social-app
|
|
||||||
APP_NAME=Aiat
|
|
||||||
PKG=aiat
|
|
||||||
TEAM_NAME=
|
|
||||||
TEAM_ID=
|
|
||||||
CERT="Apple Distribution: ${TEAM_NAME} (${TEAM_ID})"
|
|
||||||
MAIL=user@example.com
|
|
||||||
KEY_CHAIN=EXAMPLE
|
|
||||||
|
|
||||||
cd $d
|
|
||||||
# npx expo prebuild --clean
|
|
||||||
# cd ios && pod install && cd ..
|
|
||||||
|
|
||||||
## アーカイブ
|
|
||||||
xcodebuild -workspace ios/${PKG}.xcworkspace \
|
|
||||||
-scheme ${PKG} \
|
|
||||||
-configuration Release \
|
|
||||||
-archivePath build/${APP_NAME}.xcarchive \
|
|
||||||
-allowProvisioningUpdates \
|
|
||||||
archive
|
|
||||||
|
|
||||||
cd build
|
|
||||||
|
|
||||||
# IPA作成
|
|
||||||
rm -rf Payload ${APP_NAME}.ipa
|
|
||||||
mkdir -p Payload
|
|
||||||
cp -R ${APP_NAME}.xcarchive/Products/Applications/${PKG}.app Payload/
|
|
||||||
cp ../store.mobileprovision Payload/${PKG}.app/embedded.mobileprovision
|
|
||||||
|
|
||||||
# entitlements抽出
|
|
||||||
security cms -D -i Payload/${PKG}.app/embedded.mobileprovision > /tmp/profile.plist
|
|
||||||
/usr/libexec/PlistBuddy -x -c "Print :Entitlements" /tmp/profile.plist > /tmp/entitlements.plist
|
|
||||||
|
|
||||||
codesign -f -s "$CERT" Payload/${PKG}.app/Frameworks/*.framework 2>/dev/null || true
|
|
||||||
codesign -f -s "$CERT" --entitlements /tmp/entitlements.plist Payload/${PKG}.app
|
|
||||||
|
|
||||||
zip -r ${APP_NAME}.ipa Payload
|
|
||||||
|
|
||||||
xcrun altool --upload-app -f ${APP_NAME}.ipa -t ios -u "${MAIL}" -p "@keychain:${KEY_CHAIN}"
|
|
||||||
|
|
||||||
echo "Upload complete"
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#!/bin/zsh
|
|
||||||
|
|
||||||
if [ "$1" = "social-app-custom" ];then
|
|
||||||
at-social-app-custom-pages
|
|
||||||
at-social-app-custom-screens
|
|
||||||
at-social-app-aiat-config
|
|
||||||
at-social-app-aiat-logo
|
|
||||||
at-origin-social-app
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
function at-social-app-custom-pages() {
|
|
||||||
d_=$d/repos/social-app
|
|
||||||
custom=$d/social-app-custom
|
|
||||||
|
|
||||||
echo "copying custom components to social-app"
|
|
||||||
|
|
||||||
# Create components directory if not exists
|
|
||||||
mkdir -p ${d_}/src/components/custom
|
|
||||||
|
|
||||||
# Copy custom components
|
|
||||||
cp ${custom}/PrivacyContent.tsx ${d_}/src/components/custom/
|
|
||||||
cp ${custom}/AppInfo.tsx ${d_}/src/components/custom/
|
|
||||||
|
|
||||||
echo "custom components copied successfully"
|
|
||||||
}
|
|
||||||
|
|
||||||
function at-social-app-aiat-config() {
|
|
||||||
d_=$d/repos/social-app
|
|
||||||
custom=$d/social-app-custom
|
|
||||||
|
|
||||||
echo "applying Aiat configuration"
|
|
||||||
|
|
||||||
# Update app.config.js
|
|
||||||
cd ${d_}
|
|
||||||
|
|
||||||
# Backup original
|
|
||||||
cp app.config.js app.config.js.orig
|
|
||||||
|
|
||||||
# Apply changes using sed
|
|
||||||
sed -i "s/name: 'Bluesky'/name: 'Aiat'/g" app.config.js
|
|
||||||
sed -i "s/slug: 'bluesky'/slug: 'aiat'/g" app.config.js
|
|
||||||
sed -i "s/scheme: 'bluesky'/scheme: 'aiat'/g" app.config.js
|
|
||||||
sed -i "s/owner: 'blueskysocial'/owner: 'syui'/g" app.config.js
|
|
||||||
sed -i "s/bundleIdentifier: 'xyz.blueskyweb.app'/bundleIdentifier: 'ai.syui.at'/g" app.config.js
|
|
||||||
|
|
||||||
# Update package.json name
|
|
||||||
sed -i 's/"name": "bsky.app"/"name": "aiat"/g' package.json
|
|
||||||
|
|
||||||
echo "Aiat configuration applied"
|
|
||||||
}
|
|
||||||
|
|
||||||
function at-social-app-aiat-logo() {
|
|
||||||
d_=$d/repos/social-app
|
|
||||||
custom=$d/social-app-custom
|
|
||||||
|
|
||||||
echo "applying Aiat logo"
|
|
||||||
|
|
||||||
# Create logo directory if not exists
|
|
||||||
mkdir -p ${custom}/assets
|
|
||||||
|
|
||||||
# Copy logo if exists in custom folder
|
|
||||||
if [ -f ${custom}/assets/icon.png ]; then
|
|
||||||
cp ${custom}/assets/icon.png ${d_}/assets/app-icons/ios_icon_default_next.png
|
|
||||||
echo "Aiat logo applied"
|
|
||||||
else
|
|
||||||
echo "Warning: Logo file not found at ${custom}/assets/icon.png"
|
|
||||||
echo "Please add your logo file there"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function at-social-app-custom-screens() {
|
|
||||||
d_=$d/repos/social-app
|
|
||||||
custom=$d/social-app-custom
|
|
||||||
|
|
||||||
echo "applying custom screens"
|
|
||||||
|
|
||||||
# Copy custom screen files
|
|
||||||
cp ${custom}/PrivacyPolicy.screen.tsx ${d_}/src/view/screens/PrivacyPolicy.tsx
|
|
||||||
cp ${custom}/Support.screen.tsx ${d_}/src/view/screens/Support.tsx
|
|
||||||
cp ${custom}/LicenseNotice.tsx ${d_}/src/components/custom/
|
|
||||||
|
|
||||||
echo "custom screens applied"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
14
ios/config.zsh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
APP_NAME="Aiat"
|
||||||
|
DEVICE_ID="xxx"
|
||||||
|
REPO_DIR="../repos/social-app"
|
||||||
|
APP_SLUG="aiat"
|
||||||
|
APP_SCHEME="syui"
|
||||||
|
BUNDLE_ID="ai.syui.at"
|
||||||
|
APP_GROUP="group.ai.syui.at"
|
||||||
|
SERVICE_URL="https://syu.is"
|
||||||
|
HELP_URL="https://syu.is/help"
|
||||||
|
PRIVACY_URL="https://syu.is/privacy"
|
||||||
|
TERMS_URL="https://syu.is/terms"
|
||||||
|
REPO_DIR="../repos/social-app"
|
||||||
|
CONFIG_FILE="$REPO_DIR/app.config.js"
|
||||||
|
CONSTANTS_FILE="$REPO_DIR/src/lib/constants.ts"
|
||||||
BIN
ios/icon.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
67
ios/patch_drawer_links.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
file_path = sys.argv[1]
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
new_lines = []
|
||||||
|
in_extra_links = False
|
||||||
|
extra_links_replaced = False
|
||||||
|
|
||||||
|
# We will replace the entire ExtraLinks function
|
||||||
|
extra_links_code = """
|
||||||
|
function ExtraLinks() {
|
||||||
|
const {_} = useLingui()
|
||||||
|
const t = useTheme()
|
||||||
|
const kawaii = useKawaiiMode()
|
||||||
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.flex_col, a.gap_md, a.flex_wrap]}>
|
||||||
|
<TouchableOpacity onPress={() => navigation.navigate('TermsOfService')}>
|
||||||
|
<Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||||
|
<Trans>Terms of Service</Trans>
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity onPress={() => navigation.navigate('PrivacyPolicy')}>
|
||||||
|
<Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||||
|
<Trans>Privacy Policy</Trans>
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
{kawaii && (
|
||||||
|
<Text style={t.atoms.text_contrast_medium}>
|
||||||
|
<Trans>
|
||||||
|
Logo by{' '}
|
||||||
|
<InlineLinkText
|
||||||
|
style={[a.text_md]}
|
||||||
|
to="/profile/sawaratsuki.bsky.social"
|
||||||
|
label="@sawaratsuki.bsky.social">
|
||||||
|
@sawaratsuki.bsky.social
|
||||||
|
</InlineLinkText>
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if 'function ExtraLinks() {' in line:
|
||||||
|
in_extra_links = True
|
||||||
|
new_lines.append(extra_links_code)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if in_extra_links:
|
||||||
|
if line.strip() == '}':
|
||||||
|
in_extra_links = False
|
||||||
|
# Don't append the closing brace because extra_links_code includes it?
|
||||||
|
# Wait, extra_links_code includes the whole function.
|
||||||
|
# So we skip everything until LAST closing brace of function.
|
||||||
|
# Simple heuristic: indentation.
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_lines.append(line)
|
||||||
|
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
f.write(''.join(new_lines))
|
||||||
63
ios/preview.zsh
Executable file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
set -e
|
||||||
|
d=${0:a:h}
|
||||||
|
cd $d
|
||||||
|
|
||||||
|
source $d/config.zsh
|
||||||
|
|
||||||
|
echo "Running iOS preview workflow..."
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
|
||||||
|
# 0. Environment Setup (Fix Node Version)
|
||||||
|
export NVM_DIR="$HOME/.nvm"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
|
echo "Checking Node version..."
|
||||||
|
if command -v nvm >/dev/null; then
|
||||||
|
nvm use 22 || nvm use 20 || echo "Warning: Could not switch to Node 22/20. Current: $(node -v)"
|
||||||
|
else
|
||||||
|
echo "nvm not found, using system node: $(node -v)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. Install dependencies
|
||||||
|
echo "1. Installing dependencies (yarn)..."
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# 2. Prebuild (Generate ios directory)
|
||||||
|
echo "2. Running Expo Prebuild..."
|
||||||
|
# Clean old ios folder to remove old entitlements/AppClip targets
|
||||||
|
rm -rf ios
|
||||||
|
npx expo prebuild --platform ios --clean
|
||||||
|
|
||||||
|
# 3. CocoaPods
|
||||||
|
echo "3. Installing CocoaPods..."
|
||||||
|
# Ensure PATH includes Homebrew ruby gems if needed
|
||||||
|
export PATH="/opt/homebrew/lib/ruby/gems/3.4.0/bin:$PATH"
|
||||||
|
cd ios
|
||||||
|
pod install
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# 4. Signing (Manual Step)
|
||||||
|
echo "4. Opening Xcode for Signing..."
|
||||||
|
XCODE_PROJ="ios/${APP_NAME}.xcodeproj"
|
||||||
|
# Fallback search if variable name logic differs
|
||||||
|
if [ ! -d "$XCODE_PROJ" ]; then
|
||||||
|
XCODE_PROJ=$(find ios -name "*.xcodeproj" | head -n 1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
open "$XCODE_PROJ"
|
||||||
|
echo "========================================================"
|
||||||
|
echo " [ACTION REQUIRED] "
|
||||||
|
echo " Xcode opened ($XCODE_PROJ)."
|
||||||
|
echo " 1. Go to 'Signing & Capabilities' tab."
|
||||||
|
echo " 2. Select your Team."
|
||||||
|
echo " 3. Verify 'App Clip' target is gone."
|
||||||
|
echo " 4. Ensure no red errors exist."
|
||||||
|
echo " Press ENTER here once you are done to continue building."
|
||||||
|
echo "========================================================"
|
||||||
|
read
|
||||||
|
|
||||||
|
# 5. Run
|
||||||
|
echo "5. Building and Running..."
|
||||||
|
# If user wants specific device ID, uncomment below, otherwise let Expo ask/pick boot simulator
|
||||||
|
# npx expo run:ios --device "$DEVICE_ID" --configuration Release
|
||||||
|
npx expo run:ios
|
||||||
232
ios/setup.zsh
Executable file
@@ -0,0 +1,232 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
d=${0:a:h}
|
||||||
|
cd $d
|
||||||
|
|
||||||
|
source $d/config.zsh
|
||||||
|
|
||||||
|
# Sed compatibility wrapper
|
||||||
|
function sediment() {
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
sed -i '' "$@"
|
||||||
|
else
|
||||||
|
sed -i "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Configuring $APP_NAME..."
|
||||||
|
|
||||||
|
# Check if repo exists
|
||||||
|
#if [ ! -d "$REPO_DIR" ]; then
|
||||||
|
# echo "Cloning social-app..."
|
||||||
|
# git clone https://github.com/bluesky-social/social-app "$REPO_DIR"
|
||||||
|
#else
|
||||||
|
# echo "Updating social-app..."
|
||||||
|
# pushd "$REPO_DIR"
|
||||||
|
# git stash -u
|
||||||
|
# if ! git pull; then
|
||||||
|
# echo "Git pull failed. Resetting..."
|
||||||
|
# git reset --hard HEAD
|
||||||
|
# git pull
|
||||||
|
# fi
|
||||||
|
# popd
|
||||||
|
#fi
|
||||||
|
|
||||||
|
# Backup config if not exists (or restore from backup to start fresh)
|
||||||
|
if [ ! -f "$CONFIG_FILE.bak" ]; then
|
||||||
|
cp "$CONFIG_FILE" "$CONFIG_FILE.bak"
|
||||||
|
else
|
||||||
|
cp "$CONFIG_FILE.bak" "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. app.config.js modifications
|
||||||
|
echo "Updating app.config.js..."
|
||||||
|
|
||||||
|
# Replace name
|
||||||
|
sediment "s/name: 'Bluesky'/name: '$APP_NAME'/g" "$CONFIG_FILE"
|
||||||
|
sediment "s/slug: 'bluesky'/slug: '$APP_SLUG'/g" "$CONFIG_FILE"
|
||||||
|
sediment "s/scheme: 'bsky'/scheme: '$APP_SCHEME'/g" "$CONFIG_FILE"
|
||||||
|
|
||||||
|
# Replace Bundle ID and App Group
|
||||||
|
sediment "s/xyz.blueskyweb.app/$BUNDLE_ID/g" "$CONFIG_FILE"
|
||||||
|
sediment "s/group.app.bsky/$APP_GROUP/g" "$CONFIG_FILE"
|
||||||
|
|
||||||
|
# REMOVE App Clip Configuration (Critical for Personal Team Signing)
|
||||||
|
# Use Python for safer multi-line removal than sed
|
||||||
|
echo "Removing App Clip configuration..."
|
||||||
|
python3 -c "
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open('$CONFIG_FILE', 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
with open('$CONFIG_FILE', 'w') as f:
|
||||||
|
skip = 0
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if skip > 0:
|
||||||
|
skip -= 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Remove the plugin import line
|
||||||
|
if 'withStarterPackAppClip.js' in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check if this line defines the AppClip target
|
||||||
|
# Structure we expect:
|
||||||
|
# {
|
||||||
|
# targetName: 'BlueskyClip',
|
||||||
|
# ...
|
||||||
|
# },
|
||||||
|
# We look for the targetName, and if found, we attempt to remove the preceding '{' line if possible
|
||||||
|
|
||||||
|
if \"targetName: 'BlueskyClip'\" in line:
|
||||||
|
# We found the target. We need to NOT write this line.
|
||||||
|
# And we need to ensure the PREVIOUS line (which was '{') is not written?
|
||||||
|
# Since we are writing sequentially, we can't pop easily unless we buffer.
|
||||||
|
# Actually, simpler: Read file, modify list, write back.
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Retry with list manipulation approach
|
||||||
|
out = []
|
||||||
|
i = 0
|
||||||
|
while i < len(lines):
|
||||||
|
line = lines[i]
|
||||||
|
|
||||||
|
# Remove plugin import
|
||||||
|
if 'withStarterPackAppClip.js' in line:
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Identify the block start
|
||||||
|
# We look ahead. If lines[i] is '{' and lines[i+1] has 'BlueskyClip', we skip the block.
|
||||||
|
if i + 1 < len(lines) and lines[i].strip() == '{' and \"targetName: 'BlueskyClip'\" in lines[i+1]:
|
||||||
|
# Found the start of the block.
|
||||||
|
# Skip until we find the closing '},'
|
||||||
|
# Typical block is 4 lines.
|
||||||
|
# {
|
||||||
|
# targetName: 'BlueskyClip',
|
||||||
|
# bundleIdentifier: ...,
|
||||||
|
# },
|
||||||
|
# We'll just skip 4 lines to be safe matching the observed file structure
|
||||||
|
i += 4
|
||||||
|
continue
|
||||||
|
|
||||||
|
out.append(line)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
f.writelines(out)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error processing file: {e}')
|
||||||
|
sys.exit(1)
|
||||||
|
"
|
||||||
|
|
||||||
|
# Inject NSAppTransportSecurity for development/preview (Allow Arbitrary Loads)
|
||||||
|
if ! grep -q "NSAppTransportSecurity" "$CONFIG_FILE"; then
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
sed -i '' "/ios: {/a\\
|
||||||
|
infoPlist: {\\
|
||||||
|
NSAppTransportSecurity: {\\
|
||||||
|
NSAllowsArbitraryLoads: true,\\
|
||||||
|
},\\
|
||||||
|
}," "$CONFIG_FILE"
|
||||||
|
else
|
||||||
|
sed -i "/ios: {/a\\
|
||||||
|
infoPlist: {\\
|
||||||
|
NSAppTransportSecurity: {\\
|
||||||
|
NSAllowsArbitraryLoads: true,\\
|
||||||
|
},\\
|
||||||
|
}," "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. constants.ts modifications
|
||||||
|
echo "Updating constants.ts..."
|
||||||
|
sediment "s|export const BSKY_SERVICE = 'https://bsky.social'|export const BSKY_SERVICE = '$SERVICE_URL'|g" "$CONSTANTS_FILE"
|
||||||
|
sediment "s|export const BSKY_SERVICE_DID = 'did:web:bsky.social'|export const BSKY_SERVICE_DID = 'did:web:syu.is'|g" "$CONSTANTS_FILE"
|
||||||
|
sediment "s|export const PUBLIC_BSKY_SERVICE = 'https://public.api.bsky.app'|export const PUBLIC_BSKY_SERVICE = 'https://bsky.syu.is'|g" "$CONSTANTS_FILE"
|
||||||
|
sediment "s|const HELP_DESK_LANG = 'en-us'|const HELP_DESK_LANG = 'ja-jp'|g" "$CONSTANTS_FILE"
|
||||||
|
sediment "s|export const HELP_DESK_URL = \`https://blueskyweb.zendesk.com/hc/\${HELP_DESK_LANG}\`|export const HELP_DESK_URL = '$HELP_URL'|g" "$CONSTANTS_FILE"
|
||||||
|
|
||||||
|
# 3. Footer/Link replacements (Global text replacement for specific URLs)
|
||||||
|
echo "Replacing links..."
|
||||||
|
grep -r "https://bsky.social/about/blog" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|https://bsky.social/about/blog|$HELP_URL|g\" {}; else sed -i \"s|https://bsky.social/about/blog|$HELP_URL|g\" {}; fi"
|
||||||
|
grep -r "https://bsky.social/about/blog/jobs" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|https://bsky.social/about/blog/jobs|$HELP_URL|g\" {}; else sed -i \"s|https://bsky.social/about/blog/jobs|$HELP_URL|g\" {}; fi"
|
||||||
|
grep -r "/support/privacy" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|/support/privacy|$PRIVACY_URL|g\" {}; else sed -i \"s|/support/privacy|$PRIVACY_URL|g\" {}; fi"
|
||||||
|
grep -r "/support/tos" "$REPO_DIR/src" -l | xargs -I {} zsh -c "if [[ \"\$OSTYPE\" == \"darwin\"* ]]; then sed -i '' \"s|/support/tos|$TERMS_URL|g\" {}; else sed -i \"s|/support/tos|$TERMS_URL|g\" {}; fi"
|
||||||
|
|
||||||
|
# 4. Icon replacement
|
||||||
|
if [ -d "app-icons" ]; then
|
||||||
|
echo "Updating icons from app-icons/ directory..."
|
||||||
|
# Copy the entire contents of the user-provided app-icons directory to the repo's assets/app-icons
|
||||||
|
# This covers all variants (Aurora, Bonfire, etc.) as the user has prepared them.
|
||||||
|
cp -rf "app-icons/"* "$REPO_DIR/assets/app-icons/"
|
||||||
|
|
||||||
|
# Also update the main app icons referenced by default
|
||||||
|
if [ -f "app-icons/ios_icon_default_next.png" ]; then
|
||||||
|
cp "app-icons/ios_icon_default_next.png" "$REPO_DIR/assets/icon.png"
|
||||||
|
cp "app-icons/ios_icon_default_next.png" "$REPO_DIR/assets/icon-android-notification.png"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Force app.config.js to use the 'default_next' PNG instead of the complex .icon directory
|
||||||
|
sediment "s|'./assets/app-icons/ios_icon_default.icon'|'./assets/app-icons/ios_icon_default_next.png'|g" "$CONFIG_FILE"
|
||||||
|
|
||||||
|
elif [ -f "icon.png" ]; then
|
||||||
|
echo "Updating ALL icons from single icon.png..."
|
||||||
|
# 1. Overwrite the files that app.config.js points to by default
|
||||||
|
cp "icon.png" "$REPO_DIR/assets/icon.png"
|
||||||
|
cp "icon.png" "$REPO_DIR/assets/icon-android-notification.png"
|
||||||
|
|
||||||
|
# 2. Overwrite ALL icons in app-icons/ since no specific set was provided
|
||||||
|
echo "Overwriting all assets/app-icons/*.png..."
|
||||||
|
find "$REPO_DIR/assets/app-icons" -name "*.png" -exec cp "icon.png" {} \;
|
||||||
|
|
||||||
|
# 3. Handle ios_icon_default.icon special case
|
||||||
|
TARGET_ICON_DIR="$REPO_DIR/assets/app-icons/ios_icon_default.icon"
|
||||||
|
if [ -d "$TARGET_ICON_DIR" ]; then
|
||||||
|
cp "icon.png" "$TARGET_ICON_DIR/icon.png" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Force app.config.js to point to PNG
|
||||||
|
sediment "s|'./assets/app-icons/ios_icon_default.icon'|'./assets/app-icons/ios_icon_default_next.png'|g" "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Build Fixes (Entitlements and NSE Sounds)
|
||||||
|
echo "Applying build fixes..."
|
||||||
|
|
||||||
|
# Fix 1: Create Config Plugin to Allow Entitlements Modification
|
||||||
|
cat <<EOF > "$REPO_DIR/plugins/withCodeSignEntitlements.js"
|
||||||
|
const { withXcodeProject } = require('expo/config-plugins');
|
||||||
|
|
||||||
|
module.exports = function withCodeSignEntitlements(config) {
|
||||||
|
return withXcodeProject(config, (config) => {
|
||||||
|
const xcodeProject = config.modResults;
|
||||||
|
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
||||||
|
for (const key in configurations) {
|
||||||
|
const buildSettings = configurations[key].buildSettings;
|
||||||
|
if (buildSettings) {
|
||||||
|
buildSettings['CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION'] = 'YES';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Register the plugin in app.config.js
|
||||||
|
# We insert it into the plugins array. Finding a safe anchor.
|
||||||
|
# 'expo-video' is in the plugins array.
|
||||||
|
sediment "s/'expo-video',/'expo-video', '.\/plugins\/withCodeSignEntitlements.js',/g" "$CONFIG_FILE"
|
||||||
|
|
||||||
|
|
||||||
|
# Fix 2: Disable soundFiles in Notification Extension to avoid 'no rule to process dm.aiff'
|
||||||
|
# The main app handles sounds via expo-notifications. The extension adding it as a source fails.
|
||||||
|
NOTIF_EXT_FILE="$REPO_DIR/plugins/notificationsExtension/withNotificationsExtension.js"
|
||||||
|
if [ -f "$NOTIF_EXT_FILE" ]; then
|
||||||
|
echo "Patching withNotificationsExtension.js..."
|
||||||
|
sediment "s/const soundFiles = \['dm.aiff'\]/const soundFiles = []/g" "$NOTIF_EXT_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Setup complete. App Clip configuration removed. Build fixes applied."
|
||||||