expo-dev-menu 0.10.3 → 0.10.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,26 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.10.6 — 2022-05-06
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Fix dev menu will reload the application when open for the first time while using Hermes. ([#17377](https://github.com/expo/expo/pull/17377) by [@lukmccall](https://github.com/lukmccall))
18
+
19
+ ## 0.10.5 — 2022-05-05
20
+
21
+ ### 🐛 Bug fixes
22
+
23
+ - Fix `unresolved reference: loadFonts` in the release build on Android. ([#17241](https://github.com/expo/expo/pull/17241) by [@lukmccall](https://github.com/lukmccall))
24
+ - Fix remote debugging crashing the application on iOS. ([#17248](https://github.com/expo/expo/pull/17248) by [@lukmccall](https://github.com/lukmccall))
25
+ - Fix crashes when the app was launched from a deep link and the react-native-reanimated were installed on Android. ([#17282](https://github.com/expo/expo/pull/17282) by [@lukmccall](https://github.com/lukmccall))
26
+
27
+ ## 0.10.4 — 2022-04-26
28
+
29
+ ### 🐛 Bug fixes
30
+
31
+ - Fix error on summoning dev-menu first time, that leads to the application freeze. ([#17215](https://github.com/expo/expo/pull/17215) by [@lukmccall](https://github.com/lukmccall))
32
+
13
33
  ## 0.10.3 — 2022-04-25
14
34
 
15
35
  _This version does not introduce any user-facing changes._
@@ -7,7 +7,7 @@ apply plugin: 'kotlin-android'
7
7
  apply plugin: 'maven-publish'
8
8
 
9
9
  group = 'host.exp.exponent'
10
- version = '0.10.3'
10
+ version = '0.10.6'
11
11
 
12
12
  // reanimated v2
13
13
  def reactNativeFilePath = ["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()
@@ -207,7 +207,7 @@ android {
207
207
  minSdkVersion safeExtGet("minSdkVersion", 21)
208
208
  targetSdkVersion safeExtGet("targetSdkVersion", 31)
209
209
  versionCode 10
210
- versionName '0.10.3'
210
+ versionName '0.10.6'
211
211
  }
212
212
  lintOptions {
213
213
  abortOnError false
@@ -174,12 +174,6 @@ object DevMenuManager : DevMenuManagerInterface, LifecycleEventListener {
174
174
  devMenuHost = DevMenuHost(application)
175
175
  UiThreadUtil.runOnUiThread {
176
176
  devMenuHost.reactInstanceManager.createReactContextInBackground()
177
-
178
- // Hermes inspector will use latest executed script for Chrome DevTools Protocol.
179
- // It will be EXDevMenuApp.android.js in our case.
180
- // To let Hermes aware target bundle, we try to reload here as a workaround solution.
181
- // @see <a href="https://github.com/facebook/react-native/blob/0.63-stable/ReactCommon/hermes/inspector/Inspector.cpp#L231>code here</a>
182
- currentReactInstanceManager.get()?.devSupportManager?.handleReloadJS()
183
177
  }
184
178
  }
185
179
  }
@@ -224,19 +218,19 @@ object DevMenuManager : DevMenuManagerInterface, LifecycleEventListener {
224
218
  Log.i(DEV_MENU_TAG, "Delegate's context was loaded.")
225
219
 
226
220
  maybeInitDevMenuHost(reactContext.currentActivity?.application
227
- ?: reactContext.applicationContext as Application)
221
+ ?: reactContext.applicationContext as Application)
228
222
  maybeStartDetectors(devMenuHost.getContext())
229
223
  preferences = (testInterceptor.overrideSettings()
230
- ?: if (reactContext.hasNativeModule(DevMenuPreferences::class.java)) {
231
- reactContext.getNativeModule(DevMenuPreferences::class.java)!!
232
- } else {
233
- DevMenuDefaultPreferences()
234
- }).also {
235
- shouldLaunchDevMenuOnStart = canLaunchDevMenuOnStart && (it.showsAtLaunch || !it.isOnboardingFinished)
236
- if (shouldLaunchDevMenuOnStart) {
237
- reactContext.addLifecycleEventListener(this)
238
- }
239
- }
224
+ ?: if (reactContext.hasNativeModule(DevMenuPreferences::class.java)) {
225
+ reactContext.getNativeModule(DevMenuPreferences::class.java)!!
226
+ } else {
227
+ DevMenuDefaultPreferences()
228
+ }).also {
229
+ shouldLaunchDevMenuOnStart = canLaunchDevMenuOnStart && (it.showsAtLaunch || !it.isOnboardingFinished)
230
+ if (shouldLaunchDevMenuOnStart) {
231
+ reactContext.addLifecycleEventListener(this)
232
+ }
233
+ }
240
234
  }
241
235
 
242
236
  fun getAppInfo(): Bundle {
@@ -260,6 +254,7 @@ object DevMenuManager : DevMenuManagerInterface, LifecycleEventListener {
260
254
  if (fontsWereLoaded) {
261
255
  return
262
256
  }
257
+ fontsWereLoaded = true
263
258
 
264
259
  val fonts = arrayOf(
265
260
  "Inter-Black",
@@ -279,8 +274,6 @@ object DevMenuManager : DevMenuManagerInterface, LifecycleEventListener {
279
274
  val font = Typeface.createFromAsset(assets, "$familyName.otf")
280
275
  ReactFontManager.getInstance().setTypeface(familyName, Typeface.NORMAL, font)
281
276
  }
282
-
283
- fontsWereLoaded = true
284
277
  }
285
278
 
286
279
  //endregion
@@ -1,37 +1,14 @@
1
1
  package expo.modules.devmenu.modules.internals
2
2
 
3
- import android.graphics.Typeface
4
3
  import com.facebook.react.bridge.Promise
5
4
  import com.facebook.react.bridge.ReactApplicationContext
6
- import com.facebook.react.views.text.ReactFontManager
5
+ import expo.modules.devmenu.DevMenuManager
7
6
  import expo.modules.devmenu.modules.DevMenuInternalFontManagerModuleInterface
8
7
 
9
- private var fontsWereLoaded = false
10
-
11
8
  class DevMenuInternalFontManagerModule(private val reactContext: ReactApplicationContext) :
12
9
  DevMenuInternalFontManagerModuleInterface {
13
10
  override fun loadFontsAsync(promise: Promise) {
14
- if (fontsWereLoaded) {
15
- promise.resolve(null)
16
- return
17
- }
18
-
19
- val fonts = mapOf(
20
- "Material Design Icons" to "MaterialCommunityIcons.ttf",
21
- "Ionicons" to "Ionicons.ttf"
22
- )
23
-
24
- val assets = reactContext.applicationContext.assets
25
- fonts.map { (familyName, fontFile) ->
26
- val font = Typeface.createFromAsset(assets, fontFile)
27
- if (font == null) {
28
- promise.reject("ERR_DEVMENU_CANNOT_CREATE_FONT", "Couldn't create $familyName font.")
29
- return
30
- }
31
- ReactFontManager.getInstance().setTypeface(familyName, Typeface.NORMAL, font)
32
- }
33
-
34
- fontsWereLoaded = true
11
+ DevMenuManager.loadFonts(reactContext)
35
12
  promise.resolve(null)
36
13
  }
37
14
  }
@@ -3,14 +3,11 @@ package expo.modules.devmenu.modules.internals
3
3
  import android.content.ClipData
4
4
  import android.content.ClipboardManager
5
5
  import android.content.Context
6
- import android.content.pm.PackageManager
7
6
  import com.facebook.react.bridge.Arguments
8
7
  import com.facebook.react.bridge.Promise
9
8
  import com.facebook.react.bridge.ReactContext
10
9
  import com.facebook.react.bridge.ReadableMap
11
- import com.facebook.react.devsupport.DevInternalSettings
12
10
  import expo.modules.devmenu.DevMenuManager
13
- import expo.modules.devmenu.devtools.DevMenuDevToolsDelegate
14
11
  import expo.modules.devmenu.modules.DevMenuInternalMenuControllerModuleInterface
15
12
  import kotlinx.coroutines.launch
16
13
 
@@ -7,6 +7,7 @@ import android.view.MotionEvent
7
7
  import com.facebook.react.ReactInstanceManager
8
8
  import com.facebook.react.ReactNativeHost
9
9
  import com.facebook.react.bridge.ReadableMap
10
+ import com.facebook.react.bridge.ReactApplicationContext
10
11
  import expo.interfaces.devmenu.DevMenuDelegateInterface
11
12
  import expo.interfaces.devmenu.DevMenuManagerInterface
12
13
  import expo.interfaces.devmenu.DevMenuPreferencesInterface
@@ -114,6 +115,10 @@ object DevMenuManager : DevMenuManagerInterface {
114
115
  throw IllegalStateException(DEV_MENU_IS_NOT_AVAILABLE)
115
116
  }
116
117
 
118
+ fun loadFonts(applicationContext: ReactApplicationContext) {
119
+ throw IllegalStateException(DEV_MENU_IS_NOT_AVAILABLE)
120
+ }
121
+
117
122
  override val coroutineScope: CoroutineScope
118
123
  get() = throw IllegalStateException(DEV_MENU_IS_NOT_AVAILABLE)
119
124
  }
package/app/App.tsx CHANGED
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { AppProviders } from './components/AppProviders';
4
+ import { LoadInitialData } from './components/LoadInitialData';
4
5
  import { Main } from './components/Main';
5
6
  import { Onboarding } from './components/Onboarding';
7
+ import { Splash } from './components/Splash';
6
8
  import { AppInfo, DevSettings, MenuPreferences } from './native-modules/DevMenu';
7
9
 
8
10
  type DevMenuInitialProps = {
@@ -15,8 +17,10 @@ type DevMenuInitialProps = {
15
17
  export function App({ devSettings, appInfo, menuPreferences, isDevice }: DevMenuInitialProps) {
16
18
  return (
17
19
  <AppProviders appInfo={appInfo} devSettings={devSettings} menuPreferences={menuPreferences}>
18
- <Main />
19
- <Onboarding isDevice={isDevice} />
20
+ <LoadInitialData loader={<Splash />}>
21
+ <Main />
22
+ <Onboarding isDevice={isDevice} />
23
+ </LoadInitialData>
20
24
  </AppProviders>
21
25
  );
22
26
  }
@@ -0,0 +1,26 @@
1
+ import { View } from 'expo-dev-client-components';
2
+ import * as React from 'react';
3
+
4
+ import { loadFontsAsync } from '../native-modules/DevMenu';
5
+ import { Splash } from './Splash';
6
+
7
+ type LoadInitialDataProps = {
8
+ children: React.ReactElement<any>[];
9
+ loader?: React.ReactElement<any>;
10
+ };
11
+
12
+ export function LoadInitialData({ children, loader = <Splash /> }: LoadInitialDataProps) {
13
+ const [isLoading, setIsLoading] = React.useState(true);
14
+
15
+ React.useEffect(() => {
16
+ loadFontsAsync().then(() => {
17
+ setIsLoading(false);
18
+ });
19
+ }, []);
20
+
21
+ if (isLoading) {
22
+ return loader;
23
+ }
24
+
25
+ return <View flex="1">{children}</View>;
26
+ }
@@ -64,9 +64,10 @@ export function Main() {
64
64
 
65
65
  return (
66
66
  <View flex="1" bg="secondary">
67
- <View padding="medium" bg="default">
67
+ <View py="medium" bg="default">
68
68
  <Row align="start">
69
- <Row align="center">
69
+ <Spacer.Horizontal size="medium" />
70
+ <Row align="center" shrink="1">
70
71
  <View>
71
72
  <View height="xl" width="xl" overflow="hidden" bg="secondary" rounded="medium">
72
73
  {Boolean(appInfo.appIcon) && (
@@ -80,8 +81,13 @@ export function Main() {
80
81
 
81
82
  <Spacer.Horizontal size="small" />
82
83
 
83
- <View>
84
- <Heading weight="bold">{appInfo.appName}</Heading>
84
+ <View shrink="1">
85
+ <Row style={{ flexWrap: 'wrap' }}>
86
+ <Heading weight="bold" numberOfLines={1}>
87
+ {appInfo.appName}
88
+ </Heading>
89
+ </Row>
90
+
85
91
  {Boolean(appInfo.runtimeVersion) && (
86
92
  <>
87
93
  <Text size="small" color="secondary">
@@ -98,20 +104,25 @@ export function Main() {
98
104
  </>
99
105
  )}
100
106
  </View>
101
- </Row>
102
107
 
103
- <Spacer.Horizontal />
104
- <GestureHandlerTouchableWrapper onPress={bottomSheet.collapse}>
105
- <Button.ScaleOnPressContainer
106
- onPress={bottomSheet.collapse}
107
- bg="ghost"
108
- rounded="full"
109
- minScale={0.8}>
110
- <View padding="micro">
111
- <XIcon />
112
- </View>
113
- </Button.ScaleOnPressContainer>
114
- </GestureHandlerTouchableWrapper>
108
+ <Spacer.Horizontal />
109
+
110
+ <View width="large" style={{ alignSelf: 'flex-start' }}>
111
+ <GestureHandlerTouchableWrapper onPress={bottomSheet.collapse}>
112
+ <Button.ScaleOnPressContainer
113
+ onPress={bottomSheet.collapse}
114
+ bg="ghost"
115
+ rounded="full"
116
+ minScale={0.8}>
117
+ <View padding="micro">
118
+ <XIcon />
119
+ </View>
120
+ </Button.ScaleOnPressContainer>
121
+ </GestureHandlerTouchableWrapper>
122
+ </View>
123
+
124
+ <Spacer.Horizontal size="small" />
125
+ </Row>
115
126
  </Row>
116
127
  </View>
117
128
 
@@ -237,6 +248,7 @@ export function Main() {
237
248
  bg="default"
238
249
  roundedTop="none"
239
250
  roundedBottom="large"
251
+ onPress={onCopyAppInfoPress}
240
252
  disabled={hasCopiedAppInfoContent}>
241
253
  <Row px="medium" py="small" align="center" bg="default">
242
254
  <Text color="link" size="medium">
@@ -0,0 +1,12 @@
1
+ import { View, ExpoLogoIcon } from 'expo-dev-client-components';
2
+ import * as React from 'react';
3
+
4
+ const iconWidth = 85;
5
+
6
+ export function Splash() {
7
+ return (
8
+ <View flex="1" style={{ justifyContent: 'center', alignItems: 'center' }} bg="default">
9
+ <ExpoLogoIcon style={{ width: iconWidth, resizeMode: 'contain' }} resizeMode="contain" />
10
+ </View>
11
+ );
12
+ }
package/app/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AppRegistry } from 'react-native';
2
2
  import { enableScreens } from 'react-native-screens';
3
3
 
4
- import { App } from './App'
4
+ import { App } from './App';
5
5
 
6
6
  enableScreens(false);
7
7
 
@@ -76,3 +76,7 @@ export async function copyToClipboardAsync(content: string) {
76
76
  export async function setOnboardingFinishedAsync(isFinished: boolean) {
77
77
  return await DevMenu.setOnboardingFinished(isFinished);
78
78
  }
79
+
80
+ export async function loadFontsAsync() {
81
+ return await DevMenu.loadFontsAsync();
82
+ }