my fork of the bluesky client
1const pkg = require('./package.json')
2
3const SPLASH_CONFIG = {
4 backgroundColor: '#ffffff',
5 image: './assets/splash.png',
6 resizeMode: 'cover',
7}
8const DARK_SPLASH_CONFIG = {
9 backgroundColor: '#001429',
10 image: './assets/splash-dark.png',
11 resizeMode: 'cover',
12}
13
14const SPLASH_CONFIG_ANDROID = {
15 backgroundColor: '#0c7cff',
16 image: './assets/splash.png',
17 resizeMode: 'cover',
18}
19const DARK_SPLASH_CONFIG_ANDROID = {
20 backgroundColor: '#0f141b',
21 image: './assets/splash-dark.png',
22 resizeMode: 'cover',
23}
24
25module.exports = function (config) {
26 /**
27 * App version number. Should be incremented as part of a release cycle.
28 */
29 const VERSION = pkg.version
30
31 /**
32 * Uses built-in Expo env vars
33 *
34 * @see https://docs.expo.dev/build-reference/variables/#built-in-environment-variables
35 */
36 const PLATFORM = process.env.EAS_BUILD_PLATFORM
37
38 const IS_DEV = process.env.EXPO_PUBLIC_ENV === 'development'
39 const IS_TESTFLIGHT = process.env.EXPO_PUBLIC_ENV === 'testflight'
40 const IS_PRODUCTION = process.env.EXPO_PUBLIC_ENV === 'production'
41
42 const ASSOCIATED_DOMAINS = [
43 'applinks:bsky.app',
44 'applinks:staging.bsky.app',
45 'appclips:bsky.app',
46 'appclips:go.bsky.app', // Allows App Clip to work when scanning QR codes
47 // When testing local services, enter an ngrok (et al) domain here. It must use a standard HTTP/HTTPS port.
48 ...(IS_DEV || IS_TESTFLIGHT ? [] : []),
49 ]
50
51 const UPDATES_CHANNEL = IS_TESTFLIGHT
52 ? 'testflight'
53 : IS_PRODUCTION
54 ? 'production'
55 : undefined
56 const UPDATES_ENABLED = !!UPDATES_CHANNEL
57
58 const USE_SENTRY = Boolean(process.env.SENTRY_AUTH_TOKEN)
59 const SENTRY_DIST = `${PLATFORM}.${VERSION}.${IS_TESTFLIGHT ? 'tf' : ''}${
60 IS_DEV ? 'dev' : ''
61 }`
62
63 return {
64 expo: {
65 version: VERSION,
66 name: 'Bluesky',
67 slug: 'bluesky',
68 scheme: 'bluesky',
69 owner: 'blueskysocial',
70 runtimeVersion: {
71 policy: 'appVersion',
72 },
73 orientation: 'portrait',
74 icon: './assets/icon.png',
75 userInterfaceStyle: 'automatic',
76 splash: SPLASH_CONFIG,
77 // hsl(211, 99%, 53%), same as palette.default.brandText
78 primaryColor: '#1083fe',
79 ios: {
80 supportsTablet: false,
81 bundleIdentifier: 'xyz.blueskyweb.app',
82 config: {
83 usesNonExemptEncryption: false,
84 },
85 infoPlist: {
86 UIBackgroundModes: ['remote-notification'],
87 NSCameraUsageDescription:
88 'Used for profile pictures, posts, and other kinds of content.',
89 NSMicrophoneUsageDescription:
90 'Used for posts and other kinds of content.',
91 NSPhotoLibraryAddUsageDescription:
92 'Used to save images to your library.',
93 NSPhotoLibraryUsageDescription:
94 'Used for profile pictures, posts, and other kinds of content',
95 CFBundleSpokenName: 'Blue Sky',
96 CFBundleLocalizations: [
97 'en',
98 'ca',
99 'de',
100 'es',
101 'fi',
102 'fr',
103 'ga',
104 'hi',
105 'hu',
106 'id',
107 'it',
108 'ja',
109 'ko',
110 'pl',
111 'pt',
112 'ru',
113 'th',
114 'tr',
115 'uk',
116 'zh_CN',
117 'zh_HK',
118 'zh_TW',
119 ],
120 },
121 associatedDomains: ASSOCIATED_DOMAINS,
122 splash: {
123 ...SPLASH_CONFIG,
124 dark: DARK_SPLASH_CONFIG,
125 },
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.bsky',
130 },
131 privacyManifests: {
132 NSPrivacyAccessedAPITypes: [
133 {
134 NSPrivacyAccessedAPIType:
135 'NSPrivacyAccessedAPICategoryFileTimestamp',
136 NSPrivacyAccessedAPITypeReasons: ['C617.1', '3B52.1', '0A2A.1'],
137 },
138 {
139 NSPrivacyAccessedAPIType: 'NSPrivacyAccessedAPICategoryDiskSpace',
140 NSPrivacyAccessedAPITypeReasons: ['E174.1', '85F4.1'],
141 },
142 {
143 NSPrivacyAccessedAPIType:
144 'NSPrivacyAccessedAPICategorySystemBootTime',
145 NSPrivacyAccessedAPITypeReasons: ['35F9.1'],
146 },
147 {
148 NSPrivacyAccessedAPIType:
149 'NSPrivacyAccessedAPICategoryUserDefaults',
150 NSPrivacyAccessedAPITypeReasons: ['CA92.1', '1C8F.1'],
151 },
152 ],
153 },
154 },
155 androidStatusBar: {
156 barStyle: 'light-content',
157 backgroundColor: '#00000000',
158 },
159 // Dark nav bar in light mode is better than light nav bar in dark mode
160 androidNavigationBar: {
161 barStyle: 'light-content',
162 backgroundColor: DARK_SPLASH_CONFIG_ANDROID.backgroundColor,
163 },
164 android: {
165 icon: './assets/icon.png',
166 adaptiveIcon: {
167 foregroundImage: './assets/icon-android-foreground.png',
168 monochromeImage: './assets/icon-android-foreground.png',
169 backgroundImage: './assets/icon-android-background.png',
170 backgroundColor: '#1185FE',
171 },
172 googleServicesFile: './google-services.json',
173 package: 'xyz.blueskyweb.app',
174 intentFilters: [
175 {
176 action: 'VIEW',
177 autoVerify: true,
178 data: [
179 {
180 scheme: 'https',
181 host: 'bsky.app',
182 },
183 IS_DEV && {
184 scheme: 'http',
185 host: 'localhost:19006',
186 },
187 ],
188 category: ['BROWSABLE', 'DEFAULT'],
189 },
190 ],
191 splash: {
192 ...SPLASH_CONFIG_ANDROID,
193 dark: DARK_SPLASH_CONFIG_ANDROID,
194 },
195 },
196 web: {
197 favicon: './assets/favicon.png',
198 },
199 updates: {
200 url: 'https://updates.bsky.app/manifest',
201 enabled: UPDATES_ENABLED,
202 fallbackToCacheTimeout: 30000,
203 codeSigningCertificate: UPDATES_ENABLED
204 ? './code-signing/certificate.pem'
205 : undefined,
206 codeSigningMetadata: UPDATES_ENABLED
207 ? {
208 keyid: 'main',
209 alg: 'rsa-v1_5-sha256',
210 }
211 : undefined,
212 checkAutomatically: 'NEVER',
213 channel: UPDATES_CHANNEL,
214 },
215 plugins: [
216 'expo-localization',
217 USE_SENTRY && [
218 '@sentry/react-native/expo',
219 {
220 organization: 'blueskyweb',
221 project: 'react-native',
222 release: VERSION,
223 dist: SENTRY_DIST,
224 },
225 ],
226 [
227 'expo-build-properties',
228 {
229 ios: {
230 deploymentTarget: '15.1',
231 newArchEnabled: false,
232 },
233 android: {
234 compileSdkVersion: 34,
235 targetSdkVersion: 34,
236 buildToolsVersion: '34.0.0',
237 kotlinVersion: '1.8.0',
238 newArchEnabled: false,
239 },
240 },
241 ],
242 [
243 'expo-notifications',
244 {
245 icon: './assets/icon-android-notification.png',
246 color: '#1185fe',
247 sounds: PLATFORM === 'ios' ? ['assets/dm.aiff'] : ['assets/dm.mp3'],
248 },
249 ],
250 'react-native-compressor',
251 './plugins/starterPackAppClipExtension/withStarterPackAppClip.js',
252 './plugins/withAndroidManifestPlugin.js',
253 './plugins/withAndroidManifestFCMIconPlugin.js',
254 './plugins/withAndroidStylesWindowBackgroundPlugin.js',
255 './plugins/withAndroidStylesAccentColorPlugin.js',
256 './plugins/withAndroidSplashScreenStatusBarTranslucentPlugin.js',
257 './plugins/shareExtension/withShareExtensions.js',
258 './plugins/notificationsExtension/withNotificationsExtension.js',
259 './plugins/withAppDelegateReferrer.js',
260 [
261 'expo-font',
262 {
263 fonts: [
264 './assets/fonts/inter/InterVariable.ttf',
265 './assets/fonts/inter/InterVariable-Italic.ttf',
266 // Android only
267 './assets/fonts/inter/Inter-Regular.otf',
268 './assets/fonts/inter/Inter-Italic.otf',
269 './assets/fonts/inter/Inter-SemiBold.otf',
270 './assets/fonts/inter/Inter-SemiBoldItalic.otf',
271 './assets/fonts/inter/Inter-ExtraBold.otf',
272 './assets/fonts/inter/Inter-ExtraBoldItalic.otf',
273 ],
274 },
275 ],
276 ].filter(Boolean),
277 extra: {
278 eas: {
279 build: {
280 experimental: {
281 ios: {
282 appExtensions: [
283 {
284 targetName: 'Share-with-Bluesky',
285 bundleIdentifier: 'xyz.blueskyweb.app.Share-with-Bluesky',
286 entitlements: {
287 'com.apple.security.application-groups': [
288 'group.app.bsky',
289 ],
290 },
291 },
292 {
293 targetName: 'BlueskyNSE',
294 bundleIdentifier: 'xyz.blueskyweb.app.BlueskyNSE',
295 entitlements: {
296 'com.apple.security.application-groups': [
297 'group.app.bsky',
298 ],
299 },
300 },
301 {
302 targetName: 'BlueskyClip',
303 bundleIdentifier: 'xyz.blueskyweb.app.AppClip',
304 },
305 ],
306 },
307 },
308 },
309 projectId: '55bd077a-d905-4184-9c7f-94789ba0f302',
310 },
311 },
312 hooks: {
313 postPublish: [
314 /*
315 * @see https://docs.expo.dev/guides/using-sentry/#app-configuration
316 */
317 {
318 file: './postHooks/uploadSentrySourcemapsPostHook',
319 config: {
320 organization: 'blueskyweb',
321 project: 'react-native',
322 release: VERSION,
323 dist: SENTRY_DIST,
324 },
325 },
326 ],
327 },
328 },
329 }
330}