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