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