Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions app/src/main/java/app/morphe/manager/ui/screen/home/HomeDialogs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ import app.morphe.manager.domain.bundles.RemotePatchBundle
import app.morphe.manager.domain.repository.PatchBundleRepository
import app.morphe.manager.ui.model.HomeAppItem
import app.morphe.manager.ui.screen.shared.*
import app.morphe.manager.ui.viewmodel.BundledAppTarget
import app.morphe.manager.ui.viewmodel.HomeViewModel
import app.morphe.manager.ui.viewmodel.InstalledAppInfoViewModel
import app.morphe.manager.ui.viewmodel.SavedApkInfo
import app.morphe.manager.ui.viewmodel.*
import app.morphe.manager.util.*
import app.morphe.patcher.patch.AppTarget
import kotlinx.coroutines.delay
Expand Down Expand Up @@ -87,6 +84,8 @@ fun HomeDialogs(
val usingMountInstall = homeViewModel.usingMountInstall
val isExpertMode = homeViewModel.prefs.useExpertMode.getBlocking()
val savedApkInfo = homeViewModel.pendingSavedApkInfo
val installedApkInfo = homeViewModel.pendingInstalledApkInfo
val targetAppInstalled = homeViewModel.pendingTargetAppInstalled == true

ApkAvailabilityDialog(
appName = appName,
Expand All @@ -96,8 +95,10 @@ fun HomeDialogs(
selectedDownloadVersion = selectedDownloadVersion,
onVersionSelect = { homeViewModel.pendingSelectedDownloadVersion = it },
usingMountInstall = usingMountInstall,
targetAppInstalled = targetAppInstalled,
isExpertMode = isExpertMode,
savedApkInfo = savedApkInfo,
installedApkInfo = installedApkInfo,
onDismiss = {
homeViewModel.showApkAvailabilityDialog = false
homeViewModel.cleanupPendingData()
Expand All @@ -116,6 +117,9 @@ fun HomeDialogs(
},
onUseSaved = {
homeViewModel.handleSavedApkSelection()
},
onUseInstalled = {
homeViewModel.handleInstalledApkSelection()
}
)
}
Expand Down Expand Up @@ -146,6 +150,7 @@ fun HomeDialogs(

DownloadInstructionsDialog(
usingMountInstall = usingMountInstall,
targetAppInstalled = homeViewModel.pendingTargetAppInstalled == true,
downloadColor = downloadColor,
isApkBundle = isApkBundle,
onDismiss = {
Expand Down Expand Up @@ -543,12 +548,15 @@ private fun ApkAvailabilityDialog(
selectedDownloadVersion: AppTarget?,
onVersionSelect: (AppTarget) -> Unit,
usingMountInstall: Boolean,
targetAppInstalled: Boolean,
isExpertMode: Boolean,
savedApkInfo: SavedApkInfo?,
installedApkInfo: InstalledApkInfo?,
onDismiss: () -> Unit,
onHaveApk: () -> Unit,
onNeedApk: () -> Unit,
onUseSaved: () -> Unit
onUseSaved: () -> Unit,
onUseInstalled: () -> Unit
) {
val deviceSdk = Build.VERSION.SDK_INT

Expand Down Expand Up @@ -582,8 +590,10 @@ private fun ApkAvailabilityDialog(
layout = DialogButtonLayout.Vertical
)

// Saved APK button (if available)
if (savedApkInfo != null) {
// Saved APK button - hidden when installed APK is the same version,
// since the installed button already covers that case
if (savedApkInfo != null &&
(installedApkInfo == null || savedApkInfo.version != installedApkInfo.version)) {
MorpheDialogOutlinedButton(
text = stringResource(
R.string.home_apk_use_saved_with_version,
Expand All @@ -594,6 +604,19 @@ private fun ApkAvailabilityDialog(
modifier = Modifier.fillMaxWidth()
)
}

// Installed APK button (if the app is currently installed as a single APK)
if (installedApkInfo != null) {
MorpheDialogOutlinedButton(
text = stringResource(
R.string.home_apk_use_installed_with_version,
installedApkInfo.version
),
onClick = onUseInstalled,
icon = Icons.Outlined.PhoneAndroid,
modifier = Modifier.fillMaxWidth()
)
}
}
}
) {
Expand Down Expand Up @@ -658,8 +681,8 @@ private fun ApkAvailabilityDialog(
)
}

// Root mode warning
if (usingMountInstall) {
// Root mode warning - only when app is not yet installed
if (usingMountInstall && !targetAppInstalled) {
InfoBadge(
text = stringResource(R.string.root_install_apk_required),
style = InfoBadgeStyle.Warning,
Expand All @@ -679,6 +702,7 @@ private fun ApkAvailabilityDialog(
@Composable
private fun DownloadInstructionsDialog(
usingMountInstall: Boolean,
targetAppInstalled: Boolean,
downloadColor: Color,
isApkBundle: Boolean,
onDismiss: () -> Unit,
Expand Down Expand Up @@ -771,11 +795,13 @@ private fun DownloadInstructionsDialog(
}
}

val mountInstallRequired = usingMountInstall && !targetAppInstalled

InstructionStep(
number = "3",
text = htmlAnnotatedString(
stringResource(
if (usingMountInstall) {
if (mountInstallRequired) {
R.string.home_download_instructions_step3_mount
} else {
R.string.home_download_instructions_step3
Expand All @@ -789,7 +815,7 @@ private fun DownloadInstructionsDialog(
InstructionStep(
number = "4",
text = stringResource(
if (usingMountInstall) R.string.home_download_instructions_step4_mount
if (mountInstallRequired) R.string.home_download_instructions_step4_mount
else R.string.home_download_instructions_step4
),
textColor = textColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import androidx.compose.material.icons.filled.DeleteForever
import androidx.compose.material.icons.filled.Error
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.InstallMobile
import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material.icons.outlined.Link
import androidx.compose.material3.*
import androidx.compose.runtime.*
Expand Down Expand Up @@ -294,6 +295,8 @@ private fun AdaptiveSuccessContent(
isError = isError
)

SuccessConflictHint(isConflict = isConflict)

SuccessRootWarning(
usingMountInstall = usingMountInstall,
isReady = !isInstalling && !isInstalled && !isError && !isConflict
Expand Down Expand Up @@ -353,6 +356,8 @@ private fun AdaptiveSuccessContent(
isError = isError
)

SuccessConflictHint(isConflict = isConflict)

SuccessRootWarning(
usingMountInstall = usingMountInstall,
isReady = !isInstalling && !isInstalled && !isError && !isConflict
Expand Down Expand Up @@ -499,6 +504,20 @@ private fun SuccessErrorMessage(
}
}

/**
* Success screen conflict hint.
*/
@Composable
private fun SuccessConflictHint(isConflict: Boolean) {
SuccessHint(
visible = isConflict,
text = stringResource(R.string.patcher_conflict_hint),
icon = Icons.Outlined.Warning,
containerColor = MaterialTheme.colorScheme.errorContainer.copy(alpha = 0.3f),
iconTint = MaterialTheme.colorScheme.error
)
}

/**
* Success screen root warning.
*/
Expand All @@ -507,17 +526,51 @@ private fun SuccessRootWarning(
usingMountInstall: Boolean,
isReady: Boolean
) {
AnimatedVisibility(
SuccessHint(
visible = usingMountInstall && isReady,
text = stringResource(R.string.root_gmscore_excluded),
icon = Icons.Outlined.Info,
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f),
iconTint = MaterialTheme.colorScheme.primary
)
}

@Composable
private fun SuccessHint(
visible: Boolean,
text: String,
icon: ImageVector,
containerColor: Color,
iconTint: Color
) {
AnimatedVisibility(
visible = visible,
enter = MorpheAnimations.fadeIn,
exit = MorpheAnimations.fadeOut
) {
InfoBadge(
text = stringResource(R.string.root_gmscore_excluded),
style = InfoBadgeStyle.Primary,
icon = Icons.Outlined.Info,
isCentered = true
)
Surface(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
color = containerColor
) {
Row(
modifier = Modifier.padding(16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = icon,
contentDescription = null,
tint = iconTint,
modifier = Modifier.size(20.dp)
)
Text(
text = text,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface
)
}
}
}
}

Expand All @@ -537,16 +590,13 @@ private fun InstallActionButton(
onOpen: () -> Unit,
modifier: Modifier = Modifier
) {
val buttonColors = when {
isInstalled -> ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary
)
isConflict || isError -> ButtonDefaults.buttonColors(
val buttonColors = if (isConflict || isError) {
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.error,
contentColor = MaterialTheme.colorScheme.onError
)
else -> ButtonDefaults.buttonColors(
} else {
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary
)
Expand All @@ -557,7 +607,6 @@ private fun InstallActionButton(
when {
isInstalled -> onOpen()
isConflict -> conflictPackageName?.let { onUninstall(it) }
isError -> onInstall()
else -> onInstall()
}
},
Expand Down Expand Up @@ -587,7 +636,6 @@ private fun InstallActionButton(
imageVector = when {
isInstalled -> Icons.AutoMirrored.Outlined.Launch
isConflict -> Icons.Default.DeleteForever
isError -> Icons.Outlined.InstallMobile
usingMountInstall -> Icons.Outlined.Link
else -> Icons.Outlined.InstallMobile
},
Expand All @@ -600,7 +648,6 @@ private fun InstallActionButton(
when {
isInstalled -> R.string.open
isConflict -> R.string.uninstall
isError -> R.string.install
usingMountInstall -> R.string.mount
else -> R.string.install
}
Expand Down
Loading
Loading