Bluesky app fork with some witchin' additions 馃挮
1const pkg = require('./package.json') 2 3module.exports = function (_config) { 4 /** 5 * App version number. Should be incremented as part of a release cycle. 6 */ 7 const VERSION = pkg.version 8 9 /** 10 * Uses built-in Expo env vars 11 * 12 * @see https://docs.expo.dev/build-reference/variables/#built-in-environment-variables 13 */ 14 const PLATFORM = process.env.EAS_BUILD_PLATFORM ?? 'web' 15 16 const IS_TESTFLIGHT = process.env.EXPO_PUBLIC_ENV === 'testflight' 17 const IS_PRODUCTION = process.env.EXPO_PUBLIC_ENV === 'production' 18 const IS_DEV = !IS_TESTFLIGHT || !IS_PRODUCTION 19 20 const ASSOCIATED_DOMAINS = [ 21 'applinks:bsky.app', 22 'applinks:staging.bsky.app', 23 'appclips:bsky.app', 24 'appclips:go.bsky.app', // Allows App Clip to work when scanning QR codes 25 // When testing local services, enter an ngrok (et al) domain here. It must use a standard HTTP/HTTPS port. 26 ...(IS_DEV || IS_TESTFLIGHT ? [] : []), 27 ] 28 29 const UPDATES_ENABLED = IS_TESTFLIGHT || IS_PRODUCTION 30 31 const USE_SENTRY = Boolean(process.env.SENTRY_AUTH_TOKEN) 32 33 return { 34 expo: { 35 version: VERSION, 36 name: 'Bluesky', 37 slug: 'bluesky', 38 scheme: 'bluesky', 39 owner: 'blueskysocial', 40 runtimeVersion: { 41 policy: 'appVersion', 42 }, 43 icon: './assets/app-icons/ios_icon_default_next.png', 44 userInterfaceStyle: 'automatic', 45 primaryColor: '#1083fe', 46 newArchEnabled: false, 47 ios: { 48 supportsTablet: false, 49 bundleIdentifier: 'xyz.blueskyweb.app', 50 config: { 51 usesNonExemptEncryption: false, 52 }, 53 icon: 54 PLATFORM === 'web' // web build doesn't like .icon files 55 ? './assets/app-icons/ios_icon_default_next.png' 56 : './assets/app-icons/ios_icon_default.icon', 57 infoPlist: { 58 UIBackgroundModes: ['remote-notification'], 59 NSCameraUsageDescription: 60 'Used for profile pictures, posts, and other kinds of content.', 61 NSMicrophoneUsageDescription: 62 'Used for posts and other kinds of content.', 63 NSPhotoLibraryAddUsageDescription: 64 'Used to save images to your library.', 65 NSPhotoLibraryUsageDescription: 66 'Used for profile pictures, posts, and other kinds of content', 67 CFBundleSpokenName: 'Blue Sky', 68 CFBundleLocalizations: [ 69 'en', 70 'an', 71 'ast', 72 'ca', 73 'cy', 74 'da', 75 'de', 76 'el', 77 'eo', 78 'es', 79 'eu', 80 'fi', 81 'fr', 82 'fy', 83 'ga', 84 'gd', 85 'gl', 86 'hi', 87 'hu', 88 'ia', 89 'id', 90 'it', 91 'ja', 92 'km', 93 'ko', 94 'ne', 95 'nl', 96 'pl', 97 'pt-BR', 98 'pt-PT', 99 'ro', 100 'ru', 101 'sv', 102 'th', 103 'tr', 104 'uk', 105 'vi', 106 'yue', 107 'zh-Hans', 108 'zh-Hant', 109 ], 110 UIDesignRequiresCompatibility: true, 111 }, 112 associatedDomains: ASSOCIATED_DOMAINS, 113 entitlements: { 114 'com.apple.developer.kernel.increased-memory-limit': true, 115 'com.apple.developer.kernel.extended-virtual-addressing': true, 116 'com.apple.security.application-groups': 'group.app.bsky', 117 }, 118 privacyManifests: { 119 NSPrivacyCollectedDataTypes: [ 120 { 121 NSPrivacyCollectedDataType: 'NSPrivacyCollectedDataTypeCrashData', 122 NSPrivacyCollectedDataTypeLinked: false, 123 NSPrivacyCollectedDataTypeTracking: false, 124 NSPrivacyCollectedDataTypePurposes: [ 125 'NSPrivacyCollectedDataTypePurposeAppFunctionality', 126 ], 127 }, 128 { 129 NSPrivacyCollectedDataType: 130 'NSPrivacyCollectedDataTypePerformanceData', 131 NSPrivacyCollectedDataTypeLinked: false, 132 NSPrivacyCollectedDataTypeTracking: false, 133 NSPrivacyCollectedDataTypePurposes: [ 134 'NSPrivacyCollectedDataTypePurposeAppFunctionality', 135 ], 136 }, 137 { 138 NSPrivacyCollectedDataType: 139 'NSPrivacyCollectedDataTypeOtherDiagnosticData', 140 NSPrivacyCollectedDataTypeLinked: false, 141 NSPrivacyCollectedDataTypeTracking: false, 142 NSPrivacyCollectedDataTypePurposes: [ 143 'NSPrivacyCollectedDataTypePurposeAppFunctionality', 144 ], 145 }, 146 ], 147 NSPrivacyAccessedAPITypes: [ 148 { 149 NSPrivacyAccessedAPIType: 150 'NSPrivacyAccessedAPICategoryFileTimestamp', 151 NSPrivacyAccessedAPITypeReasons: ['C617.1', '3B52.1', '0A2A.1'], 152 }, 153 { 154 NSPrivacyAccessedAPIType: 'NSPrivacyAccessedAPICategoryDiskSpace', 155 NSPrivacyAccessedAPITypeReasons: ['E174.1', '85F4.1'], 156 }, 157 { 158 NSPrivacyAccessedAPIType: 159 'NSPrivacyAccessedAPICategorySystemBootTime', 160 NSPrivacyAccessedAPITypeReasons: ['35F9.1'], 161 }, 162 { 163 NSPrivacyAccessedAPIType: 164 'NSPrivacyAccessedAPICategoryUserDefaults', 165 NSPrivacyAccessedAPITypeReasons: ['CA92.1', '1C8F.1'], 166 }, 167 ], 168 }, 169 }, 170 androidStatusBar: { 171 barStyle: 'light-content', 172 }, 173 // Dark nav bar in light mode is better than light nav bar in dark mode 174 androidNavigationBar: { 175 barStyle: 'light-content', 176 }, 177 android: { 178 icon: './assets/app-icons/android_icon_default_next.png', 179 adaptiveIcon: { 180 foregroundImage: './assets/icon-android-foreground.png', 181 monochromeImage: './assets/icon-android-monochrome.png', 182 backgroundColor: '#006AFF', 183 }, 184 googleServicesFile: './google-services.json', 185 package: 'xyz.blueskyweb.app', 186 intentFilters: [ 187 { 188 action: 'VIEW', 189 autoVerify: true, 190 data: [ 191 { 192 scheme: 'https', 193 host: 'bsky.app', 194 }, 195 IS_DEV && { 196 scheme: 'http', 197 host: 'localhost:19006', 198 }, 199 ], 200 category: ['BROWSABLE', 'DEFAULT'], 201 }, 202 ], 203 }, 204 web: { 205 favicon: './assets/favicon.png', 206 }, 207 updates: { 208 url: 'https://updates.bsky.app/manifest', 209 enabled: UPDATES_ENABLED, 210 fallbackToCacheTimeout: 30000, 211 codeSigningCertificate: UPDATES_ENABLED 212 ? './code-signing/certificate.pem' 213 : undefined, 214 codeSigningMetadata: UPDATES_ENABLED 215 ? { 216 keyid: 'main', 217 alg: 'rsa-v1_5-sha256', 218 } 219 : undefined, 220 checkAutomatically: 'NEVER', 221 }, 222 plugins: [ 223 'expo-video', 224 'expo-localization', 225 'expo-web-browser', 226 [ 227 'react-native-edge-to-edge', 228 {android: {enforceNavigationBarContrast: false}}, 229 ], 230 USE_SENTRY && [ 231 '@sentry/react-native/expo', 232 { 233 organization: 'blueskyweb', 234 project: 'app', 235 url: 'https://sentry.io', 236 }, 237 ], 238 [ 239 'expo-build-properties', 240 { 241 ios: { 242 deploymentTarget: '15.1', 243 buildReactNativeFromSource: true, 244 }, 245 android: { 246 compileSdkVersion: 35, 247 targetSdkVersion: 35, 248 buildToolsVersion: '35.0.0', 249 }, 250 }, 251 ], 252 [ 253 'expo-notifications', 254 { 255 icon: './assets/icon-android-notification.png', 256 color: '#1185fe', 257 sounds: PLATFORM === 'ios' ? ['assets/dm.aiff'] : ['assets/dm.mp3'], 258 }, 259 ], 260 'react-native-compressor', 261 [ 262 '@bitdrift/react-native', 263 { 264 networkInstrumentation: true, 265 }, 266 ], 267 './plugins/starterPackAppClipExtension/withStarterPackAppClip.js', 268 './plugins/withGradleJVMHeapSizeIncrease.js', 269 './plugins/withAndroidManifestLargeHeapPlugin.js', 270 './plugins/withAndroidManifestFCMIconPlugin.js', 271 './plugins/withAndroidManifestIntentQueriesPlugin.js', 272 './plugins/withAndroidStylesAccentColorPlugin.js', 273 './plugins/withAndroidDayNightThemePlugin.js', 274 './plugins/withAndroidNoJitpackPlugin.js', 275 './plugins/shareExtension/withShareExtensions.js', 276 './plugins/notificationsExtension/withNotificationsExtension.js', 277 [ 278 'expo-font', 279 { 280 fonts: [ 281 './assets/fonts/inter/InterVariable.woff2', 282 './assets/fonts/inter/InterVariable-Italic.woff2', 283 // Android only 284 './assets/fonts/inter/Inter-Regular.otf', 285 './assets/fonts/inter/Inter-Italic.otf', 286 './assets/fonts/inter/Inter-Medium.otf', 287 './assets/fonts/inter/Inter-MediumItalic.otf', 288 './assets/fonts/inter/Inter-SemiBold.otf', 289 './assets/fonts/inter/Inter-SemiBoldItalic.otf', 290 './assets/fonts/inter/Inter-Bold.otf', 291 './assets/fonts/inter/Inter-BoldItalic.otf', 292 ], 293 }, 294 ], 295 [ 296 'expo-splash-screen', 297 { 298 ios: { 299 enableFullScreenImage_legacy: true, 300 backgroundColor: '#ffffff', 301 image: './assets/splash.png', 302 resizeMode: 'cover', 303 dark: { 304 enableFullScreenImage_legacy: true, 305 backgroundColor: '#001429', 306 image: './assets/splash-dark.png', 307 resizeMode: 'cover', 308 }, 309 }, 310 android: { 311 backgroundColor: '#0c7cff', 312 image: './assets/splash-android-icon.png', 313 imageWidth: 150, 314 dark: { 315 backgroundColor: '#0c2a49', 316 image: './assets/splash-android-icon-dark.png', 317 imageWidth: 150, 318 }, 319 }, 320 }, 321 ], 322 [ 323 '@mozzius/expo-dynamic-app-icon', 324 { 325 /** 326 * Default set 327 */ 328 default_light: { 329 ios: './assets/app-icons/ios_icon_legacy_light.png', 330 android: './assets/app-icons/android_icon_legacy_light.png', 331 prerendered: true, 332 }, 333 default_dark: { 334 ios: './assets/app-icons/ios_icon_legacy_dark.png', 335 android: './assets/app-icons/android_icon_legacy_dark.png', 336 prerendered: true, 337 }, 338 339 /** 340 * Bluesky+ core set 341 */ 342 core_aurora: { 343 ios: './assets/app-icons/ios_icon_core_aurora.png', 344 android: './assets/app-icons/android_icon_core_aurora.png', 345 prerendered: true, 346 }, 347 core_bonfire: { 348 ios: './assets/app-icons/ios_icon_core_bonfire.png', 349 android: './assets/app-icons/android_icon_core_bonfire.png', 350 prerendered: true, 351 }, 352 core_sunrise: { 353 ios: './assets/app-icons/ios_icon_core_sunrise.png', 354 android: './assets/app-icons/android_icon_core_sunrise.png', 355 prerendered: true, 356 }, 357 core_sunset: { 358 ios: './assets/app-icons/ios_icon_core_sunset.png', 359 android: './assets/app-icons/android_icon_core_sunset.png', 360 prerendered: true, 361 }, 362 core_midnight: { 363 ios: './assets/app-icons/ios_icon_core_midnight.png', 364 android: './assets/app-icons/android_icon_core_midnight.png', 365 prerendered: true, 366 }, 367 core_flat_blue: { 368 ios: './assets/app-icons/ios_icon_core_flat_blue.png', 369 android: './assets/app-icons/android_icon_core_flat_blue.png', 370 prerendered: true, 371 }, 372 core_flat_white: { 373 ios: './assets/app-icons/ios_icon_core_flat_white.png', 374 android: './assets/app-icons/android_icon_core_flat_white.png', 375 prerendered: true, 376 }, 377 core_flat_black: { 378 ios: './assets/app-icons/ios_icon_core_flat_black.png', 379 android: './assets/app-icons/android_icon_core_flat_black.png', 380 prerendered: true, 381 }, 382 core_classic: { 383 ios: './assets/app-icons/ios_icon_core_classic.png', 384 android: './assets/app-icons/android_icon_core_classic.png', 385 prerendered: true, 386 }, 387 }, 388 ], 389 ['expo-screen-orientation', {initialOrientation: 'PORTRAIT_UP'}], 390 ['expo-location'], 391 ].filter(Boolean), 392 extra: { 393 eas: { 394 build: { 395 experimental: { 396 ios: { 397 appExtensions: [ 398 { 399 targetName: 'Share-with-Bluesky', 400 bundleIdentifier: 'xyz.blueskyweb.app.Share-with-Bluesky', 401 entitlements: { 402 'com.apple.security.application-groups': [ 403 'group.app.bsky', 404 ], 405 }, 406 }, 407 { 408 targetName: 'BlueskyNSE', 409 bundleIdentifier: 'xyz.blueskyweb.app.BlueskyNSE', 410 entitlements: { 411 'com.apple.security.application-groups': [ 412 'group.app.bsky', 413 ], 414 }, 415 }, 416 { 417 targetName: 'BlueskyClip', 418 bundleIdentifier: 'xyz.blueskyweb.app.AppClip', 419 }, 420 ], 421 }, 422 }, 423 }, 424 projectId: '55bd077a-d905-4184-9c7f-94789ba0f302', 425 }, 426 }, 427 }, 428 } 429}