From 47545b45b832a913a005cfa229a55cabdf86a7f4 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 21 Jan 2022 00:50:02 -0800 Subject: [PATCH] Clean up MagiskDialog --- .../topjohnwu/magisk/arch/BaseMainActivity.kt | 15 +- .../magisk/events/dialog/DarkThemeDialog.kt | 28 +- .../magisk/events/dialog/DialogEvent.kt | 6 +- .../magisk/events/dialog/EnvFixDialog.kt | 30 +- .../events/dialog/ManagerInstallDialog.kt | 10 +- .../magisk/events/dialog/MarkDownDialog.kt | 2 +- .../events/dialog/ModuleInstallDialog.kt | 24 +- .../events/dialog/SecondSlotWarningDialog.kt | 12 +- .../events/dialog/SuperuserRevokeDialog.kt | 14 +- .../magisk/events/dialog/UninstallDialog.kt | 31 +- .../com/topjohnwu/magisk/ui/MainActivity.kt | 68 ++-- .../magisk/ui/settings/BaseSettingsItem.kt | 32 +- .../com/topjohnwu/magisk/view/MagiskDialog.kt | 292 +++++++----------- .../main/res/layout/dialog_magisk_base.xml | 46 +-- .../main/res/layout/item_list_single_line.xml | 2 +- 15 files changed, 266 insertions(+), 346 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/BaseMainActivity.kt b/app/src/main/java/com/topjohnwu/magisk/arch/BaseMainActivity.kt index c3e972eed..24ed4cf81 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/BaseMainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/BaseMainActivity.kt @@ -75,15 +75,16 @@ abstract class BaseMainActivity private fun showInvalidStateMessage() { runOnUiThread { - MagiskDialog(this) - .applyTitle(R.string.unsupport_nonroot_stub_title) - .applyMessage(R.string.unsupport_nonroot_stub_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = R.string.install + MagiskDialog(this).apply { + setTitle(R.string.unsupport_nonroot_stub_title) + setMessage(R.string.unsupport_nonroot_stub_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = R.string.install onClick { HideAPK.restore(this@BaseMainActivity) } } - .cancellable(false) - .reveal() + setCancelable(false) + show() + } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/DarkThemeDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/DarkThemeDialog.kt index d60ae584d..24fd1e356 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/DarkThemeDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/DarkThemeDialog.kt @@ -1,8 +1,6 @@ package com.topjohnwu.magisk.events.dialog import android.app.Activity -import android.content.Context -import android.content.ContextWrapper import androidx.appcompat.app.AppCompatDelegate import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Config @@ -11,31 +9,25 @@ import com.topjohnwu.magisk.view.MagiskDialog class DarkThemeDialog : DialogEvent() { override fun build(dialog: MagiskDialog) { - val activity = dialog.context.unwrap() - dialog.applyTitle(R.string.settings_dark_mode_title) - .applyMessage(R.string.settings_dark_mode_message) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = R.string.settings_dark_mode_light + val activity = dialog.ownerActivity!! + dialog.apply { + setTitle(R.string.settings_dark_mode_title) + setMessage(R.string.settings_dark_mode_message) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = R.string.settings_dark_mode_light icon = R.drawable.ic_day onClick { selectTheme(AppCompatDelegate.MODE_NIGHT_NO, activity) } } - .applyButton(MagiskDialog.ButtonType.NEUTRAL) { - titleRes = R.string.settings_dark_mode_system + setButton(MagiskDialog.ButtonType.NEUTRAL) { + text = R.string.settings_dark_mode_system icon = R.drawable.ic_day_night onClick { selectTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, activity) } } - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = R.string.settings_dark_mode_dark + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = R.string.settings_dark_mode_dark icon = R.drawable.ic_night onClick { selectTheme(AppCompatDelegate.MODE_NIGHT_YES, activity) } } - } - - private fun Context.unwrap(): Activity { - return when(this) { - is Activity -> this - is ContextWrapper -> baseContext.unwrap() - else -> error("Cannot happen") } } diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt index 700326abb..e7b5886d5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt @@ -7,12 +7,10 @@ import com.topjohnwu.magisk.view.MagiskDialog abstract class DialogEvent : ViewEvent(), ActivityExecutor { - protected lateinit var dialog: MagiskDialog - override fun invoke(activity: BaseUIActivity<*, *>) { - dialog = MagiskDialog(activity) + MagiskDialog(activity) .apply { setOwnerActivity(activity) } - .apply(this::build).reveal() + .apply(this::build).show() } abstract fun build(dialog: MagiskDialog) diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/EnvFixDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/EnvFixDialog.kt index b75cfbb42..56294594e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/EnvFixDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/EnvFixDialog.kt @@ -13,16 +13,19 @@ import kotlinx.coroutines.launch class EnvFixDialog(private val vm: HomeViewModel) : DialogEvent() { override fun build(dialog: MagiskDialog) { - dialog.applyTitle(R.string.env_fix_title) - .applyMessage(R.string.env_fix_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = android.R.string.ok - preventDismiss = true + dialog.apply { + setTitle(R.string.env_fix_title) + setMessage(R.string.env_fix_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = android.R.string.ok + doNotDismiss = true onClick { - dialog.applyTitle(R.string.setup_title) - .applyMessage(R.string.setup_msg) - .resetButtons() - .cancellable(false) + dialog.apply { + setTitle(R.string.setup_title) + setMessage(R.string.setup_msg) + resetButtons() + setCancelable(false) + } (dialog.ownerActivity as BaseActivity).lifecycleScope.launch { MagiskInstaller.FixEnv { dialog.dismiss() @@ -30,14 +33,15 @@ class EnvFixDialog(private val vm: HomeViewModel) : DialogEvent() { } } } - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = android.R.string.cancel + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = android.R.string.cancel } + } if (Info.env.versionCode != BuildConfig.VERSION_CODE || Info.env.versionString != BuildConfig.VERSION_NAME) { - dialog.applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = android.R.string.ok + dialog.setButton(MagiskDialog.ButtonType.POSITIVE) { + text = android.R.string.ok onClick { vm.onMagiskPressed() dialog.dismiss() diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt index f1b9e1bef..f220d3875 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt @@ -25,14 +25,14 @@ class ManagerInstallDialog : MarkDownDialog() { override fun build(dialog: MagiskDialog) { super.build(dialog) - with(dialog) { + dialog.apply { setCancelable(true) - applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = R.string.install + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = R.string.install onClick { DownloadService.start(context, Subject.Manager()) } } - applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = android.R.string.cancel + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = android.R.string.cancel } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt index 56da30642..1453ae60a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt @@ -22,7 +22,7 @@ abstract class MarkDownDialog : DialogEvent() { override fun build(dialog: MagiskDialog) { with(dialog) { val view = LayoutInflater.from(context).inflate(R.layout.markdown_window_md2, null) - applyView(view) + setView(view) (ownerActivity as BaseActivity).lifecycleScope.launch { val tv = view.findViewById(R.id.md_txt) withContext(Dispatchers.IO) { diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt index 2b70df116..03501dd12 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt @@ -11,7 +11,7 @@ import com.topjohnwu.magisk.view.MagiskDialog class ModuleInstallDialog(private val item: OnlineModule) : DialogEvent() { override fun build(dialog: MagiskDialog) { - with(dialog) { + dialog.apply { fun download(install: Boolean) { val action = if (install) Action.Flash else Action.Download @@ -19,24 +19,22 @@ class ModuleInstallDialog(private val item: OnlineModule) : DialogEvent() { DownloadService.start(context, subject) } - applyTitle(context.getString(R.string.repo_install_title, item.name)) - .applyMessage(context.getString(R.string.repo_install_msg, item.downloadFilename)) - .cancellable(true) - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = R.string.download - icon = R.drawable.ic_download_md2 - onClick { download(false) } - } + setTitle(context.getString(R.string.repo_install_title, item.name)) + setMessage(context.getString(R.string.repo_install_msg, item.downloadFilename)) + setCancelable(true) + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = R.string.download + icon = R.drawable.ic_download_md2 + onClick { download(false) } + } if (Info.env.isActive) { - applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = R.string.install + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = R.string.install icon = R.drawable.ic_install onClick { download(true) } } } - - reveal() } } diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/SecondSlotWarningDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/SecondSlotWarningDialog.kt index 86874b3d3..7e4245d8e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/SecondSlotWarningDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/SecondSlotWarningDialog.kt @@ -6,11 +6,13 @@ import com.topjohnwu.magisk.view.MagiskDialog class SecondSlotWarningDialog : DialogEvent() { override fun build(dialog: MagiskDialog) { - dialog.applyTitle(android.R.string.dialog_alert_title) - .applyMessage(R.string.install_inactive_slot_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = android.R.string.ok + dialog.apply { + setTitle(android.R.string.dialog_alert_title) + setMessage(R.string.install_inactive_slot_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = android.R.string.ok } - .cancellable(true) + setCancelable(true) + } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/SuperuserRevokeDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/SuperuserRevokeDialog.kt index 32c15ad2f..125fb7422 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/SuperuserRevokeDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/SuperuserRevokeDialog.kt @@ -10,15 +10,17 @@ class SuperuserRevokeDialog( private val callbacks = Builder().apply(builder) override fun build(dialog: MagiskDialog) { - dialog.applyTitle(R.string.su_revoke_title) - .applyMessage(R.string.su_revoke_msg, callbacks.appName) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = android.R.string.ok + dialog.apply { + setTitle(R.string.su_revoke_title) + setMessage(R.string.su_revoke_msg, callbacks.appName) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = android.R.string.ok onClick { callbacks.listenerOnSuccess() } } - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = android.R.string.cancel + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = android.R.string.cancel } + } } inner class Builder internal constructor() { diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/UninstallDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/UninstallDialog.kt index 0f6957033..99a8848f1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/UninstallDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/UninstallDialog.kt @@ -1,6 +1,7 @@ package com.topjohnwu.magisk.events.dialog import android.app.ProgressDialog +import android.content.Context import android.widget.Toast import com.topjohnwu.magisk.R import com.topjohnwu.magisk.arch.BaseUIActivity @@ -12,22 +13,24 @@ import com.topjohnwu.superuser.Shell class UninstallDialog : DialogEvent() { override fun build(dialog: MagiskDialog) { - dialog.applyTitle(R.string.uninstall_magisk_title) - .applyMessage(R.string.uninstall_magisk_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = R.string.restore_img - onClick { restore() } + dialog.apply { + setTitle(R.string.uninstall_magisk_title) + setMessage(R.string.uninstall_magisk_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = R.string.restore_img + onClick { restore(dialog.context) } } - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = R.string.complete_uninstall - onClick { completeUninstall() } + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = R.string.complete_uninstall + onClick { completeUninstall(dialog) } } + } } @Suppress("DEPRECATION") - private fun restore() { - val dialog = ProgressDialog(dialog.context).apply { - setMessage(dialog.context.getString(R.string.restore_img_msg)) + private fun restore(context: Context) { + val dialog = ProgressDialog(context).apply { + setMessage(context.getString(R.string.restore_img_msg)) show() } @@ -41,9 +44,9 @@ class UninstallDialog : DialogEvent() { } } - private fun completeUninstall() { - (dialog.ownerActivity as? BaseUIActivity<*, *>) - ?.navigation?.navigate(FlashFragment.uninstall()) + private fun completeUninstall(dialog: MagiskDialog) { + (dialog.ownerActivity as BaseUIActivity<*, *>) + .navigation?.navigate(FlashFragment.uninstall()) } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt index 44732bed3..2bd946467 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt @@ -146,42 +146,42 @@ class MainActivity : BaseMainActivity() { private fun showUnsupportedMessage() { if (Info.env.isUnsupported) { - MagiskDialog(this) - .applyTitle(R.string.unsupport_magisk_title) - .applyMessage(R.string.unsupport_magisk_msg, Const.Version.MIN_VERSION) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } - .cancellable(false) - .reveal() + MagiskDialog(this).apply { + setTitle(R.string.unsupport_magisk_title) + setMessage(R.string.unsupport_magisk_msg, Const.Version.MIN_VERSION) + setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok } + setCancelable(false) + }.show() } if (!Info.isEmulator && Info.env.isActive && System.getenv("PATH") ?.split(':') ?.filterNot { File("$it/magisk").exists() } ?.any { File("$it/su").exists() } == true) { - MagiskDialog(this) - .applyTitle(R.string.unsupport_general_title) - .applyMessage(R.string.unsupport_other_su_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } - .cancellable(false) - .reveal() + MagiskDialog(this).apply { + setTitle(R.string.unsupport_general_title) + setMessage(R.string.unsupport_other_su_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok } + setCancelable(false) + }.show() } if (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) { - MagiskDialog(this) - .applyTitle(R.string.unsupport_general_title) - .applyMessage(R.string.unsupport_system_app_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } - .cancellable(false) - .reveal() + MagiskDialog(this).apply { + setTitle(R.string.unsupport_general_title) + setMessage(R.string.unsupport_system_app_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok } + setCancelable(false) + }.show() } if (applicationInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE != 0) { - MagiskDialog(this) - .applyTitle(R.string.unsupport_general_title) - .applyMessage(R.string.unsupport_external_storage_msg) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } - .cancellable(false) - .reveal() + MagiskDialog(this).apply { + setTitle(R.string.unsupport_general_title) + setMessage(R.string.unsupport_external_storage_msg) + setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok } + setCancelable(false) + }.show() } } @@ -190,18 +190,20 @@ class MainActivity : BaseMainActivity() { ShortcutManagerCompat.isRequestPinShortcutSupported(this)) { // Ask and show dialog Config.askedHome = true - MagiskDialog(this) - .applyTitle(R.string.add_shortcut_title) - .applyMessage(R.string.add_shortcut_msg) - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = android.R.string.cancel - }.applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = android.R.string.ok + MagiskDialog(this).apply { + setTitle(R.string.add_shortcut_title) + setMessage(R.string.add_shortcut_msg) + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = android.R.string.cancel + } + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = android.R.string.ok onClick { Shortcuts.addHomeIcon(this@MainActivity) } - }.cancellable(true) - .reveal() + } + setCancelable(true) + }.show() } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt index 812aeac49..d01406a45 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt @@ -110,25 +110,25 @@ sealed class BaseSettingsItem : ObservableRvItem() { protected abstract val inputResult: String? override fun onPressed(view: View) { - MagiskDialog(view.context) - .applyTitle(title.getText(view.resources)) - .applyView(getView(view.context)) - .applyButton(MagiskDialog.ButtonType.POSITIVE) { - titleRes = android.R.string.ok + MagiskDialog(view.context).apply { + setTitle(title.getText(view.resources)) + setView(getView(view.context)) + setButton(MagiskDialog.ButtonType.POSITIVE) { + text = android.R.string.ok onClick { inputResult?.let { result -> - preventDismiss = false + doNotDismiss = false value = result it.dismiss() return@onClick } - preventDismiss = true + doNotDismiss = true } } - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = android.R.string.cancel + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = android.R.string.cancel } - .reveal() + }.show() } abstract fun getView(context: Context): View @@ -151,15 +151,15 @@ sealed class BaseSettingsItem : ObservableRvItem() { runCatching { getStringArray(id) }.getOrDefault(emptyArray()) override fun onPressed(view: View) { - MagiskDialog(view.context) - .applyTitle(title.getText(view.resources)) - .applyButton(MagiskDialog.ButtonType.NEGATIVE) { - titleRes = android.R.string.cancel + MagiskDialog(view.context).apply { + setTitle(title.getText(view.resources)) + setButton(MagiskDialog.ButtonType.NEGATIVE) { + text = android.R.string.cancel } - .applyAdapter(entries(view.resources)) { + setListItems(entries(view.resources)) { value = it } - .reveal() + }.show() } } diff --git a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt index e42093fd6..e92eac551 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt @@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatDialog import androidx.appcompat.content.res.AppCompatResources import androidx.databinding.Bindable import androidx.databinding.PropertyChangeRegistry -import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.color.MaterialColors @@ -23,9 +22,12 @@ import com.google.android.material.shape.MaterialShapeDrawable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.databinding.* +import com.topjohnwu.magisk.view.MagiskDialog.DialogClickListener import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters import me.tatarka.bindingcollectionadapter2.ItemBinding +typealias DialogButtonClickListener = (DialogInterface) -> Unit + class MagiskDialog( context: Context, theme: Int = 0 ) : AppCompatDialog(context, theme) { @@ -39,6 +41,82 @@ class MagiskDialog( setCancelable(true) } + inner class Data : ObservableHost { + override var callbacks: PropertyChangeRegistry? = null + + @get:Bindable + var icon: Drawable? = null + set(value) = set(value, field, { field = it }, BR.icon) + + @get:Bindable + var title: CharSequence = "" + set(value) = set(value, field, { field = it }, BR.title) + + @get:Bindable + var message: CharSequence = "" + set(value) = set(value, field, { field = it }, BR.message) + + val buttonPositive = ButtonViewModel() + val buttonNeutral = ButtonViewModel() + val buttonNegative = ButtonViewModel() + } + + enum class ButtonType { + POSITIVE, NEUTRAL, NEGATIVE + } + + interface Button { + var icon: Int + var text: Any + var isEnabled: Boolean + var doNotDismiss: Boolean + + fun onClick(listener: DialogButtonClickListener) + } + + inner class ButtonViewModel : Button, ObservableHost { + override var callbacks: PropertyChangeRegistry? = null + + @get:Bindable + override var icon = 0 + set(value) = set(value, field, { field = it }, BR.icon, BR.gone) + + @get:Bindable + var message: String = "" + set(value) = set(value, field, { field = it }, BR.message, BR.gone) + + override var text: Any + get() = message + set(value) { + message = when (value) { + is Int -> context.getText(value) + else -> value + }.toString() + } + + @get:Bindable + val gone get() = icon == 0 && message.isEmpty() + + @get:Bindable + override var isEnabled = true + set(value) = set(value, field, { field = it }, BR.enabled) + + override var doNotDismiss = false + + private var onClickAction: DialogButtonClickListener = {} + + override fun onClick(listener: DialogButtonClickListener) { + onClickAction = listener + } + + fun clicked() { + onClickAction(this@MagiskDialog) + if (!doNotDismiss) { + dismiss() + } + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) super.setContentView(binding.root) @@ -58,129 +136,29 @@ class MagiskDialog( } } - inner class Data : ObservableHost { - override var callbacks: PropertyChangeRegistry? = null + override fun setTitle(@StringRes titleId: Int) { data.title = context.getString(titleId) } - @get:Bindable - var icon: Drawable? = null - set(value) = set(value, field, { field = it }, BR.icon) + override fun setTitle(title: CharSequence?) { data.title = title ?: "" } - @get:Bindable - var title: CharSequence = "" - set(value) = set(value, field, { field = it }, BR.title) - - @get:Bindable - var message: CharSequence = "" - set(value) = set(value, field, { field = it }, BR.message) - - val buttonPositive = Button() - val buttonNeutral = Button() - val buttonNegative = Button() - val buttonIDGAF = Button() + fun setMessage(@StringRes msgId: Int, vararg args: Any) { + data.message = context.getString(msgId, *args) } - enum class ButtonType { - POSITIVE, NEUTRAL, NEGATIVE, IDGAF + fun setMessage(message: CharSequence) { data.message = message } + + fun setIcon(@DrawableRes drawableRes: Int) { + data.icon = AppCompatResources.getDrawable(context, drawableRes) } - inner class Button : ObservableHost { - override var callbacks: PropertyChangeRegistry? = null + fun setIcon(drawable: Drawable) { data.icon = drawable } - @get:Bindable - var icon = 0 - set(value) = set(value, field, { field = it }, BR.icon) - - @get:Bindable - var title: CharSequence = "" - set(value) = set(value, field, { field = it }, BR.title) - - @get:Bindable - var isEnabled = true - set(value) = set(value, field, { field = it }, BR.enabled) - - var onClickAction: OnDialogButtonClickListener = {} - var preventDismiss = false - - fun clicked() { - //we might not want the click to dismiss the button to begin with - var prevention = preventDismiss - - onClickAction(this@MagiskDialog) - - //in case we don't want the dialog to close after clicking the button - //ie. the input is incorrect ... - //otherwise we disregard the request, bcs it just might reset the button in the new - //instance - if (preventDismiss) { - prevention = preventDismiss - } - - if (!prevention) { - dismiss() - } - } - } - - inner class ButtonBuilder(private val button: Button) { - var icon: Int - get() = button.icon - set(value) { - button.icon = value - } - var title: CharSequence - get() = button.title - set(value) { - button.title = value - } - var titleRes: Int - get() = 0 - set(value) { - button.title = context.getString(value) - } - var isEnabled: Boolean - get() = button.isEnabled - set(value) { - button.isEnabled = value - } - var preventDismiss: Boolean - get() = button.preventDismiss - set(value) { - button.preventDismiss = value - } - - fun onClick(listener: OnDialogButtonClickListener) { - button.onClickAction = listener - } - } - - fun applyTitle(@StringRes stringRes: Int) = - apply { data.title = context.getString(stringRes) } - - fun applyTitle(title: CharSequence) = - apply { data.title = title } - - fun applyMessage(@StringRes stringRes: Int, vararg args: Any) = - apply { data.message = context.getString(stringRes, *args) } - - fun applyMessage(message: CharSequence) = - apply { data.message = message } - - fun applyIcon(@DrawableRes drawableRes: Int) = - apply { - data.icon = AppCompatResources.getDrawable(context, drawableRes) - } - - fun applyIcon(drawable: Drawable) = - apply { data.icon = drawable } - - fun applyButton(buttonType: ButtonType, builder: ButtonBuilder.() -> Unit) = apply { + fun setButton(buttonType: ButtonType, builder: Button.() -> Unit) { val button = when (buttonType) { ButtonType.POSITIVE -> data.buttonPositive ButtonType.NEUTRAL -> data.buttonNeutral ButtonType.NEGATIVE -> data.buttonNegative - ButtonType.IDGAF -> data.buttonIDGAF } - ButtonBuilder(button).apply(builder) + button.apply(builder) } class DialogItem( @@ -190,43 +168,32 @@ class MagiskDialog( override val layoutRes = R.layout.item_list_single_line } - interface ActualOnDialogClickListener { + fun interface DialogClickListener { fun onClick(position: Int) } - fun applyAdapter( + fun setListItems( list: Array, - listener: OnDialogClickListener - ) = applyView( + listener: DialogClickListener + ) = setView( RecyclerView(context).also { it.isNestedScrollingEnabled = false it.layoutManager = LinearLayoutManager(context) - val actualListener = object : ActualOnDialogClickListener { - override fun onClick(position: Int) { - listener(position) - dismiss() - } - } val items = list.mapIndexed { i, cs -> DialogItem(cs, i) } - val binding = itemBindingOf { it.bindExtra(BR.listener, actualListener) } - .let { ItemBinding.of(it) } + val binding = itemBindingOf { item -> + item.bindExtra(BR.listener, DialogClickListener { pos -> + listener.onClick(pos) + dismiss() + }) + }.let { b -> ItemBinding.of(b) } BindingRecyclerViewAdapters.setAdapter(it, binding, items, null, null, null, null) } ) - fun cancellable(isCancellable: Boolean) = apply { - setCancelable(isCancellable) - } - - fun applyView( - binding: Binding, - body: Binding.() -> Unit = {} - ) = applyView(binding.root).also { binding.apply(body) } - - fun applyView(view: View) = apply { - resetView() + fun setView(view: View) { + binding.dialogBaseContainer.removeAllViews() binding.dialogBaseContainer.addView( view, ViewGroup.LayoutParams.MATCH_PARENT, @@ -234,57 +201,24 @@ class MagiskDialog( ) } - fun onCancel(callback: OnDialogButtonClickListener) = - apply { setOnCancelListener(callback) } - - fun onDismiss(callback: OnDialogButtonClickListener) = - apply { setOnDismissListener(callback) } - - fun onShow(callback: OnDialogButtonClickListener) = - apply { setOnShowListener(callback) } - - fun reveal() = apply { super.show() } - - // --- - - fun resetView() = apply { - binding.dialogBaseContainer.removeAllViews() - } - - fun resetTitle() = applyTitle("") - fun resetMessage() = applyMessage("") - fun resetIcon() = apply { data.icon = null } - - fun resetButtons() = apply { + fun resetButtons() { ButtonType.values().forEach { - applyButton(it) { - title = "" + setButton(it) { + text = "" icon = 0 isEnabled = true - preventDismiss = false + doNotDismiss = false onClick {} } } } - fun reset() = resetTitle() - .resetMessage() - .resetView() - .resetIcon() - .resetButtons() + // Prevent calling setContentView - //region Deprecated Members - @Deprecated("Use applyTitle instead", ReplaceWith("applyTitle")) - override fun setTitle(title: CharSequence?) = Unit - - @Deprecated("Use applyTitle instead", ReplaceWith("applyTitle")) - override fun setTitle(titleId: Int) = Unit - - @Deprecated("Use reveal()", ReplaceWith("reveal()")) - override fun show() { - } - //endregion + @Deprecated("Please use setView(view)", level = DeprecationLevel.ERROR) + override fun setContentView(layoutResID: Int) {} + @Deprecated("Please use setView(view)", level = DeprecationLevel.ERROR) + override fun setContentView(view: View) {} + @Deprecated("Please use setView(view)", level = DeprecationLevel.ERROR) + override fun setContentView(view: View, params: ViewGroup.LayoutParams?) {} } - -typealias OnDialogButtonClickListener = (DialogInterface) -> Unit -typealias OnDialogClickListener = (position: Int) -> Unit diff --git a/app/src/main/res/layout/dialog_magisk_base.xml b/app/src/main/res/layout/dialog_magisk_base.xml index 219d13bd1..e88b109b0 100644 --- a/app/src/main/res/layout/dialog_magisk_base.xml +++ b/app/src/main/res/layout/dialog_magisk_base.xml @@ -116,34 +116,18 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> -