expo-dev-launcher 5.2.0-canary-20250713-8f814f8 → 5.2.0-canary-20250729-d8899ae
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 +1 -0
- package/android/build.gradle +7 -3
- package/android/src/debug/AndroidManifest.xml +4 -2
- package/android/src/debug/java/expo/modules/devlauncher/DevLauncherController.kt +34 -23
- package/android/src/debug/java/expo/modules/devlauncher/DevLauncherPackageDelegate.kt +1 -3
- package/android/src/debug/java/expo/modules/devlauncher/compose/AuthActivity.kt +2 -2
- package/android/src/debug/java/expo/modules/devlauncher/compose/DevLauncherBottomTabsNavigator.kt +69 -20
- package/android/src/debug/java/expo/modules/devlauncher/compose/UpdatesModels.kt +14 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/models/BranchViewModel.kt +105 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/models/BranchesViewModel.kt +113 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/models/CrashReportModel.kt +22 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/models/ErrorViewModel.kt +50 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/models/HomeViewModel.kt +115 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/{ProfileViewModel.kt → models/ProfileViewModel.kt} +2 -1
- package/android/src/debug/java/expo/modules/devlauncher/compose/models/SettingsViewModel.kt +89 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/Accordion.kt +4 -4
- package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/Asyncimage.kt +1 -2
- package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/CircularProgressBar.kt +89 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/routes/CrashReport.kt +38 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Home.kt +32 -7
- package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Profile.kt +2 -2
- package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Routes.kt +20 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Settings.kt +7 -5
- package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Updates.kt +81 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/BranchScreen.kt +234 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/BranchesScreen.kt +261 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/CrashReportScreen.kt +191 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/ErrorScreen.kt +79 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/HomeScreen.kt +251 -71
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/NoUpdatesScreen.kt +72 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/screens/SettingsScreen.kt +93 -11
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AccountAvatar.kt +3 -4
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AccountSelector.kt +8 -7
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/ActionButton.kt +3 -1
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AppHeader.kt +38 -6
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/BottomTabBar.kt +10 -6
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/BottomTabButton.kt +6 -3
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/DevelopmentServerHelp.kt +1 -5
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/ProfileLayout.kt +4 -6
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/RunningAppCard.kt +19 -27
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/ScreenHeaderContainer.kt +2 -1
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/SectionHeader.kt +0 -24
- package/android/src/debug/java/expo/modules/devlauncher/compose/ui/ServerUrlInput.kt +79 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/utils/DateFormat.kt +40 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/utils/UpdatesUtils.kt +12 -0
- package/android/src/debug/java/expo/modules/devlauncher/compose/utils/WithIsLast.kt +32 -0
- package/android/src/debug/java/expo/modules/devlauncher/launcher/DevLauncherActivity.kt +11 -105
- package/android/src/debug/java/expo/modules/devlauncher/launcher/errors/DevLauncherErrorActivity.kt +27 -96
- package/android/src/debug/java/expo/modules/devlauncher/services/ApolloClientService.kt +53 -0
- package/android/src/debug/java/expo/modules/devlauncher/services/AppService.kt +82 -0
- package/android/src/debug/java/expo/modules/devlauncher/services/DependencyInjection.kt +17 -16
- package/android/src/debug/java/expo/modules/devlauncher/services/ErrorRegistryService.kt +13 -0
- package/android/src/debug/java/expo/modules/devlauncher/services/ImageLoaderService.kt +17 -5
- package/android/src/debug/java/expo/modules/devlauncher/services/PackagerService.kt +22 -5
- package/android/src/debug/java/expo/modules/devlauncher/services/SessionService.kt +1 -6
- package/android/src/debug/res/drawable-mdpi/qr_code.png +0 -0
- package/android/src/debug/res/drawable-night-mdpi/qr_code.png +0 -0
- package/android/src/debug/res/drawable-night-xhdpi/qr_code.png +0 -0
- package/android/src/debug/res/drawable-night-xxhdpi/qr_code.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/qr_code.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/qr_code.png +0 -0
- package/android/src/main/AndroidManifest.xml +6 -1
- package/android/src/main/graphql/GetBranches.graphql +17 -5
- package/android/src/main/graphql/GetUpdates.graphql +0 -13
- package/android/src/main/java/com/facebook/react/devsupport/DevLauncherDevServerHelper.kt +3 -3
- package/android/src/main/java/expo/modules/devlauncher/launcher/DevLauncherControllerInterface.kt +0 -1
- package/android/src/main/java/expo/modules/devlauncher/launcher/DevLauncherRecentlyOpenedAppsRegistry.kt +10 -9
- package/android/src/main/java/expo/modules/devlauncher/launcher/errors/DevLauncherErrorRegistry.kt +7 -6
- package/android/src/main/java/expo/modules/devlauncher/splashscreen/DevLauncherSplashScreen.kt +0 -2
- package/android/src/main/res/values/styles.xml +0 -14
- package/android/src/release/java/expo/modules/devlauncher/DevLauncherController.kt +0 -3
- package/expo-module.config.json +0 -1
- package/ios/EXDevLauncherUtils.swift +0 -9
- package/package.json +4 -4
- package/android/src/debug/assets/expo_dev_launcher_android.bundle +0 -1418
- package/android/src/debug/java/expo/modules/devlauncher/compose/HomeViewModel.kt +0 -95
- package/android/src/debug/java/expo/modules/devlauncher/launcher/DevLauncherReactHost.kt +0 -104
- package/android/src/debug/java/expo/modules/devlauncher/launcher/DevLauncherReactNativeHost.kt +0 -65
- package/android/src/debug/java/expo/modules/devlauncher/modules/DevLauncherAuth.kt +0 -72
- package/android/src/debug/res/drawable-mdpi/__node_modules_reactnavigation_elements_lib_module_assets_backicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/__node_modules_reactnavigation_elements_lib_module_assets_backiconmask.png +0 -0
- package/android/src/debug/res/drawable-mdpi/__node_modules_reactnavigation_elements_lib_module_assets_clearicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/__node_modules_reactnavigation_elements_lib_module_assets_closeicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/__node_modules_reactnavigation_elements_lib_module_assets_searchicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_branchiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_checkiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_clipboardicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_debugicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_extensionsfilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_extensionsfilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_extensionsfilledinactiveicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_extensionsfilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_extensionsiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_homefilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_homefilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_homefilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_infoiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_inspectelementicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_loadingindicatoricon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_logoicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_performanceicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_questionmarkicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_refreshicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_runicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_settingsfilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_settingsfilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_settingsfilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_showmenuatlaunchiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_threefingerlongpressiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_toolbaroverlayicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_updateiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_usericonlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_warningtriangleicon.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_warningtriangleiconlight.png +0 -0
- package/android/src/debug/res/drawable-mdpi/_expodevclientcomponents_assets_xiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/__node_modules_reactnavigation_elements_lib_module_assets_backicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/__node_modules_reactnavigation_elements_lib_module_assets_clearicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/__node_modules_reactnavigation_elements_lib_module_assets_closeicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/__node_modules_reactnavigation_elements_lib_module_assets_searchicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_branchiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_checkiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_clipboardicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_debugicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_extensionsfilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_extensionsfilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_extensionsfilledinactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_extensionsfilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_extensionsiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_homefilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_homefilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_homefilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_infoiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_inspectelementicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_loadingindicatoricon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_logoicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_performanceicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_questionmarkicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_refreshicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_runicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_settingsfilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_settingsfilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_settingsfilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_showmenuatlaunchiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_threefingerlongpressiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_toolbaroverlayicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_updateiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_usericonlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_warningtriangleicon.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_warningtriangleiconlight.png +0 -0
- package/android/src/debug/res/drawable-xhdpi/_expodevclientcomponents_assets_xiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_backicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_clearicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_closeicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_searchicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_branchiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_checkiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_clipboardicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_debugicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_extensionsfilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_extensionsfilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_extensionsfilledinactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_extensionsfilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_extensionsiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_homefilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_homefilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_homefilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_infoiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_inspectelementicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_loadingindicatoricon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_logoicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_performanceicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_questionmarkicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_refreshicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_runicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_settingsfilledactiveicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_settingsfilledactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_settingsfilledinactiveiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_showmenuatlaunchiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_threefingerlongpressiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_toolbaroverlayicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_updateiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_usericonlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_warningtriangleicon.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_warningtriangleiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxhdpi/_expodevclientcomponents_assets_xiconlight.png +0 -0
- package/android/src/debug/res/drawable-xxxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_backicon.png +0 -0
- package/android/src/debug/res/drawable-xxxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_clearicon.png +0 -0
- package/android/src/debug/res/drawable-xxxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_closeicon.png +0 -0
- package/android/src/debug/res/drawable-xxxhdpi/__node_modules_reactnavigation_elements_lib_module_assets_searchicon.png +0 -0
- package/android/src/main/java/expo/modules/devlauncher/modules/DevLauncherInternalModule.kt +0 -234
- package/android/src/main/res/drawable-mdpi/_expodevclientcomponents_assets_logoicon.png +0 -0
- package/android/src/main/res/drawable-xhdpi/_expodevclientcomponents_assets_logoicon.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/_expodevclientcomponents_assets_logoicon.png +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_branchicon.png → branch_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_buildingicon.png → building_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_checkicon.png → check_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_chevronrighticon.png → chevron_right_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_extensionsicon.png → extensions_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_homefilledinactiveicon.png → home_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_infoicon.png → info_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_settingsfilledinactiveicon.png → settings_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_shakedeviceicon.png → shake_device_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_showmenuatlaunchicon.png → show_menu_at_launch_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_terminalicon.png → terminal_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_threefingerlongpressicon.png → three_finger_long_press_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_updateicon.png → update_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_usericon.png → user_icon.png} +0 -0
- /package/android/src/debug/res/drawable-mdpi/{_expodevclientcomponents_assets_xicon.png → x_icon.png} +0 -0
- /package/android/src/debug/res/{drawable-mdpi/_expodevclientcomponents_assets_shakedeviceiconlight.png → drawable-night-mdpi/shake_device_icon.png} +0 -0
- /package/android/src/debug/res/{drawable-xhdpi/_expodevclientcomponents_assets_shakedeviceiconlight.png → drawable-night-xhdpi/shake_device_icon.png} +0 -0
- /package/android/src/debug/res/{drawable-xxhdpi/_expodevclientcomponents_assets_shakedeviceiconlight.png → drawable-night-xxhdpi/shake_device_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_branchicon.png → branch_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_buildingicon.png → building_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_checkicon.png → check_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_chevronrighticon.png → chevron_right_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_extensionsicon.png → extensions_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_homefilledinactiveicon.png → home_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_infoicon.png → info_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_settingsfilledinactiveicon.png → settings_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_shakedeviceicon.png → shake_device_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_showmenuatlaunchicon.png → show_menu_at_launch_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_terminalicon.png → terminal_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_threefingerlongpressicon.png → three_finger_long_press_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_updateicon.png → update_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_usericon.png → user_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xhdpi/{_expodevclientcomponents_assets_xicon.png → x_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_branchicon.png → branch_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_buildingicon.png → building_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_checkicon.png → check_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_chevronrighticon.png → chevron_right_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_extensionsicon.png → extensions_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_homefilledinactiveicon.png → home_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_infoicon.png → info_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_settingsfilledinactiveicon.png → settings_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_shakedeviceicon.png → shake_device_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_showmenuatlaunchicon.png → show_menu_at_launch_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_terminalicon.png → terminal_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_threefingerlongpressicon.png → three_finger_long_press_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_updateicon.png → update_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_usericon.png → user_icon.png} +0 -0
- /package/android/src/debug/res/drawable-xxhdpi/{_expodevclientcomponents_assets_xicon.png → x_icon.png} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
### 🎉 New features
|
|
8
8
|
|
|
9
9
|
- [iOS] Reimplement UI in SwiftUI. ([#37413](https://github.com/expo/expo/pull/37413) by [@alanjhughes](https://github.com/alanjhughes))
|
|
10
|
+
- [Android] Add floating action button option in the settings menu. ([#38247](https://github.com/expo/expo/pull/38247) by [@behenate](https://github.com/behenate))
|
|
10
11
|
|
|
11
12
|
### 🐛 Bug fixes
|
|
12
13
|
|
package/android/build.gradle
CHANGED
|
@@ -20,13 +20,13 @@ expoModule {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
group = "host.exp.exponent"
|
|
23
|
-
version = "5.2.0-canary-
|
|
23
|
+
version = "5.2.0-canary-20250729-d8899ae"
|
|
24
24
|
|
|
25
25
|
android {
|
|
26
26
|
namespace "expo.modules.devlauncher"
|
|
27
27
|
defaultConfig {
|
|
28
28
|
versionCode 9
|
|
29
|
-
versionName "5.2.0-canary-
|
|
29
|
+
versionName "5.2.0-canary-20250729-d8899ae"
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
buildTypes {
|
|
@@ -97,10 +97,14 @@ dependencies {
|
|
|
97
97
|
implementation "androidx.compose.ui:ui:$composeVersion"
|
|
98
98
|
implementation "androidx.compose.ui:ui-tooling:$composeVersion"
|
|
99
99
|
implementation "androidx.navigation:navigation-compose:2.9.0"
|
|
100
|
+
implementation "com.google.android.gms:play-services-code-scanner:16.1.0"
|
|
101
|
+
implementation "com.google.mlkit:barcode-scanning:17.3.0"
|
|
102
|
+
|
|
103
|
+
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1")
|
|
100
104
|
|
|
101
105
|
implementation("com.apollographql.apollo:apollo-runtime:4.3.1")
|
|
102
106
|
|
|
103
|
-
implementation("com.composables:core:1.
|
|
107
|
+
implementation("com.composables:core:1.37.0")
|
|
104
108
|
|
|
105
109
|
testImplementation 'androidx.test:core:1.4.0'
|
|
106
110
|
testImplementation 'androidx.test:core-ktx:1.4.0'
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
|
|
2
3
|
<application>
|
|
3
4
|
<activity
|
|
4
5
|
android:name="expo.modules.devlauncher.launcher.DevLauncherActivity"
|
|
5
6
|
android:exported="true"
|
|
6
7
|
android:launchMode="singleTask"
|
|
7
|
-
android:theme="@style/Theme.
|
|
8
|
+
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
|
|
8
9
|
|
|
9
10
|
<activity
|
|
10
11
|
android:name="expo.modules.devlauncher.compose.AuthActivity"
|
|
11
12
|
android:exported="true"
|
|
12
|
-
android:launchMode="singleTask"
|
|
13
|
+
android:launchMode="singleTask"
|
|
14
|
+
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">
|
|
13
15
|
<intent-filter>
|
|
14
16
|
<action android:name="android.intent.action.VIEW" />
|
|
15
17
|
|
|
@@ -5,7 +5,9 @@ import android.content.Context
|
|
|
5
5
|
import android.content.Intent
|
|
6
6
|
import android.net.Uri
|
|
7
7
|
import android.os.Bundle
|
|
8
|
+
import android.util.Log
|
|
8
9
|
import androidx.annotation.UiThread
|
|
10
|
+
import androidx.core.net.toUri
|
|
9
11
|
import com.facebook.react.ReactActivity
|
|
10
12
|
import com.facebook.react.ReactActivityDelegate
|
|
11
13
|
import com.facebook.react.ReactApplication
|
|
@@ -30,8 +32,6 @@ import expo.modules.devlauncher.launcher.DevLauncherIntentRegistryInterface
|
|
|
30
32
|
import expo.modules.devlauncher.launcher.DevLauncherLifecycle
|
|
31
33
|
import expo.modules.devlauncher.launcher.DevLauncherNetworkInterceptor
|
|
32
34
|
import expo.modules.devlauncher.launcher.DevLauncherReactActivityDelegateSupplier
|
|
33
|
-
import expo.modules.devlauncher.launcher.DevLauncherReactHost
|
|
34
|
-
import expo.modules.devlauncher.launcher.DevLauncherReactNativeHost
|
|
35
35
|
import expo.modules.devlauncher.launcher.DevLauncherRecentlyOpenedAppsRegistry
|
|
36
36
|
import expo.modules.devlauncher.launcher.errors.DevLauncherAppError
|
|
37
37
|
import expo.modules.devlauncher.launcher.errors.DevLauncherErrorActivity
|
|
@@ -40,6 +40,7 @@ import expo.modules.devlauncher.launcher.loaders.DevLauncherAppLoaderFactoryInte
|
|
|
40
40
|
import expo.modules.devlauncher.launcher.manifest.DevLauncherManifestParser
|
|
41
41
|
import expo.modules.devlauncher.react.activitydelegates.DevLauncherReactActivityNOPDelegate
|
|
42
42
|
import expo.modules.devlauncher.react.activitydelegates.DevLauncherReactActivityRedirectDelegate
|
|
43
|
+
import expo.modules.devlauncher.services.DependencyInjection
|
|
43
44
|
import expo.modules.devlauncher.tests.DevLauncherTestInterceptor
|
|
44
45
|
import expo.modules.devmenu.DevMenuManager
|
|
45
46
|
import expo.modules.manifests.core.Manifest
|
|
@@ -52,10 +53,6 @@ import org.koin.core.component.get
|
|
|
52
53
|
import org.koin.core.component.inject
|
|
53
54
|
import org.koin.dsl.module
|
|
54
55
|
|
|
55
|
-
// Use this to load from a development server for the development client launcher UI
|
|
56
|
-
// private val DEV_LAUNCHER_HOST = "10.0.0.175:8090";
|
|
57
|
-
private val DEV_LAUNCHER_HOST: String? = null
|
|
58
|
-
|
|
59
56
|
private const val NEW_ACTIVITY_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK or
|
|
60
57
|
Intent.FLAG_ACTIVITY_CLEAR_TASK or
|
|
61
58
|
Intent.FLAG_ACTIVITY_NO_ANIMATION
|
|
@@ -74,27 +71,29 @@ class DevLauncherController private constructor() :
|
|
|
74
71
|
var devMenuManager: DevMenuManager = DevMenuManager
|
|
75
72
|
override var updatesInterface: UpdatesInterface?
|
|
76
73
|
get() = internalUpdatesInterface
|
|
77
|
-
set(value) =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
set(value) = run {
|
|
75
|
+
if (value != null) {
|
|
76
|
+
DependencyInjection.appService.setUpUpdateInterface(value, context)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
DevLauncherKoinContext.app.koin.loadModules(
|
|
80
|
+
listOf(
|
|
81
|
+
module {
|
|
82
|
+
single { value }
|
|
83
|
+
}
|
|
84
|
+
)
|
|
82
85
|
)
|
|
83
|
-
|
|
84
|
-
override val coroutineScope = CoroutineScope(Dispatchers.Default)
|
|
86
|
+
}
|
|
85
87
|
|
|
86
|
-
override val
|
|
87
|
-
ReactHostWrapper(
|
|
88
|
-
reactNativeHost = DevLauncherReactNativeHost(context as Application, DEV_LAUNCHER_HOST),
|
|
89
|
-
reactHostProvider = { DevLauncherReactHost.create(context as Application, DEV_LAUNCHER_HOST) }
|
|
90
|
-
)
|
|
91
|
-
}
|
|
88
|
+
override val coroutineScope = CoroutineScope(Dispatchers.Default)
|
|
92
89
|
|
|
93
90
|
private val recentlyOpedAppsRegistry = DevLauncherRecentlyOpenedAppsRegistry(context)
|
|
94
91
|
override var manifest: Manifest? = null
|
|
95
92
|
private set
|
|
93
|
+
|
|
96
94
|
override var manifestURL: Uri? = null
|
|
97
95
|
private set
|
|
96
|
+
|
|
98
97
|
override var latestLoadedApp: Uri? = null
|
|
99
98
|
override var useDeveloperSupport = true
|
|
100
99
|
var canLaunchDevMenuOnStart = false
|
|
@@ -144,7 +143,7 @@ class DevLauncherController private constructor() :
|
|
|
144
143
|
// default to the EXPO_UPDATE_URL value configured in AndroidManifest.xml when project url is unspecified for an EAS update
|
|
145
144
|
if (isEASUpdate && projectUrl == null) {
|
|
146
145
|
val projectUrlString = getMetadataValue(context, "expo.modules.updates.EXPO_UPDATE_URL")
|
|
147
|
-
parsedProjectUrl =
|
|
146
|
+
parsedProjectUrl = projectUrlString.toUri()
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
val manifestParser = DevLauncherManifestParser(httpClient, parsedUrl, installationIDHelper.getOrCreateInstallationID(context))
|
|
@@ -206,7 +205,8 @@ class DevLauncherController private constructor() :
|
|
|
206
205
|
}
|
|
207
206
|
}
|
|
208
207
|
|
|
209
|
-
override fun getRecentlyOpenedApps(): List<DevLauncherAppEntry> =
|
|
208
|
+
override fun getRecentlyOpenedApps(): List<DevLauncherAppEntry> =
|
|
209
|
+
recentlyOpedAppsRegistry.getRecentlyOpenedApps()
|
|
210
210
|
|
|
211
211
|
override fun clearRecentlyOpenedApps() {
|
|
212
212
|
recentlyOpedAppsRegistry.clearRegistry()
|
|
@@ -270,8 +270,8 @@ class DevLauncherController private constructor() :
|
|
|
270
270
|
if (shouldTryToLaunchLastOpenedBundle && lastOpenedApp != null) {
|
|
271
271
|
coroutineScope.launch {
|
|
272
272
|
try {
|
|
273
|
-
loadApp(
|
|
274
|
-
} catch (
|
|
273
|
+
loadApp(lastOpenedApp.url.toUri(), activityToBeInvalidated)
|
|
274
|
+
} catch (_: Throwable) {
|
|
275
275
|
navigateToLauncher()
|
|
276
276
|
}
|
|
277
277
|
}
|
|
@@ -415,6 +415,17 @@ class DevLauncherController private constructor() :
|
|
|
415
415
|
|
|
416
416
|
@JvmStatic
|
|
417
417
|
internal fun initialize(context: Context, reactHost: ReactHostWrapper) {
|
|
418
|
+
try {
|
|
419
|
+
val splashScreenManagerClass = Class.forName("expo.modules.splashscreen.SplashScreenManager")
|
|
420
|
+
val splashScreenManager = splashScreenManagerClass
|
|
421
|
+
.kotlin
|
|
422
|
+
.objectInstance
|
|
423
|
+
splashScreenManagerClass.getMethod("hide")
|
|
424
|
+
.invoke(splashScreenManager)
|
|
425
|
+
} catch (e: Throwable) {
|
|
426
|
+
Log.e("DevLauncherController", "Failed to hide splash screen", e)
|
|
427
|
+
}
|
|
428
|
+
|
|
418
429
|
val testInterceptor = DevLauncherKoinContext.app.koin.get<DevLauncherTestInterceptor>()
|
|
419
430
|
if (!testInterceptor.allowReinitialization()) {
|
|
420
431
|
check(!wasInitialized()) { "DevelopmentClientController was initialized." }
|
|
@@ -13,7 +13,6 @@ import expo.modules.core.interfaces.ReactActivityHandler
|
|
|
13
13
|
import expo.modules.core.interfaces.ReactActivityLifecycleListener
|
|
14
14
|
import expo.modules.devlauncher.launcher.DevLauncherReactActivityDelegateSupplier
|
|
15
15
|
import expo.modules.devlauncher.modules.DevLauncherModule
|
|
16
|
-
import expo.modules.devlauncher.modules.DevLauncherAuth
|
|
17
16
|
import expo.modules.core.interfaces.ReactNativeHostHandler
|
|
18
17
|
import expo.modules.devlauncher.modules.DevLauncherDevMenuExtension
|
|
19
18
|
import expo.modules.devlauncher.react.DevLauncherReactNativeHostHandler
|
|
@@ -22,8 +21,7 @@ object DevLauncherPackageDelegate {
|
|
|
22
21
|
fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
|
|
23
22
|
listOf(
|
|
24
23
|
DevLauncherModule(reactContext),
|
|
25
|
-
DevLauncherDevMenuExtension(reactContext)
|
|
26
|
-
DevLauncherAuth(reactContext)
|
|
24
|
+
DevLauncherDevMenuExtension(reactContext)
|
|
27
25
|
)
|
|
28
26
|
|
|
29
27
|
fun createApplicationLifecycleListeners(context: Context?): List<ApplicationLifecycleListener> =
|
|
@@ -35,10 +35,10 @@ sealed interface AuthResult {
|
|
|
35
35
|
|
|
36
36
|
class AuthActivity : AppCompatActivity() {
|
|
37
37
|
class Contract : ActivityResultContract<AuthRequestType, AuthResult>() {
|
|
38
|
-
override fun createIntent(context: Context,
|
|
38
|
+
override fun createIntent(context: Context, input: AuthRequestType): Intent {
|
|
39
39
|
return Intent(context, AuthActivity::class.java).apply {
|
|
40
40
|
action = ACTION_VIEW
|
|
41
|
-
putExtra(AUTH_REQUEST_TYPE_KEY,
|
|
41
|
+
putExtra(AUTH_REQUEST_TYPE_KEY, input.type)
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
package/android/src/debug/java/expo/modules/devlauncher/compose/DevLauncherBottomTabsNavigator.kt
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
package expo.modules.devlauncher.compose
|
|
2
2
|
|
|
3
|
+
import androidx.compose.animation.AnimatedContentTransitionScope
|
|
3
4
|
import androidx.compose.animation.EnterTransition
|
|
4
5
|
import androidx.compose.animation.ExitTransition
|
|
6
|
+
import androidx.compose.animation.core.tween
|
|
5
7
|
import androidx.compose.foundation.background
|
|
6
8
|
import androidx.compose.foundation.layout.Box
|
|
7
9
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
8
|
-
import androidx.compose.foundation.rememberScrollState
|
|
9
|
-
import androidx.compose.foundation.verticalScroll
|
|
10
10
|
import androidx.compose.runtime.Composable
|
|
11
|
+
import androidx.compose.runtime.remember
|
|
11
12
|
import androidx.compose.ui.Modifier
|
|
12
13
|
import androidx.compose.ui.graphics.painter.Painter
|
|
13
14
|
import androidx.navigation.compose.NavHost
|
|
14
15
|
import androidx.navigation.compose.composable
|
|
15
16
|
import androidx.navigation.compose.rememberNavController
|
|
16
17
|
import expo.modules.devlauncher.compose.primitives.DefaultScaffold
|
|
17
|
-
import expo.modules.devlauncher.compose.routes.
|
|
18
|
+
import expo.modules.devlauncher.compose.routes.CrashReport
|
|
19
|
+
import expo.modules.devlauncher.compose.routes.CrashReportRoute
|
|
18
20
|
import expo.modules.devlauncher.compose.routes.HomeRoute
|
|
19
21
|
import expo.modules.devlauncher.compose.routes.ProfileRoute
|
|
20
|
-
import expo.modules.devlauncher.compose.routes.
|
|
22
|
+
import expo.modules.devlauncher.compose.routes.Routes
|
|
21
23
|
import expo.modules.devlauncher.compose.routes.SettingsRoute
|
|
24
|
+
import expo.modules.devlauncher.compose.routes.UpdatesRoute
|
|
22
25
|
import expo.modules.devlauncher.compose.ui.BottomTabBar
|
|
23
26
|
import expo.modules.devlauncher.compose.ui.Full
|
|
24
27
|
import expo.modules.devlauncher.compose.ui.rememberBottomSheetState
|
|
25
28
|
import expo.modules.devmenu.compose.theme.Theme
|
|
29
|
+
import kotlinx.serialization.Serializable
|
|
26
30
|
|
|
27
31
|
@Composable
|
|
28
32
|
fun DefaultScreenContainer(
|
|
29
33
|
content: @Composable () -> Unit
|
|
30
34
|
) {
|
|
31
|
-
val scrollState = rememberScrollState()
|
|
32
|
-
|
|
33
35
|
Box(
|
|
34
36
|
modifier = Modifier
|
|
35
37
|
.fillMaxSize()
|
|
36
|
-
.verticalScroll(scrollState)
|
|
37
38
|
.background(Theme.colors.background.secondary)
|
|
38
39
|
) {
|
|
39
40
|
content()
|
|
@@ -46,30 +47,78 @@ data class Tab(
|
|
|
46
47
|
val screen: Any
|
|
47
48
|
)
|
|
48
49
|
|
|
50
|
+
@Serializable
|
|
51
|
+
object Main
|
|
52
|
+
|
|
49
53
|
@Composable
|
|
50
54
|
fun DevLauncherBottomTabsNavigator() {
|
|
51
|
-
val
|
|
55
|
+
val mainNavController = rememberNavController()
|
|
56
|
+
val bottomTabsNavController = rememberNavController()
|
|
52
57
|
val bottomSheetState = rememberBottomSheetState()
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
val navigateToProfile = remember {
|
|
60
|
+
{ bottomSheetState.targetDetent = Full }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
NavHost(
|
|
64
|
+
navController = mainNavController,
|
|
65
|
+
startDestination = Main
|
|
66
|
+
) {
|
|
67
|
+
composable<Main>(
|
|
60
68
|
enterTransition = {
|
|
61
|
-
|
|
69
|
+
slideIntoContainer(
|
|
70
|
+
AnimatedContentTransitionScope.SlideDirection.Right,
|
|
71
|
+
animationSpec = tween(700)
|
|
72
|
+
)
|
|
62
73
|
},
|
|
63
74
|
exitTransition = {
|
|
64
|
-
|
|
75
|
+
slideOutOfContainer(
|
|
76
|
+
AnimatedContentTransitionScope.SlideDirection.Left,
|
|
77
|
+
animationSpec = tween(700)
|
|
78
|
+
)
|
|
65
79
|
}
|
|
66
80
|
) {
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
DefaultScaffold(bottomTab = {
|
|
82
|
+
BottomTabBar(bottomTabsNavController)
|
|
83
|
+
}) {
|
|
84
|
+
NavHost(
|
|
85
|
+
navController = bottomTabsNavController,
|
|
86
|
+
startDestination = Routes.Home,
|
|
87
|
+
enterTransition = {
|
|
88
|
+
EnterTransition.None
|
|
89
|
+
},
|
|
90
|
+
exitTransition = {
|
|
91
|
+
ExitTransition.None
|
|
92
|
+
}
|
|
93
|
+
) {
|
|
94
|
+
composable<Routes.Home> {
|
|
95
|
+
HomeRoute(navController = mainNavController, onProfileClick = navigateToProfile)
|
|
96
|
+
}
|
|
97
|
+
composable<Routes.Updates> {
|
|
98
|
+
UpdatesRoute(onProfileClick = navigateToProfile)
|
|
99
|
+
}
|
|
100
|
+
composable<Routes.Settings> {
|
|
101
|
+
SettingsRoute()
|
|
102
|
+
}
|
|
103
|
+
}
|
|
69
104
|
}
|
|
70
|
-
|
|
71
|
-
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
composable<CrashReport>(
|
|
108
|
+
enterTransition = {
|
|
109
|
+
slideIntoContainer(
|
|
110
|
+
AnimatedContentTransitionScope.SlideDirection.Left,
|
|
111
|
+
animationSpec = tween(700)
|
|
112
|
+
)
|
|
113
|
+
},
|
|
114
|
+
exitTransition = {
|
|
115
|
+
slideOutOfContainer(
|
|
116
|
+
AnimatedContentTransitionScope.SlideDirection.Right,
|
|
117
|
+
animationSpec = tween(700)
|
|
118
|
+
)
|
|
72
119
|
}
|
|
120
|
+
) {
|
|
121
|
+
CrashReportRoute()
|
|
73
122
|
}
|
|
74
123
|
}
|
|
75
124
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package expo.modules.devlauncher.compose
|
|
2
|
+
|
|
3
|
+
data class Update(
|
|
4
|
+
val id: String,
|
|
5
|
+
val name: String,
|
|
6
|
+
val createdAt: String?,
|
|
7
|
+
val isCompatible: Boolean = false,
|
|
8
|
+
val permalink: String
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
data class Branch(
|
|
12
|
+
val name: String,
|
|
13
|
+
val compatibleUpdate: Update? = null
|
|
14
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
package expo.modules.devlauncher.compose.models
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.mutableStateOf
|
|
4
|
+
import androidx.lifecycle.ViewModel
|
|
5
|
+
import androidx.lifecycle.viewModelScope
|
|
6
|
+
import expo.modules.devlauncher.DevLauncherController
|
|
7
|
+
import expo.modules.devlauncher.compose.Update
|
|
8
|
+
import expo.modules.devlauncher.compose.utils.formatUpdateUrl
|
|
9
|
+
import expo.modules.devlauncher.services.ApolloClientService
|
|
10
|
+
import expo.modules.devlauncher.services.AppService
|
|
11
|
+
import expo.modules.devlauncher.services.ApplicationInfo
|
|
12
|
+
import expo.modules.devlauncher.services.inject
|
|
13
|
+
import kotlinx.coroutines.flow.MutableStateFlow
|
|
14
|
+
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
|
|
15
|
+
import kotlinx.coroutines.flow.onStart
|
|
16
|
+
import kotlinx.coroutines.flow.stateIn
|
|
17
|
+
import kotlinx.coroutines.launch
|
|
18
|
+
|
|
19
|
+
sealed interface BranchAction {
|
|
20
|
+
object LoadMoreUpdates : BranchAction
|
|
21
|
+
class OpenUpdate(val update: Update) : BranchAction
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
data class BranchState(
|
|
25
|
+
val updates: List<Update> = emptyList(),
|
|
26
|
+
val isLoading: Boolean = false
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
class BranchViewModel(private val branchName: String) : ViewModel() {
|
|
30
|
+
private val appService = inject<AppService>()
|
|
31
|
+
private val apolloClientService = inject<ApolloClientService>()
|
|
32
|
+
private val launcher = inject<DevLauncherController>()
|
|
33
|
+
|
|
34
|
+
private val hasMore = mutableStateOf(true)
|
|
35
|
+
|
|
36
|
+
private var _state = MutableStateFlow(
|
|
37
|
+
BranchState(
|
|
38
|
+
updates = emptyList(),
|
|
39
|
+
isLoading = true
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
val state = _state.onStart {
|
|
44
|
+
hasMore.value = true
|
|
45
|
+
loadMoreUpdates()
|
|
46
|
+
}.stateIn(
|
|
47
|
+
scope = viewModelScope,
|
|
48
|
+
started = WhileSubscribed(5_000),
|
|
49
|
+
initialValue = _state.value
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
private suspend fun loadMoreUpdates() {
|
|
53
|
+
if (!hasMore.value) {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
val updateConfiguration = appService.applicationInfo as? ApplicationInfo.Updates
|
|
58
|
+
if (updateConfiguration == null) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_state.value = _state.value.copy(isLoading = true)
|
|
63
|
+
|
|
64
|
+
val appId = updateConfiguration.appId
|
|
65
|
+
val runtimeVersion = updateConfiguration.runtimeVersion
|
|
66
|
+
val limit = 50
|
|
67
|
+
|
|
68
|
+
val updates = apolloClientService.fetchUpdates(
|
|
69
|
+
appId = appId,
|
|
70
|
+
branchName = branchName,
|
|
71
|
+
limit = limit,
|
|
72
|
+
offset = _state.value.updates.size
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
val uiUpdates = updates.data?.app?.byId?.updateBranchByName?.updates?.map { update ->
|
|
76
|
+
Update(
|
|
77
|
+
id = update.id,
|
|
78
|
+
name = update.message ?: "No message",
|
|
79
|
+
createdAt = update.createdAt as? String,
|
|
80
|
+
isCompatible = update.runtimeVersion == runtimeVersion,
|
|
81
|
+
permalink = update.manifestPermalink
|
|
82
|
+
)
|
|
83
|
+
} ?: emptyList()
|
|
84
|
+
|
|
85
|
+
hasMore.value = uiUpdates.size == limit
|
|
86
|
+
|
|
87
|
+
_state.value = _state.value.copy(
|
|
88
|
+
updates = _state.value.updates + uiUpdates,
|
|
89
|
+
isLoading = false
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fun onAction(action: BranchAction) {
|
|
94
|
+
when (action) {
|
|
95
|
+
BranchAction.LoadMoreUpdates -> viewModelScope.launch { loadMoreUpdates() }
|
|
96
|
+
is BranchAction.OpenUpdate -> {
|
|
97
|
+
launcher.coroutineScope.launch {
|
|
98
|
+
launcher.loadApp(
|
|
99
|
+
formatUpdateUrl(action.update.permalink, action.update.name)
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package expo.modules.devlauncher.compose.models
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.mutableStateOf
|
|
4
|
+
import androidx.lifecycle.ViewModel
|
|
5
|
+
import androidx.lifecycle.viewModelScope
|
|
6
|
+
import expo.modules.devlauncher.compose.Branch
|
|
7
|
+
import expo.modules.devlauncher.compose.Update
|
|
8
|
+
import expo.modules.devlauncher.services.ApolloClientService
|
|
9
|
+
import expo.modules.devlauncher.services.AppService
|
|
10
|
+
import expo.modules.devlauncher.services.ApplicationInfo
|
|
11
|
+
import expo.modules.devlauncher.services.inject
|
|
12
|
+
import kotlinx.coroutines.flow.MutableStateFlow
|
|
13
|
+
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
|
|
14
|
+
import kotlinx.coroutines.flow.onStart
|
|
15
|
+
import kotlinx.coroutines.flow.stateIn
|
|
16
|
+
import kotlinx.coroutines.launch
|
|
17
|
+
|
|
18
|
+
sealed interface BranchesAction {
|
|
19
|
+
object LoadMoreBranches : BranchesAction
|
|
20
|
+
class OpenBranch(val branchName: String) : BranchesAction
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
data class BranchesState(
|
|
24
|
+
val branches: List<Branch> = emptyList(),
|
|
25
|
+
val isLoading: Boolean = false
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
class BranchesViewModel : ViewModel() {
|
|
29
|
+
private val apolloClientService = inject<ApolloClientService>()
|
|
30
|
+
private val appService = inject<AppService>()
|
|
31
|
+
|
|
32
|
+
private val hasMore = mutableStateOf(true)
|
|
33
|
+
|
|
34
|
+
val areUpdatesConfigured get() = appService.applicationInfo is ApplicationInfo.Updates
|
|
35
|
+
|
|
36
|
+
private var _state = MutableStateFlow(
|
|
37
|
+
BranchesState(
|
|
38
|
+
branches = emptyList(),
|
|
39
|
+
isLoading = areUpdatesConfigured
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
val state = _state.onStart {
|
|
44
|
+
if (areUpdatesConfigured) {
|
|
45
|
+
hasMore.value = true
|
|
46
|
+
loadMoreBranches()
|
|
47
|
+
}
|
|
48
|
+
}.stateIn(
|
|
49
|
+
scope = viewModelScope,
|
|
50
|
+
started = WhileSubscribed(5_000),
|
|
51
|
+
initialValue = _state.value
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
private suspend fun loadMoreBranches() {
|
|
55
|
+
val updateConfiguration = appService.applicationInfo as? ApplicationInfo.Updates
|
|
56
|
+
|
|
57
|
+
// If the app is not configured for updates, we don't need to fetch branches.
|
|
58
|
+
if (updateConfiguration == null || !hasMore.value) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
val appId = updateConfiguration.appId
|
|
63
|
+
val runtimeVersion = updateConfiguration.runtimeVersion
|
|
64
|
+
val limit = 50
|
|
65
|
+
|
|
66
|
+
val branches = if (runtimeVersion != null) {
|
|
67
|
+
apolloClientService.fetchBranches(
|
|
68
|
+
appId = appId,
|
|
69
|
+
runtimeVersion = runtimeVersion,
|
|
70
|
+
offset = _state.value.branches.size,
|
|
71
|
+
limit = limit
|
|
72
|
+
).data?.app?.byId?.updateBranches?.map { updateBranch ->
|
|
73
|
+
Branch(
|
|
74
|
+
name = updateBranch.name,
|
|
75
|
+
compatibleUpdate = updateBranch.compatibleUpdates.firstOrNull()?.let { update ->
|
|
76
|
+
Update(
|
|
77
|
+
id = update.id,
|
|
78
|
+
name = update.message ?: "No message",
|
|
79
|
+
createdAt = update.createdAt as? String,
|
|
80
|
+
isCompatible = true,
|
|
81
|
+
permalink = update.manifestPermalink
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
apolloClientService.fetchBranches(
|
|
88
|
+
appId = appId,
|
|
89
|
+
offset = _state.value.branches.size,
|
|
90
|
+
limit = limit
|
|
91
|
+
).data?.app?.byId?.updateBranches?.map { updateBranch ->
|
|
92
|
+
Branch(
|
|
93
|
+
name = updateBranch.name,
|
|
94
|
+
compatibleUpdate = null
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
} ?: emptyList()
|
|
98
|
+
|
|
99
|
+
hasMore.value = branches.size == limit
|
|
100
|
+
|
|
101
|
+
_state.value = _state.value.copy(
|
|
102
|
+
isLoading = false,
|
|
103
|
+
branches = _state.value.branches + branches
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
fun onAction(action: BranchesAction) {
|
|
108
|
+
when (action) {
|
|
109
|
+
BranchesAction.LoadMoreBranches -> viewModelScope.launch { loadMoreBranches() }
|
|
110
|
+
is BranchesAction.OpenBranch -> throw IllegalStateException("Opening branches should be handled in the screen, not in the ViewModel.")
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package expo.modules.devlauncher.compose.models
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.mutableStateOf
|
|
4
|
+
import androidx.lifecycle.SavedStateHandle
|
|
5
|
+
import androidx.lifecycle.ViewModel
|
|
6
|
+
import androidx.navigation.toRoute
|
|
7
|
+
import expo.modules.devlauncher.compose.routes.CrashReport
|
|
8
|
+
|
|
9
|
+
data class CrashReportState(
|
|
10
|
+
val report: CrashReport
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
class CrashReportModel(
|
|
14
|
+
savedStateHandle: SavedStateHandle
|
|
15
|
+
) : ViewModel() {
|
|
16
|
+
private val _state = mutableStateOf(
|
|
17
|
+
savedStateHandle.toRoute<CrashReport>()
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
val state
|
|
21
|
+
get() = _state.value
|
|
22
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
package expo.modules.devlauncher.compose.models
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.mutableStateOf
|
|
4
|
+
import androidx.lifecycle.ViewModel
|
|
5
|
+
import com.facebook.react.ReactActivity
|
|
6
|
+
import expo.modules.devlauncher.DevLauncherController
|
|
7
|
+
import expo.modules.devlauncher.launcher.errors.DevLauncherAppError
|
|
8
|
+
import expo.modules.devlauncher.services.inject
|
|
9
|
+
import kotlinx.coroutines.launch
|
|
10
|
+
|
|
11
|
+
sealed interface ErrorAction {
|
|
12
|
+
object Reload : ErrorAction
|
|
13
|
+
object GoToHome : ErrorAction
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class ErrorViewModel() : ViewModel() {
|
|
17
|
+
private val devLauncher = inject<DevLauncherController>()
|
|
18
|
+
|
|
19
|
+
private val _appError = mutableStateOf<DevLauncherAppError?>(null)
|
|
20
|
+
|
|
21
|
+
val appError
|
|
22
|
+
get() = _appError.value
|
|
23
|
+
|
|
24
|
+
fun setError(error: DevLauncherAppError) {
|
|
25
|
+
_appError.value = error
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fun onAction(action: ErrorAction) {
|
|
29
|
+
when (action) {
|
|
30
|
+
is ErrorAction.Reload -> {
|
|
31
|
+
val appUrl = devLauncher.latestLoadedApp
|
|
32
|
+
|
|
33
|
+
if (appUrl == null) {
|
|
34
|
+
devLauncher.navigateToLauncher()
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
devLauncher.coroutineScope.launch {
|
|
39
|
+
devLauncher
|
|
40
|
+
.loadApp(
|
|
41
|
+
appUrl,
|
|
42
|
+
devLauncher.appHost.currentReactContext?.currentActivity as? ReactActivity?
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
is ErrorAction.GoToHome -> devLauncher.navigateToLauncher()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|