expo-dev-launcher 6.0.7 → 6.0.8

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.
Files changed (121) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/debug/java/expo/modules/devlauncher/compose/DevLauncherBottomTabsNavigator.kt +2 -33
  4. package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/Accordion.kt +8 -11
  5. package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/AsyncImage.kt +17 -8
  6. package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/CircularProgressBar.kt +0 -1
  7. package/android/src/debug/java/expo/modules/devlauncher/compose/primitives/DefaultScaffold.kt +4 -2
  8. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/CrashReport.kt +1 -1
  9. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Home.kt +1 -1
  10. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Profile.kt +90 -85
  11. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Routes.kt +3 -0
  12. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Settings.kt +1 -1
  13. package/android/src/debug/java/expo/modules/devlauncher/compose/routes/Updates.kt +54 -44
  14. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/BranchScreen.kt +11 -23
  15. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/BranchesScreen.kt +17 -24
  16. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/CrashReportScreen.kt +28 -130
  17. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/ErrorScreen.kt +11 -8
  18. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/HomeScreen.kt +84 -59
  19. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/NoUpdatesScreen.kt +1 -1
  20. package/android/src/debug/java/expo/modules/devlauncher/compose/screens/SettingsScreen.kt +45 -49
  21. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AccountAvatar.kt +2 -6
  22. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AccountSelector.kt +3 -9
  23. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AppHeader.kt +5 -15
  24. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/AppLoadingErrorDialog.kt +23 -6
  25. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/BottomSheet.kt +4 -1
  26. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/BottomTabBar.kt +30 -29
  27. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/BottomTabButton.kt +7 -11
  28. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/DefaultScreenContainer.kt +23 -0
  29. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/FetchDevelopmentServersButton.kt +5 -12
  30. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/LauncherIcons.kt +220 -0
  31. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/RunningAppCard.kt +3 -10
  32. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/ScanQRCodeButton.kt +5 -12
  33. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/ServerUrlInput.kt +1 -10
  34. package/android/src/debug/java/expo/modules/devlauncher/compose/ui/StackTrace.kt +50 -0
  35. package/android/src/debug/java/expo/modules/devlauncher/compose/utils/Scrollbar.kt +65 -0
  36. package/android/src/debug/java/expo/modules/devlauncher/compose/utils/UrlUtils.kt +12 -0
  37. package/android/src/main/res/values/colors.xml +0 -3
  38. package/ios/SwiftUI/GraphQL/APIClient.swift +0 -4
  39. package/ios/SwiftUI/UpdatesTab/UpdateRow.swift +3 -1
  40. package/ios/SwiftUI/UpdatesTab/UpdatesListView.swift +37 -38
  41. package/ios/SwiftUI/UpdatesTab/UpdatesTabView.swift +9 -7
  42. package/package.json +4 -4
  43. package/android/src/debug/assets/Inter-Black.otf +0 -0
  44. package/android/src/debug/assets/Inter-Bold.otf +0 -0
  45. package/android/src/debug/assets/Inter-ExtraBold.otf +0 -0
  46. package/android/src/debug/assets/Inter-ExtraLight.otf +0 -0
  47. package/android/src/debug/assets/Inter-Light.otf +0 -0
  48. package/android/src/debug/assets/Inter-Medium.otf +0 -0
  49. package/android/src/debug/assets/Inter-Regular.otf +0 -0
  50. package/android/src/debug/assets/Inter-SemiBold.otf +0 -0
  51. package/android/src/debug/assets/Inter-Thin.otf +0 -0
  52. package/android/src/debug/java/expo/modules/devlauncher/launcher/errors/DevLauncherStackAdapter.kt +0 -39
  53. package/android/src/debug/res/drawable-mdpi/building_icon.png +0 -0
  54. package/android/src/debug/res/drawable-mdpi/check_icon.png +0 -0
  55. package/android/src/debug/res/drawable-mdpi/chevron_right_icon.png +0 -0
  56. package/android/src/debug/res/drawable-mdpi/home_icon.png +0 -0
  57. package/android/src/debug/res/drawable-mdpi/info_icon.png +0 -0
  58. package/android/src/debug/res/drawable-mdpi/qr_code.png +0 -0
  59. package/android/src/debug/res/drawable-mdpi/settings_icon.png +0 -0
  60. package/android/src/debug/res/drawable-mdpi/shake_device_icon.png +0 -0
  61. package/android/src/debug/res/drawable-mdpi/show_menu_at_launch_icon.png +0 -0
  62. package/android/src/debug/res/drawable-mdpi/terminal_icon.png +0 -0
  63. package/android/src/debug/res/drawable-mdpi/three_finger_long_press_icon.png +0 -0
  64. package/android/src/debug/res/drawable-mdpi/user_icon.png +0 -0
  65. package/android/src/debug/res/drawable-mdpi/x_icon.png +0 -0
  66. package/android/src/debug/res/drawable-night-mdpi/qr_code.png +0 -0
  67. package/android/src/debug/res/drawable-night-mdpi/shake_device_icon.png +0 -0
  68. package/android/src/debug/res/drawable-night-xhdpi/qr_code.png +0 -0
  69. package/android/src/debug/res/drawable-night-xhdpi/shake_device_icon.png +0 -0
  70. package/android/src/debug/res/drawable-night-xxhdpi/qr_code.png +0 -0
  71. package/android/src/debug/res/drawable-night-xxhdpi/shake_device_icon.png +0 -0
  72. package/android/src/debug/res/drawable-xhdpi/building_icon.png +0 -0
  73. package/android/src/debug/res/drawable-xhdpi/check_icon.png +0 -0
  74. package/android/src/debug/res/drawable-xhdpi/chevron_right_icon.png +0 -0
  75. package/android/src/debug/res/drawable-xhdpi/home_icon.png +0 -0
  76. package/android/src/debug/res/drawable-xhdpi/info_icon.png +0 -0
  77. package/android/src/debug/res/drawable-xhdpi/qr_code.png +0 -0
  78. package/android/src/debug/res/drawable-xhdpi/settings_icon.png +0 -0
  79. package/android/src/debug/res/drawable-xhdpi/shake_device_icon.png +0 -0
  80. package/android/src/debug/res/drawable-xhdpi/show_menu_at_launch_icon.png +0 -0
  81. package/android/src/debug/res/drawable-xhdpi/terminal_icon.png +0 -0
  82. package/android/src/debug/res/drawable-xhdpi/three_finger_long_press_icon.png +0 -0
  83. package/android/src/debug/res/drawable-xhdpi/user_icon.png +0 -0
  84. package/android/src/debug/res/drawable-xhdpi/x_icon.png +0 -0
  85. package/android/src/debug/res/drawable-xxhdpi/building_icon.png +0 -0
  86. package/android/src/debug/res/drawable-xxhdpi/check_icon.png +0 -0
  87. package/android/src/debug/res/drawable-xxhdpi/chevron_right_icon.png +0 -0
  88. package/android/src/debug/res/drawable-xxhdpi/home_icon.png +0 -0
  89. package/android/src/debug/res/drawable-xxhdpi/info_icon.png +0 -0
  90. package/android/src/debug/res/drawable-xxhdpi/qr_code.png +0 -0
  91. package/android/src/debug/res/drawable-xxhdpi/settings_icon.png +0 -0
  92. package/android/src/debug/res/drawable-xxhdpi/shake_device_icon.png +0 -0
  93. package/android/src/debug/res/drawable-xxhdpi/show_menu_at_launch_icon.png +0 -0
  94. package/android/src/debug/res/drawable-xxhdpi/terminal_icon.png +0 -0
  95. package/android/src/debug/res/drawable-xxhdpi/three_finger_long_press_icon.png +0 -0
  96. package/android/src/debug/res/drawable-xxhdpi/user_icon.png +0 -0
  97. package/android/src/debug/res/drawable-xxhdpi/x_icon.png +0 -0
  98. package/android/src/main/res/drawable/arrow_right.xml +0 -9
  99. package/android/src/main/res/drawable/copy.xml +0 -13
  100. package/android/src/main/res/drawable/inspect.xml +0 -10
  101. package/android/src/main/res/drawable/pulse.xml +0 -10
  102. package/android/src/main/res/drawable/signal.xml +0 -26
  103. package/android/src/main/res/drawable-hdpi/dev_laucher_ic_home_white_36dp.png +0 -0
  104. package/android/src/main/res/drawable-hdpi/dev_launcher_ic_refresh_white_36dp.png +0 -0
  105. package/android/src/main/res/drawable-mdpi/dev_laucher_ic_home_white_36dp.png +0 -0
  106. package/android/src/main/res/drawable-mdpi/dev_launcher_ic_refresh_white_36dp.png +0 -0
  107. package/android/src/main/res/drawable-mdpi/dev_menu_fab_icon.png +0 -0
  108. package/android/src/main/res/drawable-xhdpi/dev_laucher_ic_home_white_36dp.png +0 -0
  109. package/android/src/main/res/drawable-xhdpi/dev_launcher_ic_refresh_white_36dp.png +0 -0
  110. package/android/src/main/res/drawable-xhdpi/dev_menu_fab_icon.png +0 -0
  111. package/android/src/main/res/drawable-xxhdpi/dev_laucher_ic_home_white_36dp.png +0 -0
  112. package/android/src/main/res/drawable-xxhdpi/dev_launcher_ic_refresh_white_36dp.png +0 -0
  113. package/android/src/main/res/drawable-xxhdpi/dev_menu_fab_icon.png +0 -0
  114. package/android/src/main/res/drawable-xxxhdpi/dev_laucher_ic_home_white_36dp.png +0 -0
  115. package/android/src/main/res/drawable-xxxhdpi/dev_launcher_ic_refresh_white_36dp.png +0 -0
  116. package/android/src/main/res/layout/error_activity_content_view.xml +0 -7
  117. package/android/src/main/res/layout/error_console_fragment.xml +0 -53
  118. package/android/src/main/res/layout/error_console_list_item.xml +0 -23
  119. package/android/src/main/res/layout/error_fragment.xml +0 -102
  120. package/android/src/main/res/values/strings.xml +0 -10
  121. /package/android/src/main/res/drawable/{reload.xml → updates_nav.xml} +0 -0
package/CHANGELOG.md CHANGED
@@ -10,6 +10,10 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 6.0.8 — 2025-08-31
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
13
17
  ## 6.0.7 — 2025-08-28
14
18
 
15
19
  _This version does not introduce any user-facing changes._
@@ -20,13 +20,13 @@ expoModule {
20
20
  }
21
21
 
22
22
  group = "host.exp.exponent"
23
- version = "6.0.7"
23
+ version = "6.0.8"
24
24
 
25
25
  android {
26
26
  namespace "expo.modules.devlauncher"
27
27
  defaultConfig {
28
28
  versionCode 9
29
- versionName "6.0.7"
29
+ versionName "6.0.8"
30
30
  }
31
31
 
32
32
  buildTypes {
@@ -4,14 +4,8 @@ import androidx.compose.animation.AnimatedContentTransitionScope
4
4
  import androidx.compose.animation.EnterTransition
5
5
  import androidx.compose.animation.ExitTransition
6
6
  import androidx.compose.animation.core.tween
7
- import androidx.compose.foundation.background
8
- import androidx.compose.foundation.layout.Box
9
- import androidx.compose.foundation.layout.fillMaxSize
10
- import androidx.compose.foundation.layout.statusBarsPadding
11
7
  import androidx.compose.runtime.Composable
12
8
  import androidx.compose.runtime.remember
13
- import androidx.compose.ui.Modifier
14
- import androidx.compose.ui.graphics.painter.Painter
15
9
  import androidx.navigation.compose.NavHost
16
10
  import androidx.navigation.compose.composable
17
11
  import androidx.navigation.compose.rememberNavController
@@ -27,31 +21,6 @@ import expo.modules.devlauncher.compose.routes.UpdatesRoute
27
21
  import expo.modules.devlauncher.compose.ui.BottomTabBar
28
22
  import expo.modules.devlauncher.compose.ui.Full
29
23
  import expo.modules.devlauncher.compose.ui.rememberBottomSheetState
30
- import expo.modules.devmenu.compose.newtheme.NewAppTheme
31
- import kotlinx.serialization.Serializable
32
-
33
- @Composable
34
- fun DefaultScreenContainer(
35
- content: @Composable () -> Unit
36
- ) {
37
- Box(
38
- modifier = Modifier
39
- .fillMaxSize()
40
- .background(NewAppTheme.colors.background.default)
41
- .statusBarsPadding()
42
- ) {
43
- content()
44
- }
45
- }
46
-
47
- data class Tab(
48
- val label: String,
49
- val icon: Painter,
50
- val screen: Any
51
- )
52
-
53
- @Serializable
54
- object Main
55
24
 
56
25
  @Composable
57
26
  fun DevLauncherBottomTabsNavigator() {
@@ -70,9 +39,9 @@ fun DevLauncherBottomTabsNavigator() {
70
39
 
71
40
  NavHost(
72
41
  navController = mainNavController,
73
- startDestination = Main
42
+ startDestination = Routes.Main
74
43
  ) {
75
- composable<Main>(
44
+ composable<Routes.Main>(
76
45
  enterTransition = {
77
46
  slideIntoContainer(
78
47
  AnimatedContentTransitionScope.SlideDirection.Right,
@@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.Column
11
11
  import androidx.compose.foundation.layout.Row
12
12
  import androidx.compose.foundation.layout.fillMaxWidth
13
13
  import androidx.compose.foundation.layout.padding
14
- import androidx.compose.foundation.layout.size
15
14
  import androidx.compose.runtime.Composable
16
15
  import androidx.compose.runtime.getValue
17
16
  import androidx.compose.runtime.mutableStateOf
@@ -19,11 +18,10 @@ import androidx.compose.runtime.remember
19
18
  import androidx.compose.runtime.setValue
20
19
  import androidx.compose.ui.Alignment
21
20
  import androidx.compose.ui.Modifier
22
- import androidx.compose.ui.res.painterResource
21
+ import androidx.compose.ui.semantics.Role
23
22
  import androidx.compose.ui.tooling.preview.Preview
24
23
  import androidx.compose.ui.unit.dp
25
- import com.composeunstyled.Icon
26
- import expo.modules.devlauncher.R
24
+ import expo.modules.devlauncher.compose.ui.LauncherIcons
27
25
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
28
26
  import expo.modules.devmenu.compose.primitives.NewText
29
27
  import expo.modules.devmenu.compose.primitives.RoundedSurface
@@ -45,7 +43,9 @@ fun Accordion(
45
43
  Column(
46
44
  modifier = Modifier
47
45
  .fillMaxWidth()
48
- .clickable { expanded = !expanded }
46
+ .clickable(
47
+ role = Role.Button
48
+ ) { expanded = !expanded }
49
49
  .padding(NewAppTheme.spacing.`3`)
50
50
  ) {
51
51
  Box {
@@ -54,12 +54,9 @@ fun Accordion(
54
54
  verticalAlignment = Alignment.CenterVertically,
55
55
  modifier = modifier
56
56
  ) {
57
- Icon(
58
- painter = painterResource(R.drawable.plus),
59
- contentDescription = "Accordion Arrow",
60
- tint = NewAppTheme.colors.text.link,
61
- modifier = Modifier
62
- .size(16.dp)
57
+ LauncherIcons.Plus(
58
+ size = 16.dp,
59
+ tint = NewAppTheme.colors.text.link
63
60
  )
64
61
 
65
62
  NewText(
@@ -8,15 +8,14 @@ import androidx.compose.runtime.mutableStateOf
8
8
  import androidx.compose.runtime.remember
9
9
  import androidx.compose.runtime.rememberCoroutineScope
10
10
  import androidx.compose.runtime.setValue
11
+ import androidx.compose.ui.graphics.ImageBitmap
11
12
  import androidx.compose.ui.graphics.asImageBitmap
12
13
  import expo.modules.devlauncher.services.ImageLoaderService
13
14
  import expo.modules.devlauncher.services.inject
14
15
  import kotlinx.coroutines.launch
15
16
 
16
17
  @Composable
17
- fun AsyncImage(
18
- url: String
19
- ) {
18
+ private fun rememberImageBitmap(url: String): ImageBitmap? {
20
19
  val imageLoaderService = inject<ImageLoaderService>()
21
20
  val scope = rememberCoroutineScope()
22
21
  var imageBitmap by remember { mutableStateOf(imageLoaderService.loadFromMemory(url)?.asImageBitmap()) }
@@ -30,10 +29,20 @@ fun AsyncImage(
30
29
  }
31
30
  }
32
31
 
33
- imageBitmap?.let {
34
- Image(
35
- bitmap = it,
36
- contentDescription = url
37
- )
32
+ return imageBitmap
33
+ }
34
+
35
+ @Composable
36
+ fun AsyncImage(
37
+ url: String
38
+ ) {
39
+ val imageBitmap = rememberImageBitmap(url)
40
+ if (imageBitmap == null) {
41
+ return
38
42
  }
43
+
44
+ Image(
45
+ bitmap = imageBitmap,
46
+ contentDescription = url
47
+ )
39
48
  }
@@ -20,7 +20,6 @@ import androidx.compose.ui.unit.dp
20
20
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
21
21
  import io.github.lukmccall.colors.blue
22
22
  import io.github.lukmccall.colors.gray
23
-
24
23
  import kotlin.time.Duration
25
24
  import kotlin.time.Duration.Companion.seconds
26
25
 
@@ -13,9 +13,11 @@ fun DefaultScaffold(
13
13
  val maxWidth = constraints.maxWidth
14
14
  val maxHeight = constraints.maxHeight
15
15
 
16
- val bottomTabPlaceables = subcompose("bottomTab", bottomTab).map { it.measure(constraints) }
16
+ val bottomTabPlaceables = subcompose("bottomTab", bottomTab)
17
+ .map { it.measure(constraints) }
17
18
  val bottomTabsHeight = bottomTabPlaceables.fastMaxBy { it.height }?.height ?: 0
18
- val contentPlaceables = subcompose("content", content).map { it.measure(constraints.copy(maxHeight = maxHeight - bottomTabsHeight)) }
19
+ val contentPlaceables = subcompose("content", content)
20
+ .map { it.measure(constraints.copy(maxHeight = maxHeight - bottomTabsHeight)) }
19
21
 
20
22
  layout(maxWidth, maxHeight) {
21
23
  contentPlaceables.forEach { it.place(0, 0) }
@@ -2,7 +2,7 @@ package expo.modules.devlauncher.compose.routes
2
2
 
3
3
  import androidx.compose.runtime.Composable
4
4
  import androidx.lifecycle.viewmodel.compose.viewModel
5
- import expo.modules.devlauncher.compose.DefaultScreenContainer
5
+ import expo.modules.devlauncher.compose.ui.DefaultScreenContainer
6
6
  import expo.modules.devlauncher.compose.models.CrashReportModel
7
7
  import expo.modules.devlauncher.compose.screens.CrashReportScreen
8
8
  import expo.modules.devlauncher.launcher.errors.DevLauncherErrorInstance
@@ -5,7 +5,7 @@ import androidx.compose.runtime.Composable
5
5
  import androidx.compose.ui.platform.LocalContext
6
6
  import androidx.lifecycle.viewmodel.compose.viewModel
7
7
  import androidx.navigation.NavController
8
- import expo.modules.devlauncher.compose.DefaultScreenContainer
8
+ import expo.modules.devlauncher.compose.ui.DefaultScreenContainer
9
9
  import expo.modules.devlauncher.compose.models.HomeAction
10
10
  import expo.modules.devlauncher.compose.models.HomeViewModel
11
11
  import expo.modules.devlauncher.compose.screens.HomeScreen
@@ -1,5 +1,6 @@
1
1
  package expo.modules.devlauncher.compose.routes
2
2
 
3
+ import androidx.activity.compose.ManagedActivityResultLauncher
3
4
  import androidx.activity.compose.rememberLauncherForActivityResult
4
5
  import androidx.compose.foundation.background
5
6
  import androidx.compose.foundation.layout.Arrangement
@@ -17,7 +18,6 @@ import androidx.compose.ui.Modifier
17
18
  import androidx.compose.ui.draw.dropShadow
18
19
  import androidx.compose.ui.graphics.Color
19
20
  import androidx.compose.ui.graphics.shadow.Shadow
20
- import androidx.compose.ui.res.painterResource
21
21
  import androidx.compose.ui.text.style.TextAlign
22
22
  import androidx.compose.ui.unit.DpOffset
23
23
  import androidx.compose.ui.unit.dp
@@ -25,8 +25,6 @@ import androidx.compose.ui.unit.sp
25
25
  import androidx.lifecycle.compose.collectAsStateWithLifecycle
26
26
  import androidx.lifecycle.viewmodel.compose.viewModel
27
27
  import com.composables.core.ModalBottomSheetState
28
- import com.composeunstyled.Icon
29
- import expo.modules.devlauncher.R
30
28
  import expo.modules.devlauncher.compose.AuthActivity
31
29
  import expo.modules.devlauncher.compose.AuthRequestType
32
30
  import expo.modules.devlauncher.compose.AuthResult
@@ -35,6 +33,7 @@ import expo.modules.devlauncher.compose.models.ProfileViewModel
35
33
  import expo.modules.devlauncher.compose.primitives.CircularProgressBar
36
34
  import expo.modules.devlauncher.compose.ui.AccountSelector
37
35
  import expo.modules.devlauncher.compose.ui.BottomSheet
36
+ import expo.modules.devlauncher.compose.ui.LauncherIcons
38
37
  import expo.modules.devlauncher.compose.ui.SignUp
39
38
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
40
39
  import expo.modules.devmenu.compose.primitives.NewText
@@ -56,95 +55,101 @@ fun ProfileRoute(
56
55
  }
57
56
 
58
57
  BottomSheet(bottomSheetState) {
58
+ val state = state // capture state for when statement
59
59
  when (state) {
60
- is ProfileState.LoggedIn -> {
61
- val state = state as ProfileState.LoggedIn
62
- AccountSelector(
63
- accounts = state.accounts,
64
- onSignOut = {
65
- viewModel.onAction(ProfileViewModel.Action.SignOut)
66
- },
67
- onClick = { account ->
68
- viewModel.onAction(ProfileViewModel.Action.SwitchAccount(account))
69
- }
70
- )
71
- }
60
+ is ProfileState.LoggedIn -> LoggedIn(state, viewModel)
61
+ ProfileState.LoggedOut -> LoggedOut(authLauncher)
62
+ ProfileState.Fetching -> Loading()
63
+ }
64
+ }
65
+ }
72
66
 
73
- ProfileState.LoggedOut -> {
74
- Column(
75
- verticalArrangement = Arrangement.spacedBy(NewAppTheme.spacing.`4`)
76
- ) {
77
- Row(
78
- horizontalArrangement = Arrangement.Center,
79
- modifier = Modifier
80
- .fillMaxWidth()
81
- ) {
82
- Box(
83
- modifier = Modifier
84
- .size(44.dp)
85
- .dropShadow(
86
- shape = RoundedCornerShape(NewAppTheme.borderRadius.md),
87
- shadow = Shadow(
88
- radius = 10.dp,
89
- offset = DpOffset(0.dp, 5.dp),
90
- color = Color.Black.copy(alpha = 0.05f)
91
- )
92
- )
93
- .dropShadow(
94
- shape = RoundedCornerShape(NewAppTheme.borderRadius.md),
95
- shadow = Shadow(
96
- radius = 25.dp,
97
- offset = DpOffset(0.dp, 15.dp),
98
- color = Color.Black.copy(alpha = 0.12f)
99
- )
100
- )
101
- .background(
102
- Color.White,
103
- shape = RoundedCornerShape(NewAppTheme.borderRadius.md)
104
- )
105
- ) {
106
- Icon(
107
- painter = painterResource(R.drawable.expo_logo),
108
- contentDescription = "Expo logo",
109
- tint = Color.Black,
110
- modifier = Modifier
111
- .size(24.dp)
112
- .align(Alignment.Center)
113
- )
114
- }
115
- }
67
+ @Composable
68
+ private fun Loading() {
69
+ Box(
70
+ contentAlignment = Alignment.Center,
71
+ modifier = Modifier
72
+ .fillMaxWidth()
73
+ .height(300.dp)
74
+ ) {
75
+ CircularProgressBar(size = 72.dp)
76
+ }
77
+ }
116
78
 
117
- NewText(
118
- "Login or create an account to view local\ndevelopment servers and more",
119
- style = NewAppTheme.font.sm.merge(
120
- lineHeight = 19.sp,
121
- textAlign = TextAlign.Center
122
- ),
123
- color = NewAppTheme.colors.text.secondary,
124
- modifier = Modifier.fillMaxWidth()
125
- )
79
+ @Composable
80
+ private fun LoggedOut(authLauncher: ManagedActivityResultLauncher<AuthRequestType, AuthResult>) {
81
+ Column(
82
+ verticalArrangement = Arrangement.spacedBy(NewAppTheme.spacing.`4`)
83
+ ) {
84
+ Row(
85
+ horizontalArrangement = Arrangement.Center,
86
+ modifier = Modifier
87
+ .fillMaxWidth()
88
+ ) {
89
+ val shape = RoundedCornerShape(NewAppTheme.borderRadius.md)
126
90
 
127
- SignUp(
128
- onLogIn = {
129
- authLauncher.launch(AuthRequestType.LOGIN)
130
- },
131
- onSignUp = {
132
- authLauncher.launch(AuthRequestType.SIGNUP)
133
- }
91
+ Box(
92
+ modifier = Modifier
93
+ .size(44.dp)
94
+ .dropShadow(
95
+ shape = shape,
96
+ shadow = Shadow(
97
+ radius = 10.dp,
98
+ offset = DpOffset(0.dp, 5.dp),
99
+ color = Color.Black.copy(alpha = 0.05f)
100
+ )
134
101
  )
135
- }
102
+ .dropShadow(
103
+ shape = shape,
104
+ shadow = Shadow(
105
+ radius = 25.dp,
106
+ offset = DpOffset(0.dp, 15.dp),
107
+ color = Color.Black.copy(alpha = 0.12f)
108
+ )
109
+ )
110
+ .background(
111
+ Color.White,
112
+ shape = shape
113
+ )
114
+ ) {
115
+ LauncherIcons.ExpoLogo(
116
+ size = 24.dp,
117
+ tint = Color.Black,
118
+ modifier = Modifier.align(Alignment.Center)
119
+ )
136
120
  }
121
+ }
122
+
123
+ NewText(
124
+ "Login or create an account to view local\ndevelopment servers and more",
125
+ style = NewAppTheme.font.sm.merge(
126
+ lineHeight = 19.sp,
127
+ textAlign = TextAlign.Center
128
+ ),
129
+ color = NewAppTheme.colors.text.secondary,
130
+ modifier = Modifier.fillMaxWidth()
131
+ )
137
132
 
138
- ProfileState.Fetching -> {
139
- Box(
140
- contentAlignment = Alignment.Center,
141
- modifier = Modifier
142
- .fillMaxWidth()
143
- .height(300.dp)
144
- ) {
145
- CircularProgressBar(size = 72.dp)
146
- }
133
+ SignUp(
134
+ onLogIn = {
135
+ authLauncher.launch(AuthRequestType.LOGIN)
136
+ },
137
+ onSignUp = {
138
+ authLauncher.launch(AuthRequestType.SIGNUP)
147
139
  }
148
- }
140
+ )
149
141
  }
150
142
  }
143
+
144
+ @Composable
145
+ private fun LoggedIn(state: ProfileState.LoggedIn, viewModel: ProfileViewModel) {
146
+ AccountSelector(
147
+ accounts = state.accounts,
148
+ onSignOut = {
149
+ viewModel.onAction(ProfileViewModel.Action.SignOut)
150
+ },
151
+ onClick = { account ->
152
+ viewModel.onAction(ProfileViewModel.Action.SwitchAccount(account))
153
+ }
154
+ )
155
+ }
@@ -3,6 +3,9 @@ package expo.modules.devlauncher.compose.routes
3
3
  import kotlinx.serialization.Serializable
4
4
 
5
5
  object Routes {
6
+ @Serializable
7
+ object Main
8
+
6
9
  @Serializable
7
10
  object Home
8
11
 
@@ -2,7 +2,7 @@ package expo.modules.devlauncher.compose.routes
2
2
 
3
3
  import androidx.compose.runtime.Composable
4
4
  import androidx.lifecycle.viewmodel.compose.viewModel
5
- import expo.modules.devlauncher.compose.DefaultScreenContainer
5
+ import expo.modules.devlauncher.compose.ui.DefaultScreenContainer
6
6
  import expo.modules.devlauncher.compose.models.SettingsViewModel
7
7
  import expo.modules.devlauncher.compose.screens.SettingsScreen
8
8
 
@@ -6,11 +6,12 @@ import androidx.compose.runtime.Composable
6
6
  import androidx.compose.runtime.getValue
7
7
  import androidx.lifecycle.compose.collectAsStateWithLifecycle
8
8
  import androidx.lifecycle.viewmodel.compose.viewModel
9
+ import androidx.navigation.NavHostController
9
10
  import androidx.navigation.compose.NavHost
10
11
  import androidx.navigation.compose.composable
11
12
  import androidx.navigation.compose.rememberNavController
12
13
  import androidx.navigation.toRoute
13
- import expo.modules.devlauncher.compose.DefaultScreenContainer
14
+ import expo.modules.devlauncher.compose.ui.DefaultScreenContainer
14
15
  import expo.modules.devlauncher.compose.models.BranchViewModel
15
16
  import expo.modules.devlauncher.compose.models.BranchesAction
16
17
  import expo.modules.devlauncher.compose.models.BranchesViewModel
@@ -42,56 +43,65 @@ fun UpdatesRoute(
42
43
  }
43
44
  ) {
44
45
  composable<Routes.Updates.Branches> {
45
- val viewModel = viewModel<BranchesViewModel>()
46
-
47
- val state by viewModel.state.collectAsStateWithLifecycle()
48
-
49
- if (viewModel.areUpdatesConfigured) {
50
- BranchesScreen(
51
- branches = state.branches,
52
- isLoading = state.isLoading,
53
- needToSignIn = state.needToSignIn,
54
- onProfileClick = onProfileClick,
55
- onAction = { action ->
56
- when (action) {
57
- is BranchesAction.OpenBranch -> {
58
- updatesNavController.navigate(
59
- Routes.Updates.Branch(action.branchName)
60
- )
61
- }
62
-
63
- else -> {
64
- viewModel.onAction(action)
65
- }
66
- }
67
- }
68
- )
69
- } else {
70
- NoUpdatesScreen(
71
- onProfileClick = onProfileClick
72
- )
73
- }
46
+ Branches(onProfileClick, updatesNavController)
74
47
  }
75
48
 
76
49
  composable<Routes.Updates.Branch> { navBackStackEntry ->
77
50
  val route = navBackStackEntry.toRoute<Routes.Updates.Branch>()
51
+ Branch(route, updatesNavController)
52
+ }
53
+ }
54
+ }
55
+ }
78
56
 
79
- val viewModel = viewModel {
80
- BranchViewModel(
81
- branchName = route.name
82
- )
83
- }
57
+ @Composable
58
+ private fun Branch(route: Routes.Updates.Branch, updatesNavController: NavHostController) {
59
+ val viewModel = viewModel {
60
+ BranchViewModel(
61
+ branchName = route.name
62
+ )
63
+ }
84
64
 
85
- val state by viewModel.state.collectAsStateWithLifecycle()
65
+ val state by viewModel.state.collectAsStateWithLifecycle()
86
66
 
87
- BranchScreen(
88
- branchName = route.name,
89
- updates = state.updates,
90
- isLoading = state.isLoading,
91
- goBack = { updatesNavController.navigateUp() },
92
- onAction = viewModel::onAction
93
- )
67
+ BranchScreen(
68
+ branchName = route.name,
69
+ updates = state.updates,
70
+ isLoading = state.isLoading,
71
+ goBack = { updatesNavController.navigateUp() },
72
+ onAction = viewModel::onAction
73
+ )
74
+ }
75
+
76
+ @Composable
77
+ private fun Branches(onProfileClick: () -> Unit, updatesNavController: NavHostController) {
78
+ val viewModel = viewModel<BranchesViewModel>()
79
+
80
+ val state by viewModel.state.collectAsStateWithLifecycle()
81
+
82
+ if (viewModel.areUpdatesConfigured) {
83
+ BranchesScreen(
84
+ branches = state.branches,
85
+ isLoading = state.isLoading,
86
+ needToSignIn = state.needToSignIn,
87
+ onProfileClick = onProfileClick,
88
+ onAction = { action ->
89
+ when (action) {
90
+ is BranchesAction.OpenBranch -> {
91
+ updatesNavController.navigate(
92
+ Routes.Updates.Branch(action.branchName)
93
+ )
94
+ }
95
+
96
+ else -> {
97
+ viewModel.onAction(action)
98
+ }
99
+ }
94
100
  }
95
- }
101
+ )
102
+ } else {
103
+ NoUpdatesScreen(
104
+ onProfileClick = onProfileClick
105
+ )
96
106
  }
97
107
  }
@@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Row
8
8
  import androidx.compose.foundation.layout.fillMaxSize
9
9
  import androidx.compose.foundation.layout.fillMaxWidth
10
10
  import androidx.compose.foundation.layout.padding
11
- import androidx.compose.foundation.layout.size
12
11
  import androidx.compose.foundation.lazy.LazyColumn
13
12
  import androidx.compose.foundation.lazy.itemsIndexed
14
13
  import androidx.compose.foundation.lazy.rememberLazyListState
@@ -20,21 +19,18 @@ import androidx.compose.runtime.getValue
20
19
  import androidx.compose.runtime.remember
21
20
  import androidx.compose.ui.Alignment
22
21
  import androidx.compose.ui.Modifier
23
- import androidx.compose.ui.draw.rotate
24
22
  import androidx.compose.ui.graphics.Color
25
- import androidx.compose.ui.res.painterResource
26
23
  import androidx.compose.ui.text.font.FontWeight
27
24
  import androidx.compose.ui.text.style.TextAlign
28
25
  import androidx.compose.ui.text.style.TextOverflow
29
26
  import androidx.compose.ui.tooling.preview.Preview
30
27
  import androidx.compose.ui.unit.dp
31
28
  import com.composeunstyled.Button
32
- import com.composeunstyled.Icon
33
- import expo.modules.devlauncher.R
34
- import expo.modules.devlauncher.compose.DefaultScreenContainer
35
29
  import expo.modules.devlauncher.compose.Update
36
30
  import expo.modules.devlauncher.compose.models.BranchAction
37
31
  import expo.modules.devlauncher.compose.primitives.CircularProgressBar
32
+ import expo.modules.devlauncher.compose.ui.DefaultScreenContainer
33
+ import expo.modules.devlauncher.compose.ui.LauncherIcons
38
34
  import expo.modules.devlauncher.compose.utils.DateFormat
39
35
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
40
36
  import expo.modules.devmenu.compose.primitives.Divider
@@ -63,13 +59,9 @@ fun BranchScreen(
63
59
  Button(
64
60
  onClick = goBack
65
61
  ) {
66
- Icon(
67
- painter = painterResource(R.drawable.chevron_right_icon),
68
- contentDescription = "Back icon",
69
- tint = NewAppTheme.colors.icon.default,
70
- modifier = Modifier
71
- .rotate(180f)
72
- .size(20.dp)
62
+ LauncherIcons.Chevron(
63
+ size = 20.dp,
64
+ tint = NewAppTheme.colors.icon.default
73
65
  )
74
66
  }
75
67
  }
@@ -135,11 +127,9 @@ fun BranchScreen(
135
127
  .fillMaxWidth()
136
128
  .padding(NewAppTheme.spacing.`3`)
137
129
  ) {
138
- Icon(
139
- painter = painterResource(R.drawable.update_icon),
140
- contentDescription = "Update Icon",
141
- tint = NewAppTheme.colors.icon.tertiary,
142
- modifier = Modifier.size(20.dp)
130
+ LauncherIcons.Updates(
131
+ size = 20.dp,
132
+ tint = NewAppTheme.colors.icon.tertiary
143
133
  )
144
134
 
145
135
  Column(
@@ -172,11 +162,9 @@ fun BranchScreen(
172
162
  }
173
163
  }
174
164
 
175
- Icon(
176
- painter = painterResource(R.drawable.chevron_right),
177
- contentDescription = "Chevron Icon",
178
- tint = NewAppTheme.colors.icon.tertiary,
179
- modifier = Modifier.size(16.dp)
165
+ LauncherIcons.Chevron(
166
+ size = 16.dp,
167
+ tint = NewAppTheme.colors.icon.tertiary
180
168
  )
181
169
  }
182
170
  }