Improve flash console screen
This commit is contained in:
parent
40f971d18a
commit
8453282fa6
@ -1,6 +1,5 @@
|
||||
package com.topjohnwu.magisk.di
|
||||
|
||||
import android.net.Uri
|
||||
import com.topjohnwu.magisk.legacy.flash.FlashViewModel
|
||||
import com.topjohnwu.magisk.legacy.surequest.SuRequestViewModel
|
||||
import com.topjohnwu.magisk.ui.MainViewModel
|
||||
@ -31,8 +30,6 @@ val viewModelModules = module {
|
||||
viewModel { MainViewModel() }
|
||||
|
||||
// Legacy
|
||||
viewModel { (action: String, file: Uri, additional: Uri) ->
|
||||
FlashViewModel(action, file, additional, get())
|
||||
}
|
||||
viewModel { FlashViewModel(get()) }
|
||||
viewModel { SuRequestViewModel(get(), get(), get(SUTimeout), get()) }
|
||||
}
|
||||
|
@ -18,18 +18,12 @@ import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||
import com.topjohnwu.magisk.ui.base.CompatNavigationDelegate
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import java.io.File
|
||||
|
||||
open class FlashActivity : BaseUIActivity<FlashViewModel, ActivityFlashBinding>() {
|
||||
|
||||
override val layoutRes: Int = R.layout.activity_flash
|
||||
override val viewModel: FlashViewModel by viewModel {
|
||||
val uri = intent.data ?: let { finish(); Uri.EMPTY }
|
||||
val additionalUri = intent.getParcelableExtra(Const.Key.FLASH_DATA) ?: uri
|
||||
val action = intent.getStringExtra(Const.Key.FLASH_ACTION) ?: let { finish();"" }
|
||||
parametersOf(action, uri, additionalUri)
|
||||
}
|
||||
override val viewModel: FlashViewModel by viewModel()
|
||||
|
||||
override val navigation: CompatNavigationDelegate<BaseUIActivity<FlashViewModel, ActivityFlashBinding>>? =
|
||||
null
|
||||
@ -40,6 +34,7 @@ open class FlashActivity : BaseUIActivity<FlashViewModel, ActivityFlashBinding>(
|
||||
val id = intent.getIntExtra(Const.Key.DISMISS_ID, -1)
|
||||
if (id != -1)
|
||||
Notifications.mgr.cancel(id)
|
||||
viewModel.startFlashing(intent)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
@ -2,35 +2,32 @@ package com.topjohnwu.magisk.legacy.flash
|
||||
|
||||
import android.Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.view.MenuItem
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.databinding.ObservableArrayList
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.*
|
||||
import com.topjohnwu.magisk.model.binding.BindingAdapter
|
||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.model.flash.FlashResultListener
|
||||
import com.topjohnwu.magisk.model.flash.Flashing
|
||||
import com.topjohnwu.magisk.model.flash.Patching
|
||||
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.ui.base.diffListOf
|
||||
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class FlashViewModel(
|
||||
action: String,
|
||||
installer: Uri,
|
||||
uri: Uri,
|
||||
private val resources: Resources
|
||||
) : BaseViewModel(), FlashResultListener {
|
||||
|
||||
@ -39,11 +36,9 @@ class FlashViewModel(
|
||||
|
||||
val behaviorText = KObservableField(resources.getString(R.string.flashing))
|
||||
|
||||
val items = DiffObservableList(ComparableRvItem.callback)
|
||||
val itemBinding = ItemBinding.of<ComparableRvItem<*>> { itemBinding, _, item ->
|
||||
item.bind(itemBinding)
|
||||
itemBinding.bindExtra(BR.viewModel, this@FlashViewModel)
|
||||
}
|
||||
val adapter = BindingAdapter<ConsoleItem>()
|
||||
val items = diffListOf<ConsoleItem>()
|
||||
val itemBinding = itemBindingOf<ConsoleItem>()
|
||||
|
||||
private val outItems = ObservableArrayList<String>()
|
||||
private val logItems = Collections.synchronizedList(mutableListOf<String>())
|
||||
@ -51,8 +46,12 @@ class FlashViewModel(
|
||||
init {
|
||||
outItems.sendUpdatesTo(items) { it.map { ConsoleItem(it) } }
|
||||
outItems.copyNewInputInto(logItems)
|
||||
}
|
||||
|
||||
state = State.LOADING
|
||||
fun startFlashing(intent: Intent) {
|
||||
val installer = intent.data ?: return
|
||||
val uri: Uri? = intent.getParcelableExtra(Const.Key.FLASH_DATA)
|
||||
val action = intent.getStringExtra(Const.Key.FLASH_ACTION) ?: return
|
||||
|
||||
when (action) {
|
||||
Const.Value.FLASH_ZIP -> Flashing
|
||||
@ -68,7 +67,7 @@ class FlashViewModel(
|
||||
.SecondSlot(installer, outItems, logItems, this)
|
||||
.exec()
|
||||
Const.Value.PATCH_FILE -> Patching
|
||||
.File(installer, uri, outItems, logItems, this)
|
||||
.File(installer, uri ?: return, outItems, logItems, this)
|
||||
.exec()
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.LenientRvItem
|
||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
||||
|
||||
class BindingAdapter : BindingRecyclerViewAdapter<ComparableRvItem<*>>() {
|
||||
class BindingAdapter <T : ComparableRvItem<*>> : BindingRecyclerViewAdapter<T>() {
|
||||
|
||||
private var recyclerView: RecyclerView? = null
|
||||
|
||||
@ -15,12 +15,12 @@ class BindingAdapter : BindingRecyclerViewAdapter<ComparableRvItem<*>>() {
|
||||
variableId: Int,
|
||||
layoutRes: Int,
|
||||
position: Int,
|
||||
item: ComparableRvItem<*>
|
||||
item: T
|
||||
) {
|
||||
super.onBindBinding(binding, variableId, layoutRes, position, item)
|
||||
|
||||
when (item) {
|
||||
is LenientRvItem -> {
|
||||
is LenientRvItem<*> -> {
|
||||
val recycler = recyclerView ?: return
|
||||
item.onBindingBound(binding)
|
||||
item.onBindingBound(binding, recycler)
|
||||
|
@ -1,18 +1,27 @@
|
||||
package com.topjohnwu.magisk.model.entity.recycler
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.R
|
||||
import kotlin.math.max
|
||||
|
||||
class ConsoleItem(val item: String) : LenientRvItem<ConsoleItem>() {
|
||||
override val layoutRes = R.layout.item_console_md2
|
||||
|
||||
private var parentWidth = -1
|
||||
|
||||
override fun onBindingBound(binding: ViewDataBinding, recyclerView: RecyclerView) {
|
||||
if (parentWidth < 0)
|
||||
parentWidth = (recyclerView.parent as View).width
|
||||
|
||||
val view = binding.root as TextView
|
||||
view.measure(0, 0)
|
||||
val desiredWidth = view.measuredWidth
|
||||
|
||||
// We want our recyclerView at least as wide as screen
|
||||
val desiredWidth = max(view.measuredWidth, parentWidth)
|
||||
|
||||
view.updateLayoutParams { width = desiredWidth }
|
||||
|
@ -5,7 +5,6 @@ import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.model.binding.BindingAdapter
|
||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
|
||||
@ -42,9 +41,9 @@ class LogViewModel(
|
||||
|
||||
// --- console
|
||||
|
||||
val consoleAdapter = BindingAdapter()
|
||||
val itemsConsole = diffListOf<ComparableRvItem<*>>()
|
||||
val itemConsoleBinding = itemBindingOf<ComparableRvItem<*>> {}
|
||||
val consoleAdapter = BindingAdapter<ConsoleItem>()
|
||||
val itemsConsole = diffListOf<ConsoleItem>()
|
||||
val itemConsoleBinding = itemBindingOf<ConsoleItem>()
|
||||
|
||||
override fun refresh(): Disposable {
|
||||
val logs = repo.fetchLogs()
|
||||
|
@ -23,6 +23,7 @@ import com.google.android.material.textfield.TextInputLayout
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.extensions.replaceRandomWithSpecial
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -62,12 +63,12 @@ fun setOnTouchListener(view: View, listener: View.OnTouchListener) {
|
||||
@BindingAdapter("scrollToLast")
|
||||
fun setScrollToLast(view: RecyclerView, shouldScrollToLast: Boolean) {
|
||||
|
||||
fun scrollToLast() = view.post {
|
||||
fun scrollToLast() = UiThreadHandler.handler.postDelayed({
|
||||
view.scrollToPosition(view.adapter?.itemCount?.minus(1) ?: 0)
|
||||
}
|
||||
}, 30)
|
||||
|
||||
fun wait(callback: () -> Unit) {
|
||||
Observable.timer(1, TimeUnit.SECONDS).subscribeK { callback() }
|
||||
UiThreadHandler.handler.postDelayed(callback, 1000)
|
||||
}
|
||||
|
||||
fun RecyclerView.Adapter<*>.setListener() {
|
||||
|
@ -56,21 +56,30 @@
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/flash_content"
|
||||
itemBinding="@{viewModel.itemBinding}"
|
||||
items="@{viewModel.items}"
|
||||
scrollToLast="@{true}"
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@{viewModel.insets.left}"
|
||||
android:paddingRight="@{viewModel.insets.right}"
|
||||
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:listitem="@layout/item_console_md2" />
|
||||
android:layout_marginTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
|
||||
tools:layout_marginTop="@dimen/internal_action_bar_size">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/flash_content"
|
||||
adapter="@{viewModel.adapter}"
|
||||
itemBinding="@{viewModel.itemBinding}"
|
||||
items="@{viewModel.items}"
|
||||
scrollToLast="@{true}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@{viewModel.insets.left}"
|
||||
android:paddingRight="@{viewModel.insets.right}"
|
||||
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:listitem="@layout/item_console_md2" />
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
gone="@{!viewModel.loaded || !viewModel.canShowReboot}"
|
||||
|
@ -30,7 +30,7 @@
|
||||
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
|
||||
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_console"
|
||||
tools:listitem="@layout/item_console_md2"
|
||||
tools:paddingTop="24dp" />
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
@ -8,11 +8,6 @@
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.model.entity.recycler.ConsoleItem" />
|
||||
|
||||
<!--no actions are required-->
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="Object" />
|
||||
|
||||
</data>
|
||||
|
||||
<TextView
|
||||
|
@ -16,7 +16,7 @@ buildscript {
|
||||
maven { url 'https://kotlin.bintray.com/kotlinx' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.0-rc02'
|
||||
classpath 'com.android.tools.build:gradle:3.6.0-rc03'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${vKotlin}"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user