From dec1094a5937f9aa88049ba25c1e70534a7a8585 Mon Sep 17 00:00:00 2001 From: Viktor De Pasquale Date: Fri, 29 Nov 2019 20:07:33 +0100 Subject: [PATCH] Added "input" settings item, that opens custom input dialog Updated order of some items in settings --- .../magisk/redesign/settings/SettingsItems.kt | 67 +++++++++- .../redesign/settings/SettingsViewModel.kt | 64 ++++++++- .../layout/dialog_settings_download_path.xml | 54 ++++++++ .../layout/dialog_settings_update_channel.xml | 46 +++++++ .../main/res/layout/item_settings_blank.xml | 2 + .../main/res/layout/item_settings_input.xml | 124 ++++++++++++++++++ .../res/layout/item_settings_selector.xml | 2 + .../main/res/layout/item_settings_toggle.xml | 3 + app/src/main/res/values/strings.xml | 2 +- 9 files changed, 352 insertions(+), 12 deletions(-) create mode 100644 app/src/main/res/layout/dialog_settings_download_path.xml create mode 100644 app/src/main/res/layout/dialog_settings_update_channel.xml create mode 100644 app/src/main/res/layout/item_settings_input.xml diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsItems.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsItems.kt index 2fceed1d1..688528315 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsItems.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsItems.kt @@ -1,14 +1,22 @@ package com.topjohnwu.magisk.redesign.settings import android.content.Context +import android.os.Environment +import android.view.LayoutInflater +import androidx.databinding.Bindable +import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.R +import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding +import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding import com.topjohnwu.magisk.extensions.get import com.topjohnwu.magisk.extensions.subscribeK +import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.asTransitive import com.topjohnwu.magisk.utils.availableLocales import com.topjohnwu.magisk.utils.currentLocale +import java.io.File // --- Customization @@ -69,16 +77,61 @@ object Restore : SettingsItem.Blank() { fun HideOrRestore() = if (get().packageName == BuildConfig.APPLICATION_ID) Hide else Restore -//todo new dialog -object DownloadPath +object DownloadPath : SettingsItem.Input() { + override var value: String by dataObservable(Config.downloadPath) { Config.downloadPath = it } + override val title = R.string.settings_download_path_title.asTransitive() + override val intermediate: String? + get() = if (Utils.ensureDownloadPath(result) != null) result else null + var result = value + @Bindable get + set(value) { + field = value + notifyChange(BR.result) + notifyChange(BR.path) + } + val path + @Bindable get() = File( + Environment.getExternalStorageDirectory(), + result + ).absolutePath.orEmpty() -//fixme this -object UpdateChannel : SettingsItem.Selector() { - override var value by dataObservable(Config.updateChannel) { Config.updateChannel = it } + override fun getView(context: Context) = DialogSettingsDownloadPathBinding + .inflate(LayoutInflater.from(context)).also { it.data = this }.root } -//fixme new dialog -object UpdateChannelUrl +object UpdateChannel : SettingsItem.Selector() { + override var value by dataObservable(Config.updateChannel) { Config.updateChannel = it } + override val title = R.string.settings_update_channel_title.asTransitive() + + init { + val entries = resources.getStringArray(R.array.update_channel).let { + if (!Utils.isCanary && Config.updateChannel < Config.Value.CANARY_CHANNEL) + it.take(it.size - 2).toTypedArray() else it + } + setValues( + entries, + resources.getStringArray(R.array.value_array) + ) + } +} + +object UpdateChannelUrl : SettingsItem.Input() { + override val title = R.string.settings_update_custom.asTransitive() + override var value: String by dataObservable(Config.customChannelUrl) { + Config.customChannelUrl = it + } + override val intermediate: String? get() = result + + var result = value + @Bindable get + set(value) { + field = value + notifyChange(BR.result) + } + + override fun getView(context: Context) = DialogSettingsUpdateChannelBinding + .inflate(LayoutInflater.from(context)).also { it.data = this }.root +} object UpdateChecker : SettingsItem.Toggle() { override val title = R.string.settings_check_update_title.asTransitive() diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsViewModel.kt index 68fd19f13..ce0282f15 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/settings/SettingsViewModel.kt @@ -1,5 +1,6 @@ package com.topjohnwu.magisk.redesign.settings +import android.content.Context import android.content.res.Resources import android.view.MotionEvent import android.view.View @@ -8,6 +9,7 @@ import androidx.databinding.Bindable import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.topjohnwu.magisk.BR +import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.R import com.topjohnwu.magisk.model.entity.recycler.ObservableItem import com.topjohnwu.magisk.model.events.DieEvent @@ -29,10 +31,11 @@ class SettingsViewModel : CompatViewModel(), SettingsItem.Callback { val itemBinding = itemBindingOf { it.bindExtra(BR.callback, this) } val items = diffListOf( Customization, - Theme, Language, Redesign, + Theme, Language, Redesign, DownloadPath, Manager, - ClearRepoCache, HideOrRestore(), UpdateChecker, SystemlessHosts, Biometrics, + UpdateChannel, UpdateChannelUrl, ClearRepoCache, HideOrRestore(), UpdateChecker, + SystemlessHosts, Biometrics, Magisk, SafeMode, MagiskHide, @@ -44,11 +47,23 @@ class SettingsViewModel : CompatViewModel(), SettingsItem.Callback { override fun onItemPressed(view: View, item: SettingsItem) = when (item) { // use only instances you want, don't declare everything - Theme -> Navigation.theme().publish() - Redesign -> DieEvent().publish() + is Theme -> Navigation.theme().publish() + is Redesign -> DieEvent().publish() + is UpdateChannel -> item.openUrlIfNecessary(view) else -> Unit } + private fun UpdateChannel.openUrlIfNecessary(view: View) { + if (value == Config.Value.CUSTOM_CHANNEL) { + if (UpdateChannelUrl.value.isBlank()) { + UpdateChannelUrl.onPressed(view, this@SettingsViewModel) + } + UpdateChannelUrl.isEnabled = true + } else { + UpdateChannelUrl.isEnabled = false + } + } + } sealed class SettingsItem : ObservableItem() { @@ -60,6 +75,13 @@ sealed class SettingsItem : ObservableItem() { @Bindable open val description: TransitiveText = TransitiveText.empty + var isEnabled = true + @Bindable get + set(value) { + field = value + notifyChange(BR.enabled) + } + protected open val isFullSpan: Boolean = false @CallSuper @@ -127,6 +149,40 @@ sealed class SettingsItem : ObservableItem() { } + abstract class Input : Value(), KoinComponent { + + override val layoutRes = R.layout.item_settings_input + + protected val resources get() = get() + protected abstract val intermediate: String? + + override fun onPressed(view: View, callback: Callback) { + MagiskDialog(view.context) + .applyTitle(title.getText(resources)) + .applyView(getView(view.context)) + .applyButton(MagiskDialog.ButtonType.POSITIVE) { + titleRes = android.R.string.ok + onClick { + intermediate?.let { result -> + preventDismiss = false + value = result + it.dismiss() + super.onPressed(view, callback) + return@onClick + } + preventDismiss = true + } + } + .applyButton(MagiskDialog.ButtonType.NEGATIVE) { + titleRes = android.R.string.cancel + } + .reveal() + } + + abstract fun getView(context: Context): View + + } + abstract class Selector : Value(), KoinComponent { override val layoutRes = R.layout.item_settings_selector diff --git a/app/src/main/res/layout/dialog_settings_download_path.xml b/app/src/main/res/layout/dialog_settings_download_path.xml new file mode 100644 index 000000000..d5782a298 --- /dev/null +++ b/app/src/main/res/layout/dialog_settings_download_path.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_settings_update_channel.xml b/app/src/main/res/layout/dialog_settings_update_channel.xml new file mode 100644 index 000000000..57cb087b4 --- /dev/null +++ b/app/src/main/res/layout/dialog_settings_update_channel.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_settings_blank.xml b/app/src/main/res/layout/item_settings_blank.xml index 25935519c..367f142f1 100644 --- a/app/src/main/res/layout/item_settings_blank.xml +++ b/app/src/main/res/layout/item_settings_blank.xml @@ -18,6 +18,8 @@ diff --git a/app/src/main/res/layout/item_settings_input.xml b/app/src/main/res/layout/item_settings_input.xml new file mode 100644 index 000000000..285c939eb --- /dev/null +++ b/app/src/main/res/layout/item_settings_input.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_settings_selector.xml b/app/src/main/res/layout/item_settings_selector.xml index 346a7d4ec..cb8a91fa3 100644 --- a/app/src/main/res/layout/item_settings_selector.xml +++ b/app/src/main/res/layout/item_settings_selector.xml @@ -19,6 +19,8 @@ style="@style/WidgetFoundation.Card" android:layout_width="match_parent" android:layout_height="wrap_content" + isEnabled="@{item.enabled}" + android:alpha="@{item.enabled ? 1f : .5f}" android:onClick="@{(view) -> item.onPressed(view, callback)}" tools:layout_gravity="center"> diff --git a/app/src/main/res/layout/item_settings_toggle.xml b/app/src/main/res/layout/item_settings_toggle.xml index 7c6a5acd3..ba9b1ebc5 100644 --- a/app/src/main/res/layout/item_settings_toggle.xml +++ b/app/src/main/res/layout/item_settings_toggle.xml @@ -20,6 +20,8 @@ @@ -49,6 +51,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="@dimen/l_25" android:checked="@{item.value}" + isEnabled="@{item.enabled}" android:text="" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d9a127161..c23851d53 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -137,7 +137,7 @@ Update Channel Stable Beta - Custom + Custom Channel Insert a custom URL Magisk Core Only Mode Enable only core features. MagiskSU and MagiskHide will still be enabled, but no modules will be loaded