fix(manager): back handler
This commit is contained in:
@@ -13,7 +13,11 @@
|
||||
tools:targetApi="34"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:icon="@android:drawable/ic_input_add">
|
||||
<activity android:name=".ui.MainActivity" android:exported="true" android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:screenOrientation="nosensor">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.*
|
||||
@@ -107,6 +108,7 @@ class InstallPackageTab : Tab("install_app") {
|
||||
} else it
|
||||
} ?: false }
|
||||
|
||||
BackHandler(installStage != InstallStage.DONE || installStage != InstallStage.ERROR) {}
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.rhunk.snapenhance.manager.ui.tab.impl.download
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
@@ -15,8 +16,11 @@ import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.compose.composable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import me.rhunk.snapenhance.manager.data.APKMirror
|
||||
import me.rhunk.snapenhance.manager.data.DownloadItem
|
||||
@@ -25,15 +29,19 @@ import me.rhunk.snapenhance.manager.ui.components.DowngradeNoticeDialog
|
||||
import me.rhunk.snapenhance.manager.ui.tab.Tab
|
||||
import okio.use
|
||||
import java.io.File
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
class LSPatchTab : Tab("lspatch") {
|
||||
private var localItemFile: File? = null
|
||||
private var downloadItem: DownloadItem? = null
|
||||
private var snapEnhanceModule: File? = null
|
||||
private var patchedApk by mutableStateOf<File?>(null)
|
||||
private val apkMirror = APKMirror()
|
||||
|
||||
private fun patch(log: (Any?) -> Unit, onProgress: (Float) -> Unit) {
|
||||
private fun patch(
|
||||
log: (Any?) -> Unit,
|
||||
onProgress: (Float) -> Unit,
|
||||
downloadItem: DownloadItem? = null,
|
||||
snapEnhanceModule: File? = null,
|
||||
localItemFile: File? = null,
|
||||
patchedApk: MutableState<File?>,
|
||||
) {
|
||||
var apkFile: File? = localItemFile
|
||||
|
||||
downloadItem?.let {
|
||||
@@ -91,119 +99,132 @@ class LSPatchTab : Tab("lspatch") {
|
||||
log("== Patching apk ==")
|
||||
val outputFiles = lsPatch.patchSplits(listOf(apkFile!!))
|
||||
|
||||
patchedApk = outputFiles["base.apk"] ?: run {
|
||||
patchedApk.value = outputFiles["base.apk"] ?: run {
|
||||
log("== Failed to patch apk ==")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
patchedApk = apkFile
|
||||
patchedApk.value = apkFile
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Suppress("DEPRECATION")
|
||||
override fun Content() {
|
||||
this.localItemFile = remember { getArguments()?.getString("localItemFile")?.let { File(it) } }
|
||||
this.downloadItem = remember { getArguments()?.getParcelable("downloadItem") }
|
||||
this.snapEnhanceModule = remember {
|
||||
getArguments()?.getString("modulePath")?.let {
|
||||
File(it)
|
||||
override fun build(navGraphBuilder: NavGraphBuilder) {
|
||||
var currentJob: Job? = null
|
||||
val coroutineScope = CoroutineScope(Dispatchers.IO)
|
||||
val patchedApk = mutableStateOf<File?>(null)
|
||||
val status = mutableStateOf("")
|
||||
var progress by mutableFloatStateOf(-1f)
|
||||
var isRunning by Delegates.observable(false) { _, _, newValue ->
|
||||
if (!newValue) {
|
||||
currentJob?.cancel()
|
||||
currentJob = null
|
||||
progress = -1f
|
||||
}
|
||||
}
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var showDowngradeNoticeDialog by remember { mutableStateOf(false) }
|
||||
navGraphBuilder.composable(route) {
|
||||
var showDowngradeNoticeDialog by remember { mutableStateOf(false) }
|
||||
|
||||
var status by remember { mutableStateOf("") }
|
||||
var progress by remember { mutableFloatStateOf(-1f) }
|
||||
|
||||
LaunchedEffect(this.snapEnhanceModule) {
|
||||
patchedApk = null
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
runCatching {
|
||||
patch(log = {
|
||||
LaunchedEffect(Unit) {
|
||||
if (isRunning) return@LaunchedEffect
|
||||
status.value = ""
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
isRunning = true
|
||||
runCatching {
|
||||
patch(
|
||||
localItemFile = getArguments()?.getString("localItemFile")?.let { File(it) } ,
|
||||
log = {
|
||||
coroutineScope.launch {
|
||||
status.value += when (it) {
|
||||
is Throwable -> it.message + "\n" + it.stackTraceToString()
|
||||
else -> it.toString()
|
||||
} + "\n"
|
||||
}
|
||||
},
|
||||
downloadItem = getArguments()?.getParcelable("downloadItem"),
|
||||
snapEnhanceModule = getArguments()?.getString("modulePath")?.let {
|
||||
File(it)
|
||||
},
|
||||
patchedApk = patchedApk,
|
||||
onProgress = { progress = it }
|
||||
)
|
||||
}.onFailure {
|
||||
coroutineScope.launch {
|
||||
status += when (it) {
|
||||
is Throwable -> it.message + "\n" + it.stackTraceToString()
|
||||
else -> it.toString()
|
||||
} + "\n"
|
||||
status.value += it.message + "\n" + it.stackTraceToString()
|
||||
}
|
||||
}) {
|
||||
progress = it
|
||||
}
|
||||
}.onFailure {
|
||||
coroutineScope.launch {
|
||||
status += it.message + "\n" + it.stackTraceToString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
coroutineScope.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
fun triggerInstallation(shouldUninstall: Boolean) {
|
||||
navigation.navigateTo(InstallPackageTab::class, args = Bundle().apply {
|
||||
putString("downloadPath", patchedApk?.absolutePath)
|
||||
putString("appPackage", sharedConfig.snapchatPackageName)
|
||||
putBoolean("uninstall", shouldUninstall)
|
||||
})
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(20.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(10.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Text(text = status, overflow = TextOverflow.Visible, modifier = Modifier.padding(10.dp))
|
||||
}
|
||||
}
|
||||
if (progress != -1f) {
|
||||
LinearProgressIndicator(progress = progress, modifier = Modifier.height(10.dp), strokeCap = StrokeCap.Round)
|
||||
isRunning = false
|
||||
}.also { currentJob = it }
|
||||
}
|
||||
|
||||
if (patchedApk != null) {
|
||||
Button(modifier = Modifier.fillMaxWidth(), onClick = {
|
||||
triggerInstallation(true)
|
||||
}) {
|
||||
Text(text = "Uninstall & Install")
|
||||
}
|
||||
|
||||
Button(modifier = Modifier.fillMaxWidth(), onClick = {
|
||||
showDowngradeNoticeDialog = true
|
||||
}) {
|
||||
Text(text = "Update")
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
if (isRunning) return@onDispose
|
||||
patchedApk.value = null
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(status) {
|
||||
scrollState.scrollTo(scrollState.maxValue)
|
||||
}
|
||||
}
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
if (showDowngradeNoticeDialog) {
|
||||
Dialog(onDismissRequest = { showDowngradeNoticeDialog = false }) {
|
||||
DowngradeNoticeDialog(onDismiss = { showDowngradeNoticeDialog = false }, onSuccess = {
|
||||
triggerInstallation(false)
|
||||
fun triggerInstallation(shouldUninstall: Boolean) {
|
||||
navigation.navigateTo(InstallPackageTab::class, args = Bundle().apply {
|
||||
putString("downloadPath", patchedApk.value?.absolutePath)
|
||||
putString("appPackage", sharedConfig.snapchatPackageName)
|
||||
putBoolean("uninstall", shouldUninstall)
|
||||
})
|
||||
}
|
||||
BackHandler(isRunning) {}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(20.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(10.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Text(text = status.value, overflow = TextOverflow.Visible, modifier = Modifier.padding(10.dp))
|
||||
}
|
||||
}
|
||||
if (progress != -1f) {
|
||||
LinearProgressIndicator(progress = progress, modifier = Modifier.height(10.dp), strokeCap = StrokeCap.Round)
|
||||
}
|
||||
|
||||
if (patchedApk.value != null) {
|
||||
Button(modifier = Modifier.fillMaxWidth(), onClick = {
|
||||
triggerInstallation(true)
|
||||
}) {
|
||||
Text(text = "Uninstall & Install")
|
||||
}
|
||||
|
||||
Button(modifier = Modifier.fillMaxWidth(), onClick = {
|
||||
showDowngradeNoticeDialog = true
|
||||
}) {
|
||||
Text(text = "Update")
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(status) {
|
||||
scrollState.scrollTo(scrollState.maxValue)
|
||||
}
|
||||
}
|
||||
|
||||
if (showDowngradeNoticeDialog) {
|
||||
Dialog(onDismissRequest = { showDowngradeNoticeDialog = false }) {
|
||||
DowngradeNoticeDialog(onDismiss = { showDowngradeNoticeDialog = false }, onSuccess = {
|
||||
triggerInstallation(false)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,7 +279,7 @@ class SnapchatPatchTab : Tab("snapchat_download") {
|
||||
navigation.navigateTo(LSPatchTab::class, args = Bundle().apply {
|
||||
putParcelable("downloadItem", selectedSnapchatVersion)
|
||||
putString("modulePath", installedSnapEnhanceVersion?.applicationInfo?.sourceDir)
|
||||
}, noHistory = true)
|
||||
})
|
||||
}
|
||||
) {
|
||||
Text("Download & Patch")
|
||||
@@ -292,7 +292,7 @@ class SnapchatPatchTab : Tab("snapchat_download") {
|
||||
navigation.navigateTo(LSPatchTab::class, args = Bundle().apply {
|
||||
putString("localItemFile", installedSnapchatPackage?.applicationInfo?.sourceDir ?: return@apply)
|
||||
putString("modulePath", installedSnapEnhanceVersion?.applicationInfo?.sourceDir ?: return@apply)
|
||||
}, noHistory = true)
|
||||
})
|
||||
}
|
||||
) {
|
||||
Text("Patch from existing installation")
|
||||
@@ -306,7 +306,7 @@ class SnapchatPatchTab : Tab("snapchat_download") {
|
||||
onClick = {
|
||||
navigation.navigateTo(LSPatchTab::class, args = Bundle().apply {
|
||||
putParcelable("downloadItem", selectedSnapchatVersion)
|
||||
}, noHistory = true)
|
||||
})
|
||||
}
|
||||
) {
|
||||
Text("Install/Restore Original Snapchat")
|
||||
|
||||
Reference in New Issue
Block a user