Added custom install dialogs

This commit is contained in:
Viktor De Pasquale 2019-10-08 20:29:11 +02:00
parent 4a68fd65b6
commit 4292ddd0ae
7 changed files with 249 additions and 27 deletions

View File

@ -0,0 +1,16 @@
package com.topjohnwu.magisk.model.events.dialog
import android.content.Context
import com.skoumal.teanity.viewevents.ViewEvent
import com.topjohnwu.magisk.model.events.ContextExecutor
import com.topjohnwu.magisk.view.MagiskDialog
abstract class DialogEvent : ViewEvent(), ContextExecutor {
override fun invoke(context: Context) {
MagiskDialog(context).apply(this::build).reveal()
}
abstract fun build(dialog: MagiskDialog)
}

View File

@ -0,0 +1,81 @@
package com.topjohnwu.magisk.model.events.dialog
import com.topjohnwu.magisk.Info
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.res
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.MarkDownWindow
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
class MagiskInstallDialog : DialogEvent() {
override fun build(dialog: MagiskDialog) {
with(dialog) {
val filename =
"Magisk v${Info.remote.magisk.version}(${Info.remote.magisk.versionCode})"
applyTitle(R.string.repo_install_title.res(R.string.magisk.res()))
applyMessage(R.string.repo_install_msg.res(filename))
setCancelable(true)
applyButton(MagiskDialog.ButtonType.POSITIVE) {
titleRes = R.string.install
preventDismiss = true
onClick {
updateForInstallMethod(dialog)
}
}
if (Info.remote.magisk.note.isEmpty()) return
applyButton(MagiskDialog.ButtonType.NEGATIVE) {
titleRes = R.string.release_notes
onClick {
if (Info.remote.magisk.note.contains("forum.xda-developers")) {
OpenInappLinkEvent(Info.remote.magisk.note).invoke(context)
} else {
MarkDownWindow.show(context, null, Info.remote.magisk.note)
}
}
}
}
}
private fun updateForInstallMethod(dialog: MagiskDialog) {
with(dialog) {
applyTitle(R.string.select_method)
applyMessage("")
applyButton(MagiskDialog.ButtonType.POSITIVE) {
titleRes = R.string.download_zip_only
preventDismiss = false
onClick {
TODO()
}
}
applyButton(MagiskDialog.ButtonType.NEUTRAL) {
titleRes = R.string.select_patch_file
onClick {
TODO()
}
}
if (!Shell.rootAccess()) return
applyButton(MagiskDialog.ButtonType.NEGATIVE) {
titleRes = R.string.direct_install
onClick {
TODO()
}
}
if (!isABDevice()) return
applyButton(MagiskDialog.ButtonType.IDGAF) {
titleRes = R.string.install_inactive_slot
onClick {
TODO()
}
}
}
}
private fun isABDevice() = ShellUtils
.fastCmd("grep_prop ro.build.ab_update")
.let { it.isNotEmpty() && it.toBoolean() }
}

View File

@ -0,0 +1,36 @@
package com.topjohnwu.magisk.model.events.dialog
import com.topjohnwu.magisk.Info
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.res
import com.topjohnwu.magisk.model.download.DownloadService
import com.topjohnwu.magisk.model.entity.internal.Configuration
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.MarkDownWindow
class ManagerInstallDialog : DialogEvent() {
override fun build(dialog: MagiskDialog) {
with(dialog) {
val subject = DownloadSubject.Manager(Configuration.APK.Upgrade)
applyTitle(R.string.repo_install_title.res(R.string.app_name.res()))
applyMessage(R.string.repo_install_msg.res(subject.title))
setCancelable(true)
applyButton(MagiskDialog.ButtonType.POSITIVE) {
titleRes = R.string.install
onClick { DownloadService(context) { this.subject = subject } }
}
if (Info.remote.app.note.isEmpty()) return
applyButton(MagiskDialog.ButtonType.NEGATIVE) {
titleRes = R.string.app_changelog
onClick { MarkDownWindow.show(context, null, Info.remote.app.note) }
}
}
}
}

View File

@ -15,6 +15,8 @@ import com.topjohnwu.magisk.model.entity.ManagerJson
import com.topjohnwu.magisk.model.entity.UpdateInfo import com.topjohnwu.magisk.model.entity.UpdateInfo
import com.topjohnwu.magisk.model.entity.recycler.HomeItem import com.topjohnwu.magisk.model.entity.recycler.HomeItem
import com.topjohnwu.magisk.model.events.OpenInappLinkEvent import com.topjohnwu.magisk.model.events.OpenInappLinkEvent
import com.topjohnwu.magisk.model.events.dialog.MagiskInstallDialog
import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.redesign.compat.CompatViewModel import com.topjohnwu.magisk.redesign.compat.CompatViewModel
import com.topjohnwu.magisk.ui.home.MagiskState import com.topjohnwu.magisk.ui.home.MagiskState
@ -50,11 +52,10 @@ class HomeViewModel(
val stateVersionUpdateManager = KObservableField("") val stateVersionUpdateManager = KObservableField("")
val stateHideManagerName = R.string.manager.res().let { val stateHideManagerName = R.string.manager.res().let {
val result = R.string.manager.res()
if (!statePackageOriginal) { if (!statePackageOriginal) {
result.replaceRandomWithSpecial(3) it.replaceRandomWithSpecial(3)
} else { } else {
result it
} }
} }
@ -102,9 +103,14 @@ class HomeViewModel(
} }
} }
fun onDeletePressed() {}
fun onLinkPressed(link: String) = OpenInappLinkEvent(link).publish() fun onLinkPressed(link: String) = OpenInappLinkEvent(link).publish()
fun onDeletePressed() {}
fun onManagerPressed() = ManagerInstallDialog().publish()
fun onMagiskPressed() = MagiskInstallDialog().publish()
} }
@Suppress("unused") @Suppress("unused")

View File

@ -58,12 +58,15 @@ class MagiskDialog @JvmOverloads constructor(
val isEnabled = KObservableField(true) val isEnabled = KObservableField(true)
var onClickAction: OnDialogButtonClickListener = {} var onClickAction: OnDialogButtonClickListener = {}
var preventDismiss = false
fun clicked() { fun clicked() {
onClickAction(this@MagiskDialog) onClickAction(this@MagiskDialog)
if (!preventDismiss) {
dismiss() dismiss()
} }
} }
}
inner class ButtonBuilder(private val button: Button) { inner class ButtonBuilder(private val button: Button) {
var icon: Int var icon: Int
@ -86,6 +89,11 @@ class MagiskDialog @JvmOverloads constructor(
set(value) { set(value) {
button.isEnabled.value = value button.isEnabled.value = value
} }
var preventDismiss: Boolean
get() = button.preventDismiss
set(value) {
button.preventDismiss = value
}
fun onClick(listener: OnDialogButtonClickListener) { fun onClick(listener: OnDialogButtonClickListener) {
button.onClickAction = listener button.onClickAction = listener

View File

@ -19,6 +19,7 @@
style="@style/Widget.Card" style="@style/Widget.Card"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardElevation="@dimen/margin_generic" app:cardElevation="@dimen/margin_generic"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
@ -26,7 +27,7 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent" app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_max="400dp" app:layout_constraintWidth_max="400dp"
app:layout_constraintWidth_percent=".9"> app:layout_constraintWidth_percent="1">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -55,19 +56,19 @@
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
style="@style/Widget.Icon" style="?styleIconNormal"
gone="@{data.icon == 0}" gone="@{data.icon == 0}"
srcCompat="@{data.icon}" srcCompat="@{data.icon}"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="@dimen/margin_generic" android:layout_marginTop="@dimen/l1"
app:tint="@color/colorSecondary" app:tint="@color/colorSecondary"
tools:src="@drawable/ic_delete" /> tools:src="@drawable/ic_delete" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
style="@style/Widget.Icon.Large" style="?styleImageBig"
gone="@{data.iconRaw == null}" gone="@{data.iconRaw == null}"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="@dimen/margin_generic" android:layout_marginTop="@dimen/l1"
android:src="@{data.iconRaw}" android:src="@{data.iconRaw}"
tools:src="@drawable/ic_delete" /> tools:src="@drawable/ic_delete" />
@ -75,12 +76,12 @@
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/dialog_base_title" android:id="@+id/dialog_base_title"
style="@style/Widget.Text.Title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_generic_half" android:layout_marginTop="@dimen/l1"
android:gravity="center" android:gravity="center"
android:text="@{data.title}" android:text="@{data.title}"
android:textAppearance="?appearanceTextTitleNormal"
app:layout_constraintLeft_toLeftOf="@+id/dialog_base_start" app:layout_constraintLeft_toLeftOf="@+id/dialog_base_start"
app:layout_constraintRight_toRightOf="@+id/dialog_base_end" app:layout_constraintRight_toRightOf="@+id/dialog_base_end"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_icon" app:layout_constraintTop_toBottomOf="@+id/dialog_base_icon"
@ -102,13 +103,13 @@
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/dialog_base_message" android:id="@+id/dialog_base_message"
style="@style/Widget.Text"
gone="@{data.message.length == 0}" gone="@{data.message.length == 0}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_generic_half" android:layout_marginTop="@dimen/l_50"
android:gravity="center" android:gravity="center"
android:text="@{data.message}" android:text="@{data.message}"
android:textAppearance="?appearanceTextBodyNormal"
tools:lines="3" tools:lines="3"
tools:text="@tools:sample/lorem/random" /> tools:text="@tools:sample/lorem/random" />
@ -124,7 +125,7 @@
<Space <Space
android:id="@+id/dialog_base_space" android:id="@+id/dialog_base_space"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/margin_generic" android:layout_height="@dimen/l1"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_scroll" /> app:layout_constraintTop_toBottomOf="@+id/dialog_base_scroll" />
@ -132,13 +133,30 @@
<View <View
android:id="@+id/dialog_base_button_0_divider" android:id="@+id/dialog_base_button_0_divider"
style="@style/Widget.Divider.Horizontal" style="@style/Widget.Divider.Horizontal"
gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length == 0}"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_space" /> app:layout_constraintTop_toBottomOf="@+id/dialog_base_space" />
gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length ==
0}"
<LinearLayout <com.google.android.material.button.MaterialButton
android:id="@+id/dialog_base_button_1" android:id="@+id/dialog_base_button_1"
style="?styleButtonText"
gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length == 0}"
isEnabled="@{data.buttonPositive.isEnabled()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:filterTouchesWhenObscured="true"
android:onClick="@{() -> data.buttonPositive.clicked()}"
android:text="@{data.buttonPositive.title}"
app:icon="@{data.buttonPositive.icon}"
app:iconGravity="textStart"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_0_divider"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<!--<LinearLayout
style="@style/Widget.DialogButton" style="@style/Widget.DialogButton"
gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length == 0}" gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length == 0}"
android:clickable="@{data.buttonPositive.isEnabled()}" android:clickable="@{data.buttonPositive.isEnabled()}"
@ -161,17 +179,35 @@
android:text="@{data.buttonPositive.title}" android:text="@{data.buttonPositive.title}"
tools:text="Button 1" /> tools:text="Button 1" />
</LinearLayout> </LinearLayout>-->
<View <View
android:id="@+id/dialog_base_button_1_divider" android:id="@+id/dialog_base_button_1_divider"
style="@style/Widget.Divider.Horizontal" style="@style/Widget.Divider.Horizontal"
gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length == 0}"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_1" /> app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_1" />
gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length ==
0}"
<LinearLayout <com.google.android.material.button.MaterialButton
android:id="@+id/dialog_base_button_2"
style="?styleButtonText"
gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length == 0}"
isEnabled="@{data.buttonNeutral.isEnabled()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:filterTouchesWhenObscured="true"
android:onClick="@{() -> data.buttonNeutral.clicked()}"
android:text="@{data.buttonNeutral.title}"
app:icon="@{data.buttonNeutral.icon}"
app:iconGravity="textStart"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_1_divider"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<!--<LinearLayout
android:id="@+id/dialog_base_button_2" android:id="@+id/dialog_base_button_2"
style="@style/Widget.DialogButton" style="@style/Widget.DialogButton"
gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length == 0}" gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length == 0}"
@ -195,17 +231,35 @@
android:text="@{data.buttonNeutral.title}" android:text="@{data.buttonNeutral.title}"
tools:text="Button 2" /> tools:text="Button 2" />
</LinearLayout> </LinearLayout>-->
<View <View
android:id="@+id/dialog_base_button_2_divider" android:id="@+id/dialog_base_button_2_divider"
style="@style/Widget.Divider.Horizontal" style="@style/Widget.Divider.Horizontal"
gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length == 0}"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_2" /> app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_2" />
gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length ==
0}"
<LinearLayout <com.google.android.material.button.MaterialButton
android:id="@+id/dialog_base_button_3"
style="?styleButtonText"
gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length == 0}"
isEnabled="@{data.buttonNegative.isEnabled()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:filterTouchesWhenObscured="true"
android:onClick="@{() -> data.buttonNegative.clicked()}"
android:text="@{data.buttonNegative.title}"
app:icon="@{data.buttonNegative.icon}"
app:iconGravity="textStart"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_2_divider"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<!--<LinearLayout
android:id="@+id/dialog_base_button_3" android:id="@+id/dialog_base_button_3"
style="@style/Widget.DialogButton" style="@style/Widget.DialogButton"
gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length == 0}" gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length == 0}"
@ -229,17 +283,34 @@
android:text="@{data.buttonNegative.title}" android:text="@{data.buttonNegative.title}"
tools:text="Button 3" /> tools:text="Button 3" />
</LinearLayout> </LinearLayout>-->
<View <View
android:id="@+id/dialog_base_button_3_divider" android:id="@+id/dialog_base_button_3_divider"
style="@style/Widget.Divider.Horizontal" style="@style/Widget.Divider.Horizontal"
gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_3" /> app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_3" />
gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}"
<LinearLayout <com.google.android.material.button.MaterialButton
android:id="@+id/dialog_base_button_4"
style="?styleButtonText"
gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}"
isEnabled="@{data.buttonIDGAF.isEnabled()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:filterTouchesWhenObscured="true"
android:onClick="@{() -> data.buttonIDGAF.clicked()}"
android:text="@{data.buttonIDGAF.title}"
app:icon="@{data.buttonIDGAF.icon}"
app:iconGravity="textStart"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_button_3_divider"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<!--<LinearLayout
android:id="@+id/dialog_base_button_4" android:id="@+id/dialog_base_button_4"
style="@style/Widget.DialogButton" style="@style/Widget.DialogButton"
gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}" gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}"
@ -263,7 +334,7 @@
android:text="@{data.buttonIDGAF.title}" android:text="@{data.buttonIDGAF.title}"
tools:text="Button 4" /> tools:text="Button 4" />
</LinearLayout> </LinearLayout>-->
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -109,6 +109,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:onClick="@{() -> viewModel.onMagiskPressed()}"
android:text="@string/update" android:text="@string/update"
app:icon="@drawable/ic_update_md2" app:icon="@drawable/ic_update_md2"
app:iconGravity="textEnd" app:iconGravity="textEnd"
@ -123,6 +124,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:onClick="@{() -> viewModel.onMagiskPressed()}"
android:text="@string/install" android:text="@string/install"
app:icon="@drawable/ic_install" app:icon="@drawable/ic_install"
app:iconGravity="textEnd" app:iconGravity="textEnd"
@ -208,6 +210,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:onClick="@{() -> viewModel.onManagerPressed()}"
android:text="@string/update" android:text="@string/update"
app:icon="@drawable/ic_update_md2" app:icon="@drawable/ic_update_md2"
app:iconGravity="textEnd" app:iconGravity="textEnd"
@ -220,6 +223,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:onClick="@{() -> viewModel.onManagerPressed()}"
android:text="@string/install" android:text="@string/install"
app:icon="@drawable/ic_install" app:icon="@drawable/ic_install"
app:iconGravity="textEnd" app:iconGravity="textEnd"