mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-21 14:48:29 +00:00
parent
ec2d7d77eb
commit
dd62fe89f7
@ -1,6 +1,7 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
package com.topjohnwu.magisk.ktx
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.collection.SparseArrayCompat
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@ -11,7 +12,6 @@ import java.text.SimpleDateFormat
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
import kotlin.NoSuchElementException
|
|
||||||
|
|
||||||
fun ZipInputStream.forEach(callback: (ZipEntry) -> Unit) {
|
fun ZipInputStream.forEach(callback: (ZipEntry) -> Unit) {
|
||||||
var entry: ZipEntry? = nextEntry
|
var entry: ZipEntry? = nextEntry
|
||||||
@ -36,13 +36,19 @@ inline fun <In : InputStream, Out : OutputStream> withStreams(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T, R> List<T>.firstMap(mapper: (T) -> R?): R {
|
fun <T> MutableList<T>.update(newList: List<T>) {
|
||||||
for (item: T in this) {
|
clear()
|
||||||
return mapper(item) ?: continue
|
addAll(newList)
|
||||||
}
|
|
||||||
throw NoSuchElementException("Collection contains no element matching the predicate.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun <E> SparseArrayCompat<E>.set(key: Int, value: E) {
|
||||||
|
put(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> MutableList<T>.synchronized() = Collections.synchronizedList(this)
|
||||||
|
fun <T> MutableSet<T>.synchronized() = Collections.synchronizedSet(this)
|
||||||
|
fun <K, V> MutableMap<K, V>.synchronized() = Collections.synchronizedMap(this)
|
||||||
|
|
||||||
fun String.langTagToLocale(): Locale {
|
fun String.langTagToLocale(): Locale {
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
return Locale.forLanguageTag(this)
|
return Locale.forLanguageTag(this)
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
|
||||||
|
|
||||||
import androidx.collection.SparseArrayCompat
|
|
||||||
import androidx.databinding.ObservableList
|
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
|
||||||
import kotlinx.coroutines.*
|
|
||||||
|
|
||||||
fun <T> MutableList<T>.update(newList: List<T>) {
|
|
||||||
clear()
|
|
||||||
addAll(newList)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun List<String>.toShellCmd(): String {
|
|
||||||
val sb = StringBuilder()
|
|
||||||
for (s in this) {
|
|
||||||
if (s.contains(" ")) {
|
|
||||||
sb.append('"').append(s).append('"')
|
|
||||||
} else {
|
|
||||||
sb.append(s)
|
|
||||||
}
|
|
||||||
sb.append(' ')
|
|
||||||
}
|
|
||||||
sb.deleteCharAt(sb.length - 1)
|
|
||||||
return sb.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T1, T2> ObservableList<T1>.sendUpdatesTo(
|
|
||||||
target: DiffObservableList<T2>,
|
|
||||||
scope: CoroutineScope,
|
|
||||||
mapper: (List<T1>) -> List<T2>
|
|
||||||
) = addOnListChangedCallback(object :
|
|
||||||
ObservableList.OnListChangedCallback<ObservableList<T1>>() {
|
|
||||||
override fun onChanged(sender: ObservableList<T1>?) {
|
|
||||||
updateAsync(sender ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeRemoved(sender: ObservableList<T1>?, p0: Int, p1: Int) {
|
|
||||||
updateAsync(sender ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeMoved(sender: ObservableList<T1>?, p0: Int, p1: Int, p2: Int) {
|
|
||||||
updateAsync(sender ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeInserted(sender: ObservableList<T1>?, p0: Int, p1: Int) {
|
|
||||||
updateAsync(sender ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeChanged(sender: ObservableList<T1>?, p0: Int, p1: Int) {
|
|
||||||
updateAsync(sender ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
private var updater: Job? = null
|
|
||||||
|
|
||||||
private fun updateAsync(sender: List<T1>) {
|
|
||||||
updater?.cancel()
|
|
||||||
updater = scope.launch {
|
|
||||||
val (list, diff) = withContext(Dispatchers.Default) {
|
|
||||||
val list = mapper(sender)
|
|
||||||
list to target.calculateDiff(list)
|
|
||||||
}
|
|
||||||
target.update(list, diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
fun <T1> ObservableList<T1>.copyNewInputInto(
|
|
||||||
target: MutableList<T1>
|
|
||||||
) = addOnListChangedCallback(object : ObservableList.OnListChangedCallback<ObservableList<T1>>() {
|
|
||||||
override fun onChanged(p0: ObservableList<T1>?) = Unit
|
|
||||||
override fun onItemRangeRemoved(p0: ObservableList<T1>?, p1: Int, p2: Int) = Unit
|
|
||||||
override fun onItemRangeMoved(p0: ObservableList<T1>?, p1: Int, p2: Int, p3: Int) = Unit
|
|
||||||
override fun onItemRangeChanged(p0: ObservableList<T1>?, p1: Int, p2: Int) = Unit
|
|
||||||
override fun onItemRangeInserted(
|
|
||||||
sender: ObservableList<T1>?,
|
|
||||||
positionStart: Int,
|
|
||||||
itemCount: Int
|
|
||||||
) {
|
|
||||||
val positionEnd = positionStart + itemCount
|
|
||||||
val addedValues = sender?.slice(positionStart until positionEnd).orEmpty()
|
|
||||||
target.addAll(addedValues)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
operator fun <E> SparseArrayCompat<E>.set(key: Int, value: E) {
|
|
||||||
put(key, value)
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ import android.content.res.Resources
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import androidx.databinding.ObservableArrayList
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
@ -21,12 +20,12 @@ import com.topjohnwu.magisk.ui.base.BaseViewModel
|
|||||||
import com.topjohnwu.magisk.ui.base.diffListOf
|
import com.topjohnwu.magisk.ui.base.diffListOf
|
||||||
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
|
import com.topjohnwu.superuser.CallbackList
|
||||||
import com.topjohnwu.superuser.Shell
|
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 kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class FlashViewModel(
|
class FlashViewModel(
|
||||||
args: FlashFragmentArgs,
|
args: FlashFragmentArgs,
|
||||||
@ -45,13 +44,16 @@ class FlashViewModel(
|
|||||||
val items = diffListOf<ConsoleItem>()
|
val items = diffListOf<ConsoleItem>()
|
||||||
val itemBinding = itemBindingOf<ConsoleItem>()
|
val itemBinding = itemBindingOf<ConsoleItem>()
|
||||||
|
|
||||||
private val outItems = ObservableArrayList<String>()
|
private val logItems = mutableListOf<String>().synchronized()
|
||||||
private val logItems = Collections.synchronizedList(mutableListOf<String>())
|
private val outItems = object : CallbackList<String>() {
|
||||||
|
override fun onAddElement(e: String?) {
|
||||||
|
e ?: return
|
||||||
|
items.add(ConsoleItem(e))
|
||||||
|
logItems.add(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
outItems.sendUpdatesTo(items, viewModelScope) { it.map { ConsoleItem(it) } }
|
|
||||||
outItems.copyNewInputInto(logItems)
|
|
||||||
|
|
||||||
args.dismissId.takeIf { it != -1 }?.also {
|
args.dismissId.takeIf { it != -1 }?.also {
|
||||||
Notifications.mgr.cancel(it)
|
Notifications.mgr.cancel(it)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user