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