Commit dec1094a authored by Viktor De Pasquale's avatar Viktor De Pasquale

Added "input" settings item, that opens custom input dialog

Updated order of some items in settings
parent 02e32313
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<Context>().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()
override fun getView(context: Context) = DialogSettingsDownloadPathBinding
.inflate(LayoutInflater.from(context)).also { it.data = this }.root
}
//fixme this
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)
)
}
}
//fixme new dialog
object UpdateChannelUrl
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()
......
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<SettingsItem> { 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<SettingsItem>() {
......@@ -60,6 +75,13 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
@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<SettingsItem>() {
}
abstract class Input : Value<String>(), KoinComponent {
override val layoutRes = R.layout.item_settings_input
protected val resources get() = get<Resources>()
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<Int>(), KoinComponent {
override val layoutRes = R.layout.item_settings_selector
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.topjohnwu.magisk.redesign.settings.DownloadPath" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/margin_generic">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/dialog_custom_download_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{@string/settings_download_path_message(data.path)}"
android:textAppearance="@style/AppearanceFoundation.Caption"
tools:text="@string/settings_download_path_message" />
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_generic"
android:hint="@string/settings_download_path_title"
app:boxStrokeColor="?colorOnSurfaceVariant"
app:errorTextColor="?colorError"
app:hintEnabled="true"
app:hintTextAppearance="@style/AppearanceFoundation.Tiny"
app:hintTextColor="?colorOnSurfaceVariant">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dialog_custom_download_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:text="@={data.result}"
android:textAppearance="@style/AppearanceFoundation.Body"
android:textColor="?colorOnSurface"
tools:text="@tools:sample/lorem" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.topjohnwu.magisk.redesign.settings.UpdateChannelUrl" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/margin_generic">
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_generic"
android:hint="@string/settings_update_custom_msg"
app:boxStrokeColor="?colorOnSurfaceVariant"
app:errorTextColor="?colorError"
app:hintEnabled="true"
app:hintTextAppearance="@style/AppearanceFoundation.Tiny"
app:hintTextColor="?colorOnSurfaceVariant">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/dialog_custom_download_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:text="@={data.result}"
android:textAppearance="@style/AppearanceFoundation.Body"
android:textColor="?colorOnSurface"
tools:text="@tools:sample/lorem" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</layout>
......@@ -18,6 +18,8 @@
<com.google.android.material.card.MaterialCardView
style="@style/WidgetFoundation.Card"
android:layout_width="match_parent"
isEnabled="@{item.enabled}"
android:alpha="@{item.enabled ? 1f : .5f}"
android:layout_height="wrap_content"
android:onClick="@{(view) -> callback.onItemPressed(view, item)}"
tools:layout_gravity="center">
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="item"
type="com.topjohnwu.magisk.redesign.settings.SettingsItem.Input" />
<variable
name="callback"
type="com.topjohnwu.magisk.redesign.settings.SettingsItem.Callback" />
</data>
<com.google.android.material.card.MaterialCardView
style="@style/WidgetFoundation.Card"
isEnabled="@{item.enabled}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="@{item.enabled ? 1f : .5f}"
android:onClick="@{(view) -> item.onPressed(view, callback)}"
tools:layout_gravity="center">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeightSmall"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/input_icon"
style="@style/WidgetFoundation.Icon"
gone="@{item.icon == 0}"
android:background="@null"
android:rotation="180"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@+id/input_divider"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@{item.icon}"
tools:srcCompat="@drawable/ic_fingerprint" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/input_indicator"
style="@style/WidgetFoundation.Icon"
android:background="@null"
android:rotation="180"
app:layout_constraintBottom_toTopOf="@+id/input_divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_back_md2" />
<LinearLayout
android:id="@+id/input_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@{item.icon == 0 ? (int) @dimen/l1 : 0}"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingTop="@dimen/l1"
android:paddingBottom="@dimen/l1"
app:layout_constraintBottom_toTopOf="@+id/input_divider"
app:layout_constraintEnd_toStartOf="@+id/input_indicator"
app:layout_constraintStart_toEndOf="@+id/input_icon"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/input_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="start"
android:text="@{item.title}"
android:textAppearance="@style/AppearanceFoundation.Body"
android:textStyle="bold"
tools:lines="1"
tools:text="@tools:sample/lorem/random" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/input_description"
gone="@{item.description.empty}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{item.description}"
android:textAppearance="@style/AppearanceFoundation.Tiny.Variant"
tools:lines="2"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>
<View
android:id="@+id/input_divider"
gone="@{item.value.empty}"
android:layout_width="match_parent"
android:layout_height="0dp"
android:alpha=".5"
android:background="?colorSurface"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/input_text" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/input_selection"
gone="@{item.value.empty}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/l1"
android:paddingTop="@dimen/l_75"
android:paddingEnd="@dimen/l1"
android:paddingBottom="@dimen/l_75"
android:text="@{item.value}"
android:textAppearance="@style/AppearanceFoundation.Tiny.Variant"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/input_text"
app:layout_constraintTop_toTopOf="@+id/input_divider"
tools:text="@tools:sample/lorem" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</layout>
\ No newline at end of file
......@@ -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">
......
......@@ -20,6 +20,8 @@
<com.google.android.material.card.MaterialCardView
style="@style/WidgetFoundation.Card"
android:layout_width="match_parent"
isEnabled="@{item.enabled}"
android:alpha="@{item.enabled ? 1f : .5f}"
android:layout_height="wrap_content"
android:onClick="@{(view) -> item.onPressed(view, callback)}"
tools:layout_gravity="center">
......@@ -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"
......
......@@ -137,7 +137,7 @@
<string name="settings_update_channel_title">Update Channel</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom">Custom Channel</string>
<string name="settings_update_custom_msg">Insert a custom URL</string>
<string name="settings_core_only_title">Magisk Core Only Mode</string>
<string name="settings_core_only_summary">Enable only core features. MagiskSU and MagiskHide will still be enabled, but no modules will be loaded</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment