mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-25 02:55:33 +00:00
app: auto close action fragment only when focus lost
This commit is contained in:
parent
7dbb973db5
commit
613f2d31c5
@ -8,6 +8,7 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewTreeObserver
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import androidx.core.view.isVisible
|
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.arch.viewModel
|
||||||
import com.topjohnwu.magisk.core.ktx.toast
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
import com.topjohnwu.magisk.databinding.FragmentActionMd2Binding
|
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
|
import com.topjohnwu.magisk.core.R as CoreR
|
||||||
|
|
||||||
class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
|
class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
|
||||||
@ -37,39 +36,32 @@ class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
|
|||||||
super.onStart()
|
super.onStart()
|
||||||
activity?.setTitle(viewModel.args.name)
|
activity?.setTitle(viewModel.args.name)
|
||||||
binding.closeBtn.setOnClickListener {
|
binding.closeBtn.setOnClickListener {
|
||||||
activity?.onBackPressed();
|
activity?.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.state.observe(this) {
|
viewModel.state.observe(this) {
|
||||||
activity?.supportActionBar?.setSubtitle(
|
if (it != ActionViewModel.State.RUNNING) {
|
||||||
when (it) {
|
|
||||||
ActionViewModel.State.RUNNING -> CoreR.string.running
|
|
||||||
ActionViewModel.State.SUCCESS -> CoreR.string.done
|
|
||||||
ActionViewModel.State.FAILED -> CoreR.string.failure
|
|
||||||
}
|
|
||||||
)
|
|
||||||
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 {
|
binding.closeBtn.apply {
|
||||||
if (!this.isVisible) this.show()
|
if (!this.isVisible) this.show()
|
||||||
if (!this.isFocused) this.requestFocus()
|
if (!this.isFocused) this.requestFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (it != ActionViewModel.State.SUCCESS) return@observe
|
||||||
else -> {}
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
package com.topjohnwu.magisk.ui.module
|
package com.topjohnwu.magisk.ui.module
|
||||||
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.databinding.Bindable
|
|
||||||
import androidx.databinding.ObservableArrayList
|
import androidx.databinding.ObservableArrayList
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.map
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.topjohnwu.magisk.BR
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
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.synchronized
|
||||||
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
|
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
|
||||||
import com.topjohnwu.magisk.core.ktx.toTime
|
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
|
||||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
|
||||||
import com.topjohnwu.magisk.databinding.set
|
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.ui.flash.ConsoleItem
|
import com.topjohnwu.magisk.ui.flash.ConsoleItem
|
||||||
import com.topjohnwu.superuser.CallbackList
|
import com.topjohnwu.superuser.CallbackList
|
||||||
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
class ActionViewModel : BaseViewModel() {
|
class ActionViewModel : BaseViewModel() {
|
||||||
|
|
||||||
@ -32,7 +30,6 @@ class ActionViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
private val _state = MutableLiveData(State.RUNNING)
|
private val _state = MutableLiveData(State.RUNNING)
|
||||||
val state: LiveData<State> get() = _state
|
val state: LiveData<State> get() = _state
|
||||||
val running = state.map { it == State.RUNNING }
|
|
||||||
|
|
||||||
val items = ObservableArrayList<ConsoleItem>()
|
val items = ObservableArrayList<ConsoleItem>()
|
||||||
lateinit var args: ActionFragmentArgs
|
lateinit var args: ActionFragmentArgs
|
||||||
@ -46,10 +43,17 @@ class ActionViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startRunAction() {
|
fun startRunAction() = viewModelScope.launch {
|
||||||
viewModelScope.launch {
|
onResult(withContext(Dispatchers.IO) {
|
||||||
onResult(RunAction(args.id, outItems, logItems).exec())
|
try {
|
||||||
|
Shell.cmd("run_action \'${args.id}\'")
|
||||||
|
.to(outItems, logItems)
|
||||||
|
.exec().isSuccess
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Timber.e(e)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onResult(success: Boolean) {
|
private fun onResult(success: Boolean) {
|
||||||
|
@ -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<String>,
|
|
||||||
private val logs: MutableList<String>
|
|
||||||
) {
|
|
||||||
@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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user