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
@@ -0,0 +1,220 @@
1
+ package expo.modules.devlauncher.compose.ui
2
+
3
+ import androidx.compose.foundation.layout.size
4
+ import androidx.compose.runtime.Composable
5
+ import androidx.compose.ui.Modifier
6
+ import androidx.compose.ui.graphics.Color
7
+ import androidx.compose.ui.res.painterResource
8
+ import androidx.compose.ui.unit.Dp
9
+ import com.composeunstyled.Icon
10
+ import expo.modules.devlauncher.R
11
+
12
+ object LauncherIcons {
13
+ @Composable
14
+ fun Plus(
15
+ size: Dp,
16
+ tint: Color,
17
+ modifier: Modifier = Modifier
18
+ ) {
19
+ Icon(
20
+ painter = painterResource(R.drawable.plus),
21
+ contentDescription = "Plus",
22
+ tint = tint,
23
+ modifier = Modifier
24
+ .size(size)
25
+ .then(modifier)
26
+ )
27
+ }
28
+
29
+ @Composable
30
+ fun ExpoLogo(
31
+ size: Dp,
32
+ tint: Color,
33
+ modifier: Modifier = Modifier
34
+ ) {
35
+ Icon(
36
+ painter = painterResource(R.drawable.expo_logo),
37
+ contentDescription = "Expo Logo",
38
+ tint = tint,
39
+ modifier = Modifier
40
+ .size(size)
41
+ .then(modifier)
42
+ )
43
+ }
44
+
45
+ @Composable
46
+ fun ShowAtLaunch(
47
+ size: Dp,
48
+ tint: Color,
49
+ modifier: Modifier = Modifier
50
+ ) {
51
+ Icon(
52
+ painter = painterResource(R.drawable.show_at_launch),
53
+ contentDescription = "Show at launch",
54
+ tint = tint,
55
+ modifier = Modifier
56
+ .size(size)
57
+ .then(modifier)
58
+ )
59
+ }
60
+
61
+ @Composable
62
+ fun Settings(
63
+ size: Dp,
64
+ tint: Color,
65
+ modifier: Modifier = Modifier
66
+ ) {
67
+ Icon(
68
+ painter = painterResource(R.drawable.settings),
69
+ contentDescription = "Settings",
70
+ tint = tint,
71
+ modifier = Modifier
72
+ .size(size)
73
+ .then(modifier)
74
+ )
75
+ }
76
+
77
+ @Composable
78
+ fun User(
79
+ size: Dp,
80
+ tint: Color,
81
+ modifier: Modifier = Modifier
82
+ ) {
83
+ Icon(
84
+ painter = painterResource(R.drawable.user),
85
+ contentDescription = "User",
86
+ tint = tint,
87
+ modifier = Modifier
88
+ .size(size)
89
+ .then(modifier)
90
+ )
91
+ }
92
+
93
+ @Composable
94
+ fun CheckCircle(
95
+ size: Dp,
96
+ tint: Color,
97
+ modifier: Modifier = Modifier
98
+ ) {
99
+ Icon(
100
+ painter = painterResource(R.drawable.check_circle),
101
+ contentDescription = "Check",
102
+ tint = tint,
103
+ modifier = Modifier
104
+ .size(size)
105
+ .then(modifier)
106
+ )
107
+ }
108
+
109
+ @Composable
110
+ fun UpdatesNav(
111
+ size: Dp,
112
+ tint: Color,
113
+ modifier: Modifier = Modifier
114
+ ) {
115
+ Icon(
116
+ painter = painterResource(R.drawable.updates_nav),
117
+ contentDescription = "Updates",
118
+ tint = tint,
119
+ modifier = Modifier
120
+ .size(size)
121
+ .then(modifier)
122
+ )
123
+ }
124
+
125
+ @Composable
126
+ fun Updates(
127
+ size: Dp,
128
+ tint: Color,
129
+ modifier: Modifier = Modifier
130
+ ) {
131
+ Icon(
132
+ painter = painterResource(R.drawable.update_icon),
133
+ contentDescription = "Updates",
134
+ tint = tint,
135
+ modifier = Modifier
136
+ .size(size)
137
+ .then(modifier)
138
+ )
139
+ }
140
+
141
+ @Composable
142
+ fun Home(
143
+ size: Dp,
144
+ tint: Color,
145
+ modifier: Modifier = Modifier
146
+ ) {
147
+ Icon(
148
+ painter = painterResource(R.drawable.home),
149
+ contentDescription = "Home",
150
+ tint = tint,
151
+ modifier = Modifier
152
+ .size(size)
153
+ .then(modifier)
154
+ )
155
+ }
156
+
157
+ @Composable
158
+ fun Download(
159
+ size: Dp,
160
+ tint: Color,
161
+ modifier: Modifier = Modifier
162
+ ) {
163
+ Icon(
164
+ painter = painterResource(R.drawable.download),
165
+ contentDescription = "Download",
166
+ tint = tint,
167
+ modifier = Modifier
168
+ .size(size)
169
+ .then(modifier)
170
+ )
171
+ }
172
+
173
+ @Composable
174
+ fun Scan(
175
+ size: Dp,
176
+ tint: Color,
177
+ modifier: Modifier = Modifier
178
+ ) {
179
+ Icon(
180
+ painter = painterResource(R.drawable.scan),
181
+ contentDescription = "Scan",
182
+ tint = tint,
183
+ modifier = Modifier
184
+ .size(size)
185
+ .then(modifier)
186
+ )
187
+ }
188
+
189
+ @Composable
190
+ fun Chevron(
191
+ size: Dp,
192
+ tint: Color,
193
+ modifier: Modifier = Modifier
194
+ ) {
195
+ Icon(
196
+ painter = painterResource(R.drawable.chevron_right),
197
+ contentDescription = "Chevron",
198
+ tint = tint,
199
+ modifier = Modifier
200
+ .size(size)
201
+ .then(modifier)
202
+ )
203
+ }
204
+
205
+ @Composable
206
+ fun Branch(
207
+ size: Dp,
208
+ tint: Color,
209
+ modifier: Modifier = Modifier
210
+ ) {
211
+ Icon(
212
+ painter = painterResource(R.drawable.branch_icon),
213
+ contentDescription = "Branch",
214
+ tint = tint,
215
+ modifier = Modifier
216
+ .size(size)
217
+ .then(modifier)
218
+ )
219
+ }
220
+ }
@@ -12,14 +12,11 @@ import androidx.compose.ui.Modifier
12
12
  import androidx.compose.ui.draw.drawBehind
13
13
  import androidx.compose.ui.graphics.Color
14
14
  import androidx.compose.ui.graphics.SolidColor
15
- import androidx.compose.ui.res.painterResource
16
15
  import androidx.compose.ui.text.font.FontWeight
17
16
  import androidx.compose.ui.text.style.TextOverflow
18
17
  import androidx.compose.ui.tooling.preview.Preview
19
18
  import androidx.compose.ui.unit.dp
20
19
  import com.composeunstyled.Button
21
- import com.composeunstyled.Icon
22
- import expo.modules.devlauncher.R
23
20
  import expo.modules.devmenu.compose.fromHex
24
21
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
25
22
  import expo.modules.devmenu.compose.primitives.NewText
@@ -91,12 +88,9 @@ fun RunningAppCard(
91
88
  }
92
89
  }
93
90
 
94
- Icon(
95
- painter = painterResource(R.drawable.chevron_right),
96
- contentDescription = "Open app",
97
- tint = NewAppTheme.colors.icon.quaternary,
98
- modifier = Modifier
99
- .size(20.dp)
91
+ LauncherIcons.Chevron(
92
+ size = 20.dp,
93
+ tint = NewAppTheme.colors.icon.quaternary
100
94
  )
101
95
  }
102
96
  }
@@ -109,6 +103,5 @@ fun RunningAppCardPreview() {
109
103
  RunningAppCard(
110
104
  appIp = "http://10.0.2.2:8081",
111
105
  appName = "Expo Dev Launcher"
112
-
113
106
  )
114
107
  }
@@ -4,16 +4,12 @@ import androidx.compose.foundation.layout.Arrangement
4
4
  import androidx.compose.foundation.layout.Row
5
5
  import androidx.compose.foundation.layout.fillMaxWidth
6
6
  import androidx.compose.foundation.layout.padding
7
- import androidx.compose.foundation.layout.size
8
7
  import androidx.compose.runtime.Composable
9
8
  import androidx.compose.ui.Alignment
10
9
  import androidx.compose.ui.Modifier
11
- import androidx.compose.ui.res.painterResource
12
10
  import androidx.compose.ui.tooling.preview.Preview
13
11
  import androidx.compose.ui.unit.dp
14
12
  import com.composeunstyled.Button
15
- import com.composeunstyled.Icon
16
- import expo.modules.devlauncher.R
17
13
  import expo.modules.devlauncher.compose.models.HomeAction
18
14
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
19
15
  import expo.modules.devmenu.compose.primitives.NewText
@@ -34,8 +30,8 @@ fun ScanQRCodeButton(
34
30
  ) {
35
31
  Row(
36
32
  horizontalArrangement = Arrangement.SpaceBetween,
37
- verticalAlignment = Alignment.Companion.CenterVertically,
38
- modifier = Modifier.Companion
33
+ verticalAlignment = Alignment.CenterVertically,
34
+ modifier = Modifier
39
35
  .fillMaxWidth()
40
36
  .padding(NewAppTheme.spacing.`3`)
41
37
  ) {
@@ -43,12 +39,9 @@ fun ScanQRCodeButton(
43
39
  "Scan QR Code"
44
40
  )
45
41
 
46
- Icon(
47
- painter = painterResource(R.drawable.scan),
48
- contentDescription = "Fetch development servers icon",
49
- tint = NewAppTheme.colors.icon.quaternary,
50
- modifier = Modifier
51
- .size(20.dp)
42
+ LauncherIcons.Scan(
43
+ size = 20.dp,
44
+ tint = NewAppTheme.colors.icon.quaternary
52
45
  )
53
46
  }
54
47
  }
@@ -24,21 +24,12 @@ import androidx.compose.ui.text.input.KeyboardCapitalization
24
24
  import androidx.compose.ui.text.input.KeyboardType
25
25
  import androidx.compose.ui.tooling.preview.Preview
26
26
  import androidx.compose.ui.unit.dp
27
- import androidx.core.net.toUri
28
27
  import com.composeunstyled.TextField
29
28
  import com.composeunstyled.TextInput
29
+ import expo.modules.devlauncher.compose.utils.validateUrl
30
30
  import expo.modules.devmenu.compose.newtheme.NewAppTheme
31
31
  import expo.modules.devmenu.compose.primitives.NewText
32
32
 
33
- private fun validateUrl(url: String): Boolean {
34
- return try {
35
- val uri = url.toUri()
36
- uri.scheme != null && uri.host != null
37
- } catch (_: Throwable) {
38
- false
39
- }
40
- }
41
-
42
33
  @Composable
43
34
  fun ServerUrlInput(
44
35
  openApp: (url: String) -> Unit
@@ -0,0 +1,50 @@
1
+ package expo.modules.devlauncher.compose.ui
2
+
3
+ import androidx.compose.foundation.horizontalScroll
4
+ import androidx.compose.foundation.layout.Box
5
+ import androidx.compose.foundation.layout.padding
6
+ import androidx.compose.foundation.rememberScrollState
7
+ import androidx.compose.foundation.verticalScroll
8
+ import androidx.compose.runtime.Composable
9
+ import androidx.compose.ui.Modifier
10
+ import androidx.compose.ui.text.TextStyle
11
+ import androidx.compose.ui.text.font.FontWeight
12
+ import androidx.compose.ui.unit.sp
13
+ import expo.modules.devlauncher.compose.utils.horizontalScrollbar
14
+ import expo.modules.devlauncher.compose.utils.verticalScrollbar
15
+ import expo.modules.devmenu.compose.newtheme.NewAppTheme
16
+ import expo.modules.devmenu.compose.primitives.NewText
17
+
18
+ @Composable
19
+ fun StackTrace(
20
+ stack: String,
21
+ modifier: Modifier = Modifier
22
+ ) {
23
+ val verticalScrollState = rememberScrollState()
24
+ val horizontalScrollState = rememberScrollState()
25
+ Box(
26
+ modifier = Modifier
27
+ .verticalScrollbar(verticalScrollState)
28
+ .horizontalScrollbar(horizontalScrollState)
29
+ .then(modifier)
30
+ ) {
31
+ Box(
32
+ Modifier
33
+ .verticalScroll(verticalScrollState)
34
+ .horizontalScroll(horizontalScrollState)
35
+
36
+ ) {
37
+ Box(modifier = Modifier.padding(horizontal = NewAppTheme.spacing.`4`)) {
38
+ NewText(
39
+ stack,
40
+ style = TextStyle.Default.merge(
41
+ lineHeight = 16.sp,
42
+ fontSize = 10.sp,
43
+ fontFamily = NewAppTheme.font.mono,
44
+ fontWeight = FontWeight.Light
45
+ )
46
+ )
47
+ }
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,65 @@
1
+ package expo.modules.devlauncher.compose.utils
2
+
3
+ import androidx.compose.foundation.ScrollState
4
+ import androidx.compose.runtime.Composable
5
+ import androidx.compose.ui.Modifier
6
+ import androidx.compose.ui.draw.drawWithContent
7
+ import androidx.compose.ui.geometry.Offset
8
+ import androidx.compose.ui.geometry.Size
9
+ import androidx.compose.ui.graphics.Color
10
+ import androidx.compose.ui.unit.Dp
11
+ import androidx.compose.ui.unit.dp
12
+
13
+ @Composable
14
+ fun Modifier.verticalScrollbar(
15
+ scrollState: ScrollState,
16
+ width: Dp = 6.dp,
17
+ scrollBarColor: Color = Color.LightGray,
18
+ endPadding: Float = 12f
19
+ ): Modifier {
20
+ return drawWithContent {
21
+ drawContent()
22
+
23
+ val viewportHeight = this.size.height
24
+ val totalContentHeight = scrollState.maxValue.toFloat() + viewportHeight
25
+ val scrollValue = scrollState.value.toFloat()
26
+
27
+ val scrollBarHeight =
28
+ (viewportHeight / totalContentHeight) * viewportHeight
29
+ val scrollBarStartOffset =
30
+ (scrollValue / totalContentHeight) * viewportHeight
31
+
32
+ drawRoundRect(
33
+ color = scrollBarColor,
34
+ topLeft = Offset(this.size.width - endPadding, scrollBarStartOffset),
35
+ size = Size(width.toPx(), scrollBarHeight)
36
+ )
37
+ }
38
+ }
39
+
40
+ @Composable
41
+ fun Modifier.horizontalScrollbar(
42
+ scrollState: ScrollState,
43
+ width: Dp = 6.dp,
44
+ scrollBarColor: Color = Color.LightGray,
45
+ endPadding: Float = 12f
46
+ ): Modifier {
47
+ return drawWithContent {
48
+ drawContent()
49
+
50
+ val viewportWidth = this.size.width
51
+ val totalContentWidth = scrollState.maxValue.toFloat() + viewportWidth
52
+ val scrollValue = scrollState.value.toFloat()
53
+
54
+ val scrollBarHeight =
55
+ (viewportWidth / totalContentWidth) * viewportWidth
56
+ val scrollBarStartOffset =
57
+ (scrollValue / totalContentWidth) * viewportWidth
58
+
59
+ drawRoundRect(
60
+ color = scrollBarColor,
61
+ topLeft = Offset(scrollBarStartOffset, this.size.height - endPadding),
62
+ size = Size(scrollBarHeight, width.toPx())
63
+ )
64
+ }
65
+ }
@@ -0,0 +1,12 @@
1
+ package expo.modules.devlauncher.compose.utils
2
+
3
+ import androidx.core.net.toUri
4
+
5
+ fun validateUrl(url: String): Boolean {
6
+ return try {
7
+ val uri = url.toUri()
8
+ uri.scheme != null && uri.host != null
9
+ } catch (_: Throwable) {
10
+ false
11
+ }
12
+ }
@@ -9,7 +9,4 @@
9
9
  <color name="dev_launcher_colorPrimaryDark">#011A2D</color>
10
10
 
11
11
  <color name="dev_launcher_colorAccentDark">#FFFFFF</color>
12
-
13
- <color name="dev_launcher_errorLogButton">#66FFFFFF</color>
14
- <color name="dev_launcher_errorMessage">#FF0000</color>
15
12
  </resources>
@@ -6,11 +6,7 @@ class APIClient {
6
6
  static let shared = APIClient()
7
7
 
8
8
  private var useStaging: Bool {
9
- #if DEBUG
10
- return true
11
- #else
12
9
  return false
13
- #endif
14
10
  }
15
11
 
16
12
  private var session: URLSession {
@@ -22,7 +22,9 @@ struct UpdateRow: View {
22
22
  openButton
23
23
  }
24
24
  }
25
- .padding(.vertical, 4)
25
+ .padding()
26
+ .background(Color.expoSecondarySystemBackground)
27
+ .cornerRadius(12)
26
28
  }
27
29
 
28
30
  private var openButton: some View {
@@ -12,20 +12,20 @@ struct UpdatesListView: View {
12
12
  @State private var errorMessage: String?
13
13
 
14
14
  var body: some View {
15
- List {
16
- Section {
17
- HStack {
18
- Toggle("Compatible only", isOn: $filterByCompatibility)
19
- Spacer()
20
- Button(sortByRecency ? "Newest first" : "Oldest first") {
21
- sortByRecency.toggle()
22
- applyFilters()
23
- }
24
- .font(.caption)
25
- .foregroundColor(.blue)
15
+ VStack(spacing: 20) {
16
+ HStack {
17
+ Toggle("Compatible only", isOn: $filterByCompatibility)
18
+ Spacer()
19
+ Button(sortByRecency ? "Newest first" : "Oldest first") {
20
+ sortByRecency.toggle()
21
+ applyFilters()
26
22
  }
27
- .padding(.vertical, 4)
23
+ .font(.caption)
24
+ .foregroundColor(.blue)
28
25
  }
26
+ .padding()
27
+ .background(Color.expoSecondarySystemBackground)
28
+ .cornerRadius(12)
29
29
 
30
30
  if isLoading {
31
31
  loading
@@ -34,14 +34,17 @@ struct UpdatesListView: View {
34
34
  } else if filteredUpdates.isEmpty {
35
35
  emptyUpdates
36
36
  } else {
37
- Section("Updates (\(filteredUpdates.count))") {
37
+ LazyVStack(alignment: .leading) {
38
+ Text("Updates (\(filteredUpdates.count))".uppercased())
39
+ .font(.caption)
40
+ .foregroundColor(.primary.opacity(0.6))
38
41
  ForEach(filteredUpdates, id: \.update.id) { tuple in
39
42
  UpdateRow(update: tuple.update, branchName: tuple.branchName, isCompatible: viewModel.isCompatibleRuntime(tuple.update.runtimeVersion))
40
43
  }
41
44
  }
42
45
  }
43
46
  }
44
- .background(Color.expoSystemGroupedBackground)
47
+ .padding()
45
48
  .onChange(of: filterByCompatibility) { _ in
46
49
  applyFilters()
47
50
  }
@@ -136,40 +139,36 @@ struct UpdatesListView: View {
136
139
  }
137
140
 
138
141
  private var loading: some View {
139
- Section {
140
- HStack {
141
- Spacer()
142
- ProgressView()
143
- .scaleEffect(1.2)
144
- Spacer()
145
- }
146
- .padding()
142
+ HStack {
143
+ Spacer()
144
+ ProgressView()
145
+ .scaleEffect(1.2)
146
+ Spacer()
147
147
  }
148
+ .padding()
148
149
  }
149
150
 
150
151
  @ViewBuilder
151
152
  func createError(message: String) -> some View {
152
- Section {
153
- VStack(spacing: 12) {
154
- Image(systemName: "exclamationmark.triangle")
155
- .foregroundColor(.red)
156
- .font(.title2)
153
+ VStack(spacing: 12) {
154
+ Image(systemName: "exclamationmark.triangle")
155
+ .foregroundColor(.red)
156
+ .font(.title2)
157
157
 
158
- Text("Error loading updates")
159
- .font(.headline)
158
+ Text("Error loading updates")
159
+ .font(.headline)
160
160
 
161
- Text(message)
162
- .font(.caption)
163
- .foregroundStyle(.secondary)
164
- .multilineTextAlignment(.center)
161
+ Text(message)
162
+ .font(.caption)
163
+ .foregroundStyle(.secondary)
164
+ .multilineTextAlignment(.center)
165
165
 
166
- Button("Retry") {
167
- loadBranches()
168
- }
169
- .buttonStyle(.borderedProminent)
166
+ Button("Retry") {
167
+ loadBranches()
170
168
  }
171
- .padding()
169
+ .buttonStyle(.borderedProminent)
172
170
  }
171
+ .padding()
173
172
  }
174
173
 
175
174
  private var emptyUpdates: some View {
@@ -9,13 +9,15 @@ struct UpdatesTabView: View {
9
9
  VStack(spacing: 0) {
10
10
  DevLauncherNavigationHeader()
11
11
 
12
- if !viewModel.isLoggedIn {
13
- NotSignedInView()
14
- .padding()
15
- } else if !viewModel.structuredBuildInfo.usesEASUpdates {
16
- NotUsingUpdatesView()
17
- } else {
18
- UpdatesListView()
12
+ ScrollView {
13
+ if !viewModel.isLoggedIn {
14
+ NotSignedInView()
15
+ .padding()
16
+ } else if !viewModel.structuredBuildInfo.usesEASUpdates {
17
+ NotUsingUpdatesView()
18
+ } else {
19
+ UpdatesListView()
20
+ }
19
21
  }
20
22
  }
21
23
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-dev-launcher",
3
3
  "title": "Expo Development Launcher",
4
- "version": "6.0.7",
4
+ "version": "6.0.8",
5
5
  "description": "Pre-release version of the Expo development launcher package for testing.",
6
6
  "repository": {
7
7
  "type": "git",
@@ -15,11 +15,11 @@
15
15
  "license": "MIT",
16
16
  "homepage": "https://docs.expo.dev",
17
17
  "dependencies": {
18
- "expo-dev-menu": "7.0.6",
19
- "expo-manifests": "~1.0.5"
18
+ "expo-dev-menu": "7.0.7",
19
+ "expo-manifests": "~1.0.6"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "expo": "*"
23
23
  },
24
- "gitHead": "5e15f3a5d68bc213ad36d59113d725fdea4f3411"
24
+ "gitHead": "1dafdaa317c182191909a94a355c8b08a2654783"
25
25
  }