@@ -9,6 +9,7 @@ import android.widget.Toast
99import androidx.databinding.Bindable
1010import androidx.lifecycle.LiveData
1111import androidx.lifecycle.MutableLiveData
12+ import androidx.lifecycle.Observer
1213import androidx.lifecycle.viewModelScope
1314import com.topjohnwu.magisk.BR
1415import com.topjohnwu.magisk.R
@@ -46,31 +47,55 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
4647 set(value) = set(value, field, { field = it }, BR .step)
4748
4849 private var methodId = - 1
50+ private var spuriousMethodId = - 1
4951
5052 @get:Bindable
5153 var method
5254 get() = methodId
5355 set(value) = set(value, methodId, { methodId = it }, BR .method) {
56+ if (it == spuriousMethodId) {
57+ spuriousMethodId = - 1
58+ return @set
59+ }
5460 when (it) {
5561 R .id.method_patch -> {
5662 GetContentEvent (" */*" , UriCallback ()).publish()
5763 }
5864 R .id.method_download -> {
59- DownloadDialog { url -> uri.value = url }.show()
65+ DownloadDialog (
66+ callback = { url -> _uri .value = url },
67+ onCancel = { resetMethod() },
68+ ).show()
6069 }
6170 R .id.method_inactive_slot -> {
6271 SecondSlotWarningDialog ().show()
6372 }
6473 }
6574 }
6675
67- val data: LiveData <Uri ?> get() = uri
76+ private fun resetMethod () {
77+ spuriousMethodId = methodId
78+ method = - 1
79+ }
80+
81+ private val _uri = MutableLiveData <Uri ?>()
82+ val data: LiveData <Uri ?> get() = _uri
83+
84+ private val sourceObserver = Observer <PatchSource ?> { source ->
85+ when (source) {
86+ is PatchSource .File -> _uri .value = source.uri
87+ PatchSource .Cancelled -> resetMethod()
88+ null -> return @Observer
89+ }
90+ patchSource.value = null
91+ }
6892
6993 @get:Bindable
7094 var notes: Spanned = SpannedString (" " )
7195 set(value) = set(value, field, { field = it }, BR .notes)
7296
7397 init {
98+ patchSource.observeForever(sourceObserver)
7499 viewModelScope.launch(Dispatchers .IO ) {
75100 try {
76101 val noteFile = File (AppContext .cacheDir, " ${APP_VERSION_CODE } .md" )
@@ -125,14 +150,28 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
125150 }
126151 }
127152
153+ override fun onCleared () {
154+ patchSource.removeObserver(sourceObserver)
155+ super .onCleared()
156+ }
157+
158+ private sealed interface PatchSource {
159+ data class File (val uri : Uri ) : PatchSource
160+ data object Cancelled : PatchSource
161+ }
162+
128163 @Parcelize
129164 class UriCallback : ContentResultCallback {
130165 override fun onActivityLaunch () {
131166 AppContext .toast(CoreR .string.patch_file_msg, Toast .LENGTH_LONG )
132167 }
133168
134169 override fun onActivityResult (result : Uri ) {
135- uri.value = result
170+ patchSource.value = PatchSource .File (result)
171+ }
172+
173+ override fun onActivityCancel () {
174+ patchSource.value = PatchSource .Cancelled
136175 }
137176 }
138177
@@ -147,6 +186,6 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
147186
148187 companion object {
149188 private const val INSTALL_STATE_KEY = " install_state"
150- private val uri = MutableLiveData <Uri ?>()
189+ private val patchSource = MutableLiveData <PatchSource ?>()
151190 }
152191}
0 commit comments