diff --git a/app/src/main/java/io/heckel/ntfy/app/Application.kt b/app/src/main/java/io/heckel/ntfy/app/Application.kt index f6cb30ce..d07c7cbe 100644 --- a/app/src/main/java/io/heckel/ntfy/app/Application.kt +++ b/app/src/main/java/io/heckel/ntfy/app/Application.kt @@ -1,6 +1,7 @@ package io.heckel.ntfy.app import android.app.Application +import com.google.android.material.color.DynamicColors import io.heckel.ntfy.db.Repository import io.heckel.ntfy.util.Log @@ -12,4 +13,9 @@ class Application : Application() { } repository } + + override fun onCreate() { + DynamicColors.applyToActivitiesIfAvailable(this) + super.onCreate() + } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt index 8e56bab9..256108a1 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt @@ -11,6 +11,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.* import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import io.heckel.ntfy.BuildConfig @@ -144,7 +145,7 @@ class AddFragment : DialogFragment() { loginPasswordText.addTextChangedListener(loginTextWatcher) // Build dialog - val dialog = AlertDialog.Builder(activity) + val dialog = MaterialAlertDialogBuilder(requireContext()) .setView(view) .setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ -> // This will be overridden below to avoid closing the dialog immediately diff --git a/app/src/main/java/io/heckel/ntfy/ui/BasePreferenceFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/BasePreferenceFragment.kt new file mode 100644 index 00000000..14ab8167 --- /dev/null +++ b/app/src/main/java/io/heckel/ntfy/ui/BasePreferenceFragment.kt @@ -0,0 +1,50 @@ +package io.heckel.ntfy.ui + +import androidx.preference.EditTextPreference +import androidx.preference.ListPreference +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.textfield.TextInputEditText +import io.heckel.ntfy.R + +abstract class BasePreferenceFragment : PreferenceFragmentCompat() { + /** + * Show [ListPreference] and [EditTextPreference] dialog by [MaterialAlertDialogBuilder] + */ + override fun onDisplayPreferenceDialog(preference: Preference) { + when (preference) { + is ListPreference -> { + val prefIndex = preference.entryValues.indexOf(preference.value) + MaterialAlertDialogBuilder(requireContext()) + .setTitle(preference.title) + .setSingleChoiceItems(preference.entries, prefIndex) { dialog, index -> + val newValue = preference.entryValues[index].toString() + if (preference.callChangeListener(newValue)) { + preference.value = newValue + } + dialog.dismiss() + } + .setNegativeButton(android.R.string.cancel, null) + .show() + } + is EditTextPreference -> { + val view = layoutInflater.inflate(R.layout.dialog_edit_text_preference, null) + val editText = view.findViewById(R.id.editText) + editText.setText(preference.text.toString()) + MaterialAlertDialogBuilder(requireContext()) + .setTitle(preference.title) + .setView(view) + .setPositiveButton(android.R.string.ok) { _, _ -> + val newValue = editText.text.toString() + if (preference.callChangeListener(newValue)) { + preference.text = newValue + } + } + .setNegativeButton(android.R.string.cancel, null) + .show() + } + else -> super.onDisplayPreferenceDialog(preference) + } + } +} diff --git a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt index ada14cbf..be5b499e 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/Colors.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/Colors.kt @@ -1,48 +1,45 @@ package io.heckel.ntfy.ui import android.content.Context +import android.graphics.Color import androidx.core.content.ContextCompat +import com.google.android.material.color.MaterialColors +import com.google.android.material.elevation.SurfaceColors import io.heckel.ntfy.R import io.heckel.ntfy.util.isDarkThemeOn class Colors { companion object { - const val refreshProgressIndicator = R.color.teal - fun notificationIcon(context: Context): Int { return if (isDarkThemeOn(context)) R.color.teal_light else R.color.teal } fun itemSelectedBackground(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_800b else R.color.gray_400 - } - - fun cardBackground(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_800b else R.color.white - } - - fun cardSelectedBackground(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_700b else R.color.gray_500 + return SurfaceColors.getColorForElevation(context, 10f) } fun cardBackgroundColor(context: Context): Int { - return ContextCompat.getColor(context, cardBackground(context)) + return SurfaceColors.getColorForElevation(context, 5f) } fun cardSelectedBackgroundColor(context: Context): Int { - return ContextCompat.getColor(context, cardSelectedBackground(context)) + return SurfaceColors.getColorForElevation(context, 20f) } fun statusBarNormal(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_900 else R.color.teal + return MaterialColors.getColor(context, R.attr.backgroundColor, Color.BLACK) } fun statusBarActionMode(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.black_900 else R.color.teal_dark + return MaterialColors.getColor(context, R.attr.backgroundColor, Color.BLACK) } fun dangerText(context: Context): Int { - return if (isDarkThemeOn(context)) R.color.red_light else R.color.red_dark + return MaterialColors.getColor(context, R.attr.colorError, Color.RED) + } + + fun swipeToRefreshColor(context: Context): Int { + return MaterialColors.getColor(context, R.attr.colorPrimary, Color.GREEN) } } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index 851f43ac..afda3e92 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R @@ -190,7 +191,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra // Swipe to refresh mainListContainer = findViewById(R.id.detail_notification_list_container) mainListContainer.setOnRefreshListener { refresh() } - mainListContainer.setColorSchemeResources(Colors.refreshProgressIndicator) + mainListContainer.setColorSchemeColors(Colors.swipeToRefreshColor(this)) // Update main list based on viewModel (& its datasource/livedata) val noEntriesText: View = findViewById(R.id.detail_no_notifications) @@ -568,8 +569,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private fun onClearClick() { Log.d(TAG, "Clearing all notifications for ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.detail_clear_dialog_message) .setPositiveButton(R.string.detail_clear_dialog_permanently_delete) { _, _ -> lifecycleScope.launch(Dispatchers.IO) { @@ -600,8 +600,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private fun onDeleteClick() { Log.d(TAG, "Deleting subscription ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.detail_delete_dialog_message) .setPositiveButton(R.string.detail_delete_dialog_permanently_delete) { _, _ -> Log.d(TAG, "Deleting subscription with subscription ID $subscriptionId (topic: $subscriptionTopic)") @@ -716,8 +715,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra private fun onMultiDeleteClick() { Log.d(TAG, "Showing multi-delete dialog for selected items") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.detail_action_mode_delete_dialog_message) .setPositiveButton(R.string.detail_action_mode_delete_dialog_permanently_delete) { _, _ -> adapter.selected.map { notificationId -> viewModel.markAsDeleted(notificationId) } @@ -744,9 +742,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra adapter.toggleSelection(notification.id) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarNormal(this), Colors.statusBarActionMode(this)) } private fun finishActionMode() { @@ -760,9 +756,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra adapter.notifyItemRangeChanged(0, adapter.currentList.size) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarActionMode(this), Colors.statusBarNormal(this)) } companion object { diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt index ccc0191d..d2e76a84 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -137,7 +137,7 @@ class DetailSettingsActivity : AppCompatActivity() { private fun loadInstantPref() { val appBaseUrl = getString(R.string.app_base_url) val prefId = context?.getString(R.string.detail_settings_notifications_instant_key) ?: return - val pref: SwitchPreference? = findPreference(prefId) + val pref: SwitchPreferenceCompat? = findPreference(prefId) pref?.isVisible = BuildConfig.FIREBASE_AVAILABLE && subscription.baseUrl == appBaseUrl pref?.isChecked = subscription.instant pref?.preferenceDataStore = object : PreferenceDataStore() { @@ -148,7 +148,7 @@ class DetailSettingsActivity : AppCompatActivity() { return subscription.instant } } - pref?.summaryProvider = Preference.SummaryProvider { preference -> + pref?.summaryProvider = Preference.SummaryProvider { preference -> if (preference.isChecked) { getString(R.string.detail_settings_notifications_instant_summary_on) } else { @@ -159,7 +159,7 @@ class DetailSettingsActivity : AppCompatActivity() { private fun loadDedicatedChannelsPrefs() { val prefId = context?.getString(R.string.detail_settings_notifications_dedicated_channels_key) ?: return - val pref: SwitchPreference? = findPreference(prefId) + val pref: SwitchPreferenceCompat? = findPreference(prefId) pref?.isVisible = true pref?.isChecked = subscription.dedicatedChannels pref?.preferenceDataStore = object : PreferenceDataStore() { @@ -176,7 +176,7 @@ class DetailSettingsActivity : AppCompatActivity() { return subscription.dedicatedChannels } } - pref?.summaryProvider = Preference.SummaryProvider { preference -> + pref?.summaryProvider = Preference.SummaryProvider { preference -> if (preference.isChecked) { getString(R.string.detail_settings_notifications_dedicated_channels_summary_on) } else { diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index e131f32c..4daec6b7 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -28,6 +28,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.work.* +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.floatingactionbutton.FloatingActionButton import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R @@ -96,7 +97,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc // Swipe to refresh mainListContainer = findViewById(R.id.main_subscriptions_list_container) mainListContainer.setOnRefreshListener { refreshAllSubscriptions() } - mainListContainer.setColorSchemeResources(Colors.refreshProgressIndicator) + mainListContainer.setColorSchemeColors(Colors.swipeToRefreshColor(this)) // Update main list based on viewModel (& its datasource/livedata) val noEntries: View = findViewById(R.id.main_no_subscriptions) @@ -608,8 +609,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc private fun onMultiDeleteClick() { Log.d(DetailActivity.TAG, "Showing multi-delete dialog for selected items") - val builder = AlertDialog.Builder(this) - val dialog = builder + val dialog = MaterialAlertDialogBuilder(this) .setMessage(R.string.main_action_mode_delete_dialog_message) .setPositiveButton(R.string.main_action_mode_delete_dialog_permanently_delete) { _, _ -> adapter.selected.map { subscriptionId -> viewModel.remove(this, subscriptionId) } @@ -648,9 +648,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc }) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarNormal(this), Colors.statusBarActionMode(this)) } private fun finishActionMode() { @@ -677,9 +675,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc }) // Fade status bar color - val fromColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this)) - val toColor = ContextCompat.getColor(this, Colors.statusBarNormal(this)) - fadeStatusBarColor(window, fromColor, toColor) + fadeStatusBarColor(window, Colors.statusBarActionMode(this), Colors.statusBarNormal(this)) } private fun redrawList() { diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt index ed0d2bd0..4aa7e5b6 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainAdapter.kt @@ -115,7 +115,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs itemView.setOnClickListener { onClick(subscription) } itemView.setOnLongClickListener { onLongClick(subscription); true } if (selected.contains(subscription.id)) { - itemView.setBackgroundResource(Colors.itemSelectedBackground(context)) + itemView.setBackgroundColor(Colors.itemSelectedBackground(context)) } else { itemView.setBackgroundColor(Color.TRANSPARENT) } diff --git a/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt index 2d84879c..920d1bd4 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/NotificationFragment.kt @@ -7,6 +7,7 @@ import android.os.Bundle import android.widget.RadioButton import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope +import com.google.android.material.dialog.MaterialAlertDialogBuilder import io.heckel.ntfy.R import io.heckel.ntfy.db.Repository import kotlinx.coroutines.Dispatchers @@ -74,7 +75,7 @@ class NotificationFragment : DialogFragment() { muteForeverButton = view.findViewById(R.id.notification_dialog_forever) muteForeverButton.setOnClickListener{ onClick(Repository.MUTED_UNTIL_FOREVER) } - return AlertDialog.Builder(activity) + return MaterialAlertDialogBuilder(requireContext()) .setView(view) .create() } diff --git a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt index f4ef5d86..1a9ab9ec 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt @@ -23,6 +23,7 @@ import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.preference.* import androidx.preference.Preference.OnPreferenceClickListener +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.gson.Gson import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R @@ -119,7 +120,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere return true } - class SettingsFragment : PreferenceFragmentCompat() { + class SettingsFragment : BasePreferenceFragment() { private lateinit var repository: Repository private lateinit var serviceManager: SubscriberServiceManager private var autoDownloadSelection = AUTO_DOWNLOAD_SELECTION_NOT_SET @@ -202,7 +203,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere // Keep alerting for max priority val insistentMaxPriorityPrefId = context?.getString(R.string.settings_notifications_insistent_max_priority_key) ?: return - val insistentMaxPriority: SwitchPreference? = findPreference(insistentMaxPriorityPrefId) + val insistentMaxPriority: SwitchPreferenceCompat? = findPreference(insistentMaxPriorityPrefId) insistentMaxPriority?.isChecked = repository.getInsistentMaxPriorityEnabled() insistentMaxPriority?.preferenceDataStore = object : PreferenceDataStore() { override fun putBoolean(key: String?, value: Boolean) { @@ -212,7 +213,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere return repository.getInsistentMaxPriorityEnabled() } } - insistentMaxPriority?.summaryProvider = Preference.SummaryProvider { pref -> + insistentMaxPriority?.summaryProvider = Preference.SummaryProvider { pref -> if (pref.isChecked) { getString(R.string.settings_notifications_insistent_max_priority_summary_enabled) } else { @@ -346,7 +347,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere // Broadcast enabled val broadcastEnabledPrefId = context?.getString(R.string.settings_advanced_broadcast_key) ?: return - val broadcastEnabled: SwitchPreference? = findPreference(broadcastEnabledPrefId) + val broadcastEnabled: SwitchPreferenceCompat? = findPreference(broadcastEnabledPrefId) broadcastEnabled?.isChecked = repository.getBroadcastEnabled() broadcastEnabled?.preferenceDataStore = object : PreferenceDataStore() { override fun putBoolean(key: String?, value: Boolean) { @@ -356,7 +357,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere return repository.getBroadcastEnabled() } } - broadcastEnabled?.summaryProvider = Preference.SummaryProvider { pref -> + broadcastEnabled?.summaryProvider = Preference.SummaryProvider { pref -> if (pref.isChecked) { getString(R.string.settings_advanced_broadcast_summary_enabled) } else { @@ -366,7 +367,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere // Enable UnifiedPush val unifiedPushEnabledPrefId = context?.getString(R.string.settings_advanced_unifiedpush_key) ?: return - val unifiedPushEnabled: SwitchPreference? = findPreference(unifiedPushEnabledPrefId) + val unifiedPushEnabled: SwitchPreferenceCompat? = findPreference(unifiedPushEnabledPrefId) unifiedPushEnabled?.isChecked = repository.getUnifiedPushEnabled() unifiedPushEnabled?.preferenceDataStore = object : PreferenceDataStore() { override fun putBoolean(key: String?, value: Boolean) { @@ -376,7 +377,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere return repository.getUnifiedPushEnabled() } } - unifiedPushEnabled?.summaryProvider = Preference.SummaryProvider { pref -> + unifiedPushEnabled?.summaryProvider = Preference.SummaryProvider { pref -> if (pref.isChecked) { getString(R.string.settings_advanced_unifiedpush_summary_enabled) } else { @@ -411,7 +412,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere // Record logs val recordLogsPrefId = context?.getString(R.string.settings_advanced_record_logs_key) ?: return - val recordLogsEnabled: SwitchPreference? = findPreference(recordLogsPrefId) + val recordLogsEnabled: SwitchPreferenceCompat? = findPreference(recordLogsPrefId) recordLogsEnabled?.isChecked = Log.getRecord() recordLogsEnabled?.preferenceDataStore = object : PreferenceDataStore() { override fun putBoolean(key: String?, value: Boolean) { @@ -424,7 +425,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere return Log.getRecord() } } - recordLogsEnabled?.summaryProvider = Preference.SummaryProvider { pref -> + recordLogsEnabled?.summaryProvider = Preference.SummaryProvider { pref -> if (pref.isChecked) { getString(R.string.settings_advanced_record_logs_summary_enabled) } else { @@ -658,7 +659,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere } else { getString(R.string.settings_advanced_export_logs_scrub_dialog_empty) } - val dialog = AlertDialog.Builder(activity) + val dialog = MaterialAlertDialogBuilder(requireContext()) .setTitle(title) .setMessage(scrubbedText) .setPositiveButton(R.string.settings_advanced_export_logs_scrub_dialog_button_ok) { _, _ -> /* Nothing */ } @@ -682,7 +683,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere data class NopasteResponse(val url: String) } - class UserSettingsFragment : PreferenceFragmentCompat() { + class UserSettingsFragment : BasePreferenceFragment() { private lateinit var repository: Repository override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { diff --git a/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt index 6da8304a..a6c50202 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt @@ -9,6 +9,7 @@ import android.view.WindowManager import android.widget.Button import android.widget.TextView import androidx.fragment.app.DialogFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.textfield.TextInputEditText import io.heckel.ntfy.R import io.heckel.ntfy.db.User @@ -75,7 +76,7 @@ class UserFragment : DialogFragment() { } // Build dialog - val builder = AlertDialog.Builder(activity) + val builder = MaterialAlertDialogBuilder(requireContext()) .setView(view) .setPositiveButton(positiveButtonTextResId) { _, _ -> saveClicked() diff --git a/app/src/main/java/io/heckel/ntfy/util/Util.kt b/app/src/main/java/io/heckel/ntfy/util/Util.kt index 2ffbb766..d177e0b7 100644 --- a/app/src/main/java/io/heckel/ntfy/util/Util.kt +++ b/app/src/main/java/io/heckel/ntfy/util/Util.kt @@ -501,7 +501,7 @@ fun Button.dangerButton(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { setTextAppearance(R.style.DangerText) } else { - setTextColor(ContextCompat.getColor(context, Colors.dangerText(context))) + setTextColor(Colors.dangerText(context)) } } diff --git a/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml b/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml index f3c0ad0b..09425d1c 100644 --- a/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml +++ b/app/src/main/res/drawable/ic_notifications_off_time_white_outline_24dp.xml @@ -1,6 +1,7 @@ diff --git a/app/src/main/res/layout/dialog_edit_text_preference.xml b/app/src/main/res/layout/dialog_edit_text_preference.xml new file mode 100644 index 00000000..5ffaf240 --- /dev/null +++ b/app/src/main/res/layout/dialog_edit_text_preference.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_add_dialog.xml b/app/src/main/res/layout/fragment_add_dialog.xml index ad0c7d49..77b603b9 100644 --- a/app/src/main/res/layout/fragment_add_dialog.xml +++ b/app/src/main/res/layout/fragment_add_dialog.xml @@ -47,6 +47,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/add_dialog_topic_name_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" android:maxLength="64" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/add_dialog_subscribe_description"/> @@ -187,6 +188,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/add_dialog_login_username_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" android:maxLength="64" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@+id/add_dialog_login_description"/> @@ -195,6 +197,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/add_dialog_login_password_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="textPassword" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/add_dialog_login_username"/> diff --git a/app/src/main/res/layout/fragment_user_dialog.xml b/app/src/main/res/layout/fragment_user_dialog.xml index f6ed2715..bbffa4ff 100644 --- a/app/src/main/res/layout/fragment_user_dialog.xml +++ b/app/src/main/res/layout/fragment_user_dialog.xml @@ -32,6 +32,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/user_dialog_base_url_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="6dp" app:layout_constraintTop_toBottomOf="@id/user_dialog_description"/> @@ -40,6 +41,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/user_dialog_username_hint" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="text" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="6dp" app:layout_constraintTop_toBottomOf="@id/user_dialog_base_url"/> @@ -48,6 +50,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/user_dialog_password_hint_add" android:importantForAutofill="no" + android:backgroundTint="?attr/colorPrimary" android:maxLines="1" android:inputType="textPassword" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="6dp" app:layout_constraintTop_toBottomOf="@id/user_dialog_username"/> diff --git a/app/src/main/res/layout/view_preference_switch.xml b/app/src/main/res/layout/view_preference_switch.xml new file mode 100644 index 00000000..ba3fd967 --- /dev/null +++ b/app/src/main/res/layout/view_preference_switch.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index a71491b4..11168eda 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -10,9 +10,9 @@ - https://developer.android.com/guide/topics/ui/look-and-feel/themes --> - - + + + - + + + + + + diff --git a/app/src/main/res/xml/detail_preferences.xml b/app/src/main/res/xml/detail_preferences.xml index 38cd18b7..4cb105b1 100644 --- a/app/src/main/res/xml/detail_preferences.xml +++ b/app/src/main/res/xml/detail_preferences.xml @@ -3,7 +3,7 @@ - @@ -35,7 +35,7 @@ app:entryValues="@array/detail_settings_notifications_insistent_max_priority_values" app:defaultValue="-1" app:isPreferenceVisible="false"/> - diff --git a/app/src/main/res/xml/main_preferences.xml b/app/src/main/res/xml/main_preferences.xml index 0be2442a..589ae829 100644 --- a/app/src/main/res/xml/main_preferences.xml +++ b/app/src/main/res/xml/main_preferences.xml @@ -25,7 +25,7 @@ app:entries="@array/settings_notifications_auto_delete_entries" app:entryValues="@array/settings_notifications_auto_delete_values" app:defaultValue="2592000"/> - @@ -72,15 +72,15 @@ app:entries="@array/settings_advanced_connection_protocol_entries" app:entryValues="@array/settings_advanced_connection_protocol_values" app:defaultValue="jsonhttp"/> - - -