forked from
jollywhoppers.com/witchsky.app
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 buildReactNativeFromSource: IS_PRODUCTION,
250 },
251 },
252 ],
253 [
254 'expo-notifications',
255 {
256 icon: './assets/icon-android-notification.png',
257 color: '#1185fe',
258 sounds: PLATFORM === 'ios' ? ['assets/dm.aiff'] : ['assets/dm.mp3'],
259 },
260 ],
261 'react-native-compressor',
262 [
263 '@bitdrift/react-native',
264 {
265 networkInstrumentation: true,
266 },
267 ],
268 './plugins/starterPackAppClipExtension/withStarterPackAppClip.js',
269 './plugins/withGradleJVMHeapSizeIncrease.js',
270 './plugins/withAndroidManifestLargeHeapPlugin.js',
271 './plugins/withAndroidManifestFCMIconPlugin.js',
272 './plugins/withAndroidManifestIntentQueriesPlugin.js',
273 './plugins/withAndroidStylesAccentColorPlugin.js',
274 './plugins/withAndroidDayNightThemePlugin.js',
275 './plugins/withAndroidNoJitpackPlugin.js',
276 './plugins/shareExtension/withShareExtensions.js',
277 './plugins/notificationsExtension/withNotificationsExtension.js',
278 [
279 'expo-font',
280 {
281 fonts: [
282 './assets/fonts/inter/InterVariable.woff2',
283 './assets/fonts/inter/InterVariable-Italic.woff2',
284 // Android only
285 './assets/fonts/inter/Inter-Regular.otf',
286 './assets/fonts/inter/Inter-Italic.otf',
287 './assets/fonts/inter/Inter-Medium.otf',
288 './assets/fonts/inter/Inter-MediumItalic.otf',
289 './assets/fonts/inter/Inter-SemiBold.otf',
290 './assets/fonts/inter/Inter-SemiBoldItalic.otf',
291 './assets/fonts/inter/Inter-Bold.otf',
292 './assets/fonts/inter/Inter-BoldItalic.otf',
293 ],
294 },
295 ],
296 [
297 'expo-splash-screen',
298 {
299 ios: {
300 enableFullScreenImage_legacy: true,
301 backgroundColor: '#ffffff',
302 image: './assets/splash.png',
303 resizeMode: 'cover',
304 dark: {
305 enableFullScreenImage_legacy: true,
306 backgroundColor: '#001429',
307 image: './assets/splash-dark.png',
308 resizeMode: 'cover',
309 },
310 },
311 android: {
312 backgroundColor: '#0c7cff',
313 image: './assets/splash-android-icon.png',
314 imageWidth: 150,
315 dark: {
316 backgroundColor: '#0c2a49',
317 image: './assets/splash-android-icon-dark.png',
318 imageWidth: 150,
319 },
320 },
321 },
322 ],
323 [
324 '@mozzius/expo-dynamic-app-icon',
325 {
326 /**
327 * Default set
328 */
329 default_light: {
330 ios: './assets/app-icons/ios_icon_legacy_light.png',
331 android: './assets/app-icons/android_icon_legacy_light.png',
332 prerendered: true,
333 },
334 default_dark: {
335 ios: './assets/app-icons/ios_icon_legacy_dark.png',
336 android: './assets/app-icons/android_icon_legacy_dark.png',
337 prerendered: true,
338 },
339
340 /**
341 * Bluesky+ core set
342 */
343 core_aurora: {
344 ios: './assets/app-icons/ios_icon_core_aurora.png',
345 android: './assets/app-icons/android_icon_core_aurora.png',
346 prerendered: true,
347 },
348 core_bonfire: {
349 ios: './assets/app-icons/ios_icon_core_bonfire.png',
350 android: './assets/app-icons/android_icon_core_bonfire.png',
351 prerendered: true,
352 },
353 core_sunrise: {
354 ios: './assets/app-icons/ios_icon_core_sunrise.png',
355 android: './assets/app-icons/android_icon_core_sunrise.png',
356 prerendered: true,
357 },
358 core_sunset: {
359 ios: './assets/app-icons/ios_icon_core_sunset.png',
360 android: './assets/app-icons/android_icon_core_sunset.png',
361 prerendered: true,
362 },
363 core_midnight: {
364 ios: './assets/app-icons/ios_icon_core_midnight.png',
365 android: './assets/app-icons/android_icon_core_midnight.png',
366 prerendered: true,
367 },
368 core_flat_blue: {
369 ios: './assets/app-icons/ios_icon_core_flat_blue.png',
370 android: './assets/app-icons/android_icon_core_flat_blue.png',
371 prerendered: true,
372 },
373 core_flat_white: {
374 ios: './assets/app-icons/ios_icon_core_flat_white.png',
375 android: './assets/app-icons/android_icon_core_flat_white.png',
376 prerendered: true,
377 },
378 core_flat_black: {
379 ios: './assets/app-icons/ios_icon_core_flat_black.png',
380 android: './assets/app-icons/android_icon_core_flat_black.png',
381 prerendered: true,
382 },
383 core_classic: {
384 ios: './assets/app-icons/ios_icon_core_classic.png',
385 android: './assets/app-icons/android_icon_core_classic.png',
386 prerendered: true,
387 },
388 },
389 ],
390 ['expo-screen-orientation', {initialOrientation: 'PORTRAIT_UP'}],
391 ['expo-location'],
392 [
393 'expo-contacts',
394 {
395 contactsPermission:
396 'I agree to allow Bluesky to use my contacts for friend discovery until I opt out.',
397 },
398 ],
399 ].filter(Boolean),
400 extra: {
401 eas: {
402 build: {
403 experimental: {
404 ios: {
405 appExtensions: [
406 {
407 targetName: 'Share-with-Bluesky',
408 bundleIdentifier: 'xyz.blueskyweb.app.Share-with-Bluesky',
409 entitlements: {
410 'com.apple.security.application-groups': [
411 'group.app.bsky',
412 ],
413 },
414 },
415 {
416 targetName: 'BlueskyNSE',
417 bundleIdentifier: 'xyz.blueskyweb.app.BlueskyNSE',
418 entitlements: {
419 'com.apple.security.application-groups': [
420 'group.app.bsky',
421 ],
422 },
423 },
424 {
425 targetName: 'BlueskyClip',
426 bundleIdentifier: 'xyz.blueskyweb.app.AppClip',
427 },
428 ],
429 },
430 },
431 },
432 projectId: '55bd077a-d905-4184-9c7f-94789ba0f302',
433 },
434 },
435 },
436 }
437}