From 613f2d31c59da87e5f52df8def9ed04ba1ded0f8 Mon Sep 17 00:00:00 2001 From: vvb2060 Date: Tue, 22 Oct 2024 18:23:29 +0800 Subject: [PATCH] app: auto close action fragment only when focus lost --- .../magisk/ui/module/ActionFragment.kt | 52 ++++++++----------- .../magisk/ui/module/ActionViewModel.kt | 26 ++++++---- .../topjohnwu/magisk/core/tasks/RunAction.kt | 42 --------------- 3 files changed, 37 insertions(+), 83 deletions(-) delete mode 100644 app/core/src/main/java/com/topjohnwu/magisk/core/tasks/RunAction.kt diff --git a/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionFragment.kt b/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionFragment.kt index a8c4a4994..e3055a7ce 100644 --- a/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionFragment.kt +++ b/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionFragment.kt @@ -8,6 +8,7 @@ import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View +import android.view.ViewTreeObserver import android.widget.Toast import androidx.core.view.MenuProvider import androidx.core.view.isVisible @@ -16,8 +17,6 @@ import com.topjohnwu.magisk.arch.BaseFragment import com.topjohnwu.magisk.arch.viewModel import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.databinding.FragmentActionMd2Binding -import com.topjohnwu.magisk.ui.flash.FlashViewModel -import timber.log.Timber import com.topjohnwu.magisk.core.R as CoreR class ActionFragment : BaseFragment(), MenuProvider { @@ -37,39 +36,32 @@ class ActionFragment : BaseFragment(), MenuProvider { super.onStart() activity?.setTitle(viewModel.args.name) binding.closeBtn.setOnClickListener { - activity?.onBackPressed(); + activity?.onBackPressed() } viewModel.state.observe(this) { - activity?.supportActionBar?.setSubtitle( - when (it) { - ActionViewModel.State.RUNNING -> CoreR.string.running - ActionViewModel.State.SUCCESS -> CoreR.string.done - ActionViewModel.State.FAILED -> CoreR.string.failure + if (it != ActionViewModel.State.RUNNING) { + binding.closeBtn.apply { + if (!this.isVisible) this.show() + if (!this.isFocused) this.requestFocus() + } + } + if (it != ActionViewModel.State.SUCCESS) return@observe + view?.viewTreeObserver?.addOnWindowFocusChangeListener( + object : ViewTreeObserver.OnWindowFocusChangeListener { + override fun onWindowFocusChanged(hasFocus: Boolean) { + if (hasFocus) return + view?.viewTreeObserver?.removeOnWindowFocusChangeListener(this) + view?.context?.apply { + toast( + getString(CoreR.string.done_action, viewModel.args.name), + Toast.LENGTH_SHORT + ) + } + viewModel.back() + } } ) - when (it) { - ActionViewModel.State.SUCCESS -> { - activity?.apply { - toast( - getString( - com.topjohnwu.magisk.core.R.string.done_action, - this@ActionFragment.viewModel.args.name - ), Toast.LENGTH_LONG - ) - onBackPressed() - } - } - - ActionViewModel.State.FAILED -> { - binding.closeBtn.apply { - if (!this.isVisible) this.show() - if (!this.isFocused) this.requestFocus() - } - } - - else -> {} - } } } diff --git a/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionViewModel.kt b/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionViewModel.kt index 6f1f78c6d..2591aadd1 100644 --- a/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionViewModel.kt +++ b/app/apk/src/main/java/com/topjohnwu/magisk/ui/module/ActionViewModel.kt @@ -1,28 +1,26 @@ package com.topjohnwu.magisk.ui.module import android.view.MenuItem -import androidx.databinding.Bindable import androidx.databinding.ObservableArrayList import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.map import androidx.lifecycle.viewModelScope -import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.arch.BaseViewModel -import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.ktx.synchronized import com.topjohnwu.magisk.core.ktx.timeFormatStandard import com.topjohnwu.magisk.core.ktx.toTime -import com.topjohnwu.magisk.core.tasks.RunAction import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream -import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.events.SnackbarEvent import com.topjohnwu.magisk.ui.flash.ConsoleItem import com.topjohnwu.superuser.CallbackList +import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import timber.log.Timber +import java.io.IOException class ActionViewModel : BaseViewModel() { @@ -32,7 +30,6 @@ class ActionViewModel : BaseViewModel() { private val _state = MutableLiveData(State.RUNNING) val state: LiveData get() = _state - val running = state.map { it == State.RUNNING } val items = ObservableArrayList() lateinit var args: ActionFragmentArgs @@ -46,10 +43,17 @@ class ActionViewModel : BaseViewModel() { } } - fun startRunAction() { - viewModelScope.launch { - onResult(RunAction(args.id, outItems, logItems).exec()) - } + fun startRunAction() = viewModelScope.launch { + onResult(withContext(Dispatchers.IO) { + try { + Shell.cmd("run_action \'${args.id}\'") + .to(outItems, logItems) + .exec().isSuccess + } catch (e: IOException) { + Timber.e(e) + false + } + }) } private fun onResult(success: Boolean) { diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/RunAction.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/RunAction.kt deleted file mode 100644 index 145849d5b..000000000 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/RunAction.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.topjohnwu.magisk.core.tasks - -import android.net.Uri -import androidx.core.net.toFile -import com.topjohnwu.magisk.core.AppContext -import com.topjohnwu.magisk.core.Const -import com.topjohnwu.magisk.core.ktx.writeTo -import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName -import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream -import com.topjohnwu.magisk.core.utils.unzip -import com.topjohnwu.superuser.Shell -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import timber.log.Timber -import java.io.File -import java.io.FileNotFoundException -import java.io.IOException - -open class RunAction( - private val module: String, - private val console: MutableList, - private val logs: MutableList -) { - @Throws(IOException::class) - private suspend fun run(): Boolean { - return Shell.cmd("run_action \'$module\'").to(console, logs).exec().isSuccess - } - - open suspend fun exec() = withContext(Dispatchers.IO) { - try { - if (!run()) { - console.add("! Run action failed") - false - } else { - true - } - } catch (e: IOException) { - Timber.e(e) - false - } - } -}