@@ -7,7 +7,6 @@ import android.provider.Settings
77import androidx.activity.compose.BackHandler
88import androidx.activity.compose.rememberLauncherForActivityResult
99import androidx.activity.result.contract.ActivityResultContracts
10- import androidx.compose.foundation.clickable
1110import androidx.compose.foundation.layout.Arrangement
1211import androidx.compose.foundation.layout.Column
1312import androidx.compose.foundation.layout.fillMaxSize
@@ -24,7 +23,6 @@ import androidx.compose.material.icons.outlined.Apps
2423import androidx.compose.material.icons.outlined.BugReport
2524import androidx.compose.material.icons.outlined.Delete
2625import androidx.compose.material.icons.outlined.DeleteOutline
27- import androidx.compose.material.icons.outlined.Download
2826import androidx.compose.material.icons.outlined.Notifications
2927import androidx.compose.material.icons.outlined.Refresh
3028import androidx.compose.material.icons.outlined.Settings
@@ -55,7 +53,6 @@ import androidx.compose.runtime.setValue
5553import androidx.compose.ui.Modifier
5654import androidx.compose.ui.graphics.vector.ImageVector
5755import androidx.compose.ui.platform.LocalContext
58- import androidx.compose.ui.platform.LocalResources
5956import androidx.compose.ui.res.stringResource
6057import androidx.compose.ui.unit.dp
6158import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -66,15 +63,14 @@ import app.revanced.manager.ui.component.AlertDialogExtended
6663import app.revanced.manager.ui.component.AppTopBar
6764import app.revanced.manager.ui.component.AutoUpdatesDialog
6865import app.revanced.manager.ui.component.AvailableUpdateDialog
69- import app.revanced.manager.ui.component.NotificationCard
7066import app.revanced.manager.ui.component.ConfirmDialog
67+ import app.revanced.manager.ui.component.NotificationCard
7168import app.revanced.manager.ui.component.bundle.BundleTopBar
7269import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog
7370import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton
7471import app.revanced.manager.ui.component.haptics.HapticTab
7572import app.revanced.manager.ui.viewmodel.DashboardViewModel
7673import app.revanced.manager.util.RequestInstallAppsContract
77- import app.revanced.manager.util.toast
7874import kotlinx.coroutines.launch
7975import org.koin.androidx.compose.koinViewModel
8076
@@ -91,20 +87,18 @@ enum class DashboardPage(
9187@Composable
9288fun DashboardScreen (
9389 vm : DashboardViewModel = koinViewModel(),
94- onAppSelectorClick : () -> Unit ,
9590 onSettingsClick : () -> Unit ,
9691 onUpdateClick : () -> Unit ,
9792 onAnnouncementsClick : () -> Unit ,
9893 onAnnouncementClick : (ReVancedAnnouncement ) -> Unit ,
99- onDownloaderClick : () -> Unit ,
100- onAppClick : (String ) -> Unit
94+ onAppClick : (String ) -> Unit ,
95+ onPatchableAppClick : (String ) -> Unit ,
96+ onStorageSelect : (packageName: String , path: String ) -> Unit ,
10197) {
10298 var selectedSourceCount by rememberSaveable { mutableIntStateOf(0 ) }
10399 val bundlesSelectable by remember { derivedStateOf { selectedSourceCount > 0 } }
104- val availablePatches by vm.availablePatches.collectAsStateWithLifecycle(0 )
105100 val bundleDownloadError by vm.bundleDownloadError.collectAsStateWithLifecycle(null )
106101 val androidContext = LocalContext .current
107- val resources = LocalResources .current
108102 val composableScope = rememberCoroutineScope()
109103 val pagerState = rememberPagerState(
110104 initialPage = DashboardPage .DASHBOARD .ordinal,
@@ -136,7 +130,6 @@ fun DashboardScreen(
136130 var showUpdateDialog by rememberSaveable { mutableStateOf(true ) }
137131 val showManagerUpdateDialogOnLaunch by vm.prefs.showManagerUpdateDialogOnLaunch.getAsState()
138132 val availableUpdate = vm.updatedManagerVersion
139-
140133 if (showUpdateDialog && showManagerUpdateDialogOnLaunch && availableUpdate != null ) {
141134 AvailableUpdateDialog (
142135 onDismiss = { showUpdateDialog = false },
@@ -146,20 +139,77 @@ fun DashboardScreen(
146139 )
147140 }
148141
142+ var pendingPatchablePackage by rememberSaveable { mutableStateOf<String ?>(null ) }
143+ var pendingStoragePackage by rememberSaveable { mutableStateOf<String ?>(null ) }
144+ var pendingStoragePath by rememberSaveable { mutableStateOf<String ?>(null ) }
145+
146+ fun clearPendingSelection () {
147+ pendingPatchablePackage = null
148+ pendingStoragePackage = null
149+ pendingStoragePath = null
150+ }
151+
152+ fun resumePendingSelection () {
153+ pendingPatchablePackage?.let {
154+ clearPendingSelection()
155+ onPatchableAppClick(it)
156+ return
157+ }
158+
159+ val storagePackage = pendingStoragePackage
160+ val storagePath = pendingStoragePath
161+ if (storagePackage != null && storagePath != null ) {
162+ clearPendingSelection()
163+ onStorageSelect(storagePackage, storagePath)
164+ }
165+ }
166+
149167 var showAndroid11Dialog by rememberSaveable { mutableStateOf(false ) }
150168 val installAppsPermissionLauncher =
151169 rememberLauncherForActivityResult(RequestInstallAppsContract ) { granted ->
152170 showAndroid11Dialog = false
153- if (granted) onAppSelectorClick()
171+ if (granted) {
172+ resumePendingSelection()
173+ } else {
174+ clearPendingSelection()
175+ }
154176 }
155- if (showAndroid11Dialog) Android11Dialog (
156- onDismissRequest = {
157- showAndroid11Dialog = false
158- },
159- onContinue = {
160- installAppsPermissionLauncher.launch(androidContext.packageName)
177+
178+ if (showAndroid11Dialog) {
179+ Android11Dialog (
180+ onDismissRequest = {
181+ showAndroid11Dialog = false
182+ clearPendingSelection()
183+ },
184+ onContinue = {
185+ installAppsPermissionLauncher.launch(androidContext.packageName)
186+ }
187+ )
188+ }
189+
190+ fun onPatchableSelection (packageName : String ) {
191+ if (vm.android11BugActive) {
192+ pendingPatchablePackage = packageName
193+ pendingStoragePackage = null
194+ pendingStoragePath = null
195+ showAndroid11Dialog = true
196+ return
161197 }
162- )
198+
199+ onPatchableAppClick(packageName)
200+ }
201+
202+ fun onStorageSelection (packageName : String , path : String ) {
203+ if (vm.android11BugActive) {
204+ pendingPatchablePackage = null
205+ pendingStoragePackage = packageName
206+ pendingStoragePath = path
207+ showAndroid11Dialog = true
208+ return
209+ }
210+
211+ onStorageSelect(packageName, path)
212+ }
163213
164214 var showDeleteConfirmationDialog by rememberSaveable { mutableStateOf(false ) }
165215 if (showDeleteConfirmationDialog) {
@@ -185,23 +235,11 @@ fun DashboardScreen(
185235 )
186236 },
187237 actions = {
188- IconButton (
189- onClick = {
190- showDeleteConfirmationDialog = true
191- }
192- ) {
193- Icon (
194- Icons .Outlined .DeleteOutline ,
195- stringResource(R .string.delete)
196- )
238+ IconButton (onClick = { showDeleteConfirmationDialog = true }) {
239+ Icon (Icons .Outlined .DeleteOutline , stringResource(R .string.delete))
197240 }
198- IconButton (
199- onClick = vm::updateSources
200- ) {
201- Icon (
202- Icons .Outlined .Refresh ,
203- stringResource(R .string.refresh)
204- )
241+ IconButton (onClick = vm::updateSources) {
242+ Icon (Icons .Outlined .Refresh , stringResource(R .string.refresh))
205243 }
206244 }
207245 )
@@ -210,14 +248,8 @@ fun DashboardScreen(
210248 title = stringResource(R .string.app_name),
211249 actions = {
212250 if (! vm.updatedManagerVersion.isNullOrEmpty()) {
213- IconButton (
214- onClick = onUpdateClick,
215- ) {
216- BadgedBox (
217- badge = {
218- Badge (modifier = Modifier .size(6 .dp))
219- }
220- ) {
251+ IconButton (onClick = onUpdateClick) {
252+ BadgedBox (badge = { Badge (modifier = Modifier .size(6 .dp)) }) {
221253 Icon (Icons .Outlined .Update , stringResource(R .string.update))
222254 }
223255 }
@@ -245,35 +277,17 @@ fun DashboardScreen(
245277 }
246278 },
247279 floatingActionButton = {
280+ val onBundlesTab = pagerState.currentPage == DashboardPage .BUNDLES .ordinal
281+ if (! onBundlesTab) return @Scaffold
282+
248283 HapticFloatingActionButton (
249284 onClick = {
250285 vm.cancelSourceSelection()
251-
252- when (pagerState.currentPage) {
253- DashboardPage .DASHBOARD .ordinal -> {
254- if (availablePatches < 1 ) {
255- androidContext.toast(resources.getString(R .string.no_patch_found))
256- composableScope.launch {
257- pagerState.animateScrollToPage(
258- DashboardPage .BUNDLES .ordinal
259- )
260- }
261- return @HapticFloatingActionButton
262- }
263- if (vm.android11BugActive) {
264- showAndroid11Dialog = true
265- return @HapticFloatingActionButton
266- }
267-
268- onAppSelectorClick()
269- }
270-
271- DashboardPage .BUNDLES .ordinal -> {
272- showAddBundleDialog = true
273- }
274- }
286+ showAddBundleDialog = true
275287 }
276- ) { Icon (Icons .Default .Add , stringResource(R .string.add)) }
288+ ) {
289+ Icon (Icons .Default .Add , stringResource(R .string.add))
290+ }
277291 }
278292 ) { paddingValues ->
279293 Column (Modifier .padding(paddingValues)) {
@@ -364,31 +378,32 @@ fun DashboardScreen(
364378 state = pagerState,
365379 userScrollEnabled = true ,
366380 modifier = Modifier .fillMaxSize(),
367- pageContent = { index ->
368- when (DashboardPage .entries[index]) {
369- DashboardPage .DASHBOARD -> {
370- InstalledAppsScreen (
371- onAppClick = { onAppClick(it.currentPackageName) }
372- )
373- }
381+ ) { index ->
382+ when (DashboardPage .entries[index]) {
383+ DashboardPage .DASHBOARD -> InstalledAppsScreen (
384+ onAppClick = { onAppClick(it.currentPackageName) },
385+ onPatchableAppClick = ::onPatchableSelection,
386+ onStorageSelect = ::onStorageSelection,
387+ )
374388
375- DashboardPage .BUNDLES -> {
376- BackHandler {
377- if (bundlesSelectable) vm.cancelSourceSelection() else composableScope.launch {
378- pagerState.animateScrollToPage(
379- DashboardPage .DASHBOARD .ordinal
380- )
389+ DashboardPage .BUNDLES -> {
390+ BackHandler {
391+ if (bundlesSelectable) {
392+ vm.cancelSourceSelection()
393+ } else {
394+ composableScope.launch {
395+ pagerState.animateScrollToPage(DashboardPage .DASHBOARD .ordinal)
381396 }
382397 }
383-
384- BundleListScreen (
385- eventsFlow = vm.bundleListEventsFlow,
386- setSelectedSourceCount = { selectedSourceCount = it }
387- )
388398 }
399+
400+ BundleListScreen (
401+ eventsFlow = vm.bundleListEventsFlow,
402+ setSelectedSourceCount = { selectedSourceCount = it }
403+ )
389404 }
390405 }
391- )
406+ }
392407 }
393408 }
394409}
@@ -430,4 +445,4 @@ fun Android11Dialog(onDismissRequest: () -> Unit, onContinue: () -> Unit) {
430445 Text (stringResource(R .string.android_11_bug_dialog_description))
431446 }
432447 )
433- }
448+ }
0 commit comments