Improve flash console screen

This commit is contained in:
topjohnwu 2020-02-16 19:04:26 -08:00
parent 40f971d18a
commit 8453282fa6
11 changed files with 63 additions and 59 deletions

View File

@ -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()) }
}

View File

@ -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() {

View File

@ -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()
}
}

View File

@ -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)
@ -34,4 +34,4 @@ class BindingAdapter : BindingRecyclerViewAdapter<ComparableRvItem<*>>() {
this.recyclerView = recyclerView
}
}
}

View File

@ -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 }
@ -23,4 +32,4 @@ class ConsoleItem(val item: String) : LenientRvItem<ConsoleItem>() {
override fun contentSameAs(other: ConsoleItem) = itemSameAs(other)
override fun itemSameAs(other: ConsoleItem) = item == other.item
}
}

View File

@ -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()

View File

@ -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() {
@ -241,4 +242,4 @@ fun RecyclerView.setSpanCount(count: Int) {
is GridLayoutManager -> lama.spanCount = count
is StaggeredGridLayoutManager -> lama.spanCount = count
}
}
}

View File

@ -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}"

View File

@ -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>

View File

@ -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

View File

@ -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}"