From a8dd3bebc0cacf60e6c7b5f89bce2617cb2e3eed Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Fri, 28 Jan 2022 22:53:48 -0500 Subject: [PATCH] WIP User edit dialog --- .../io/heckel/ntfy/ui/SettingsActivity.kt | 36 ++++++++++-- .../java/io/heckel/ntfy/ui/UserFragment.kt | 57 +++++++++++++++++++ .../main/res/layout/fragment_user_dialog.xml | 41 +++++++++++++ app/src/main/res/values/strings.xml | 13 +++++ 4 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt create mode 100644 app/src/main/res/layout/fragment_user_dialog.xml 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 8e523de..6577ecd 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt @@ -67,9 +67,6 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere } } - // Action bar - //title = getString(R.string.settings_title) - // Show 'Back' button supportActionBar?.setDisplayHomeAsUpEnabled(true) } @@ -524,14 +521,28 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere repository = Repository.getInstance(requireActivity()) lifecycleScope.launch(Dispatchers.IO) { - val usersByBaseUrl = repository.getUsers().groupBy { it.baseUrl } + val userIdsWithTopics = repository.getSubscriptions() + .groupBy { it.authUserId } + .mapValues { e -> e.value.map { it.topic } } + val usersByBaseUrl = repository.getUsers() + .map { user -> + val topics = userIdsWithTopics[user.id] ?: emptyList() + UserWithMetadata(user, topics) + } + .groupBy { it.user.baseUrl } + activity?.runOnUiThread { addUserPreferences(usersByBaseUrl) } } } - private fun addUserPreferences(usersByBaseUrl: Map>) { + data class UserWithMetadata( + val user: User, + val topics: List + ) + + private fun addUserPreferences(usersByBaseUrl: Map>) { usersByBaseUrl.forEach { entry -> val baseUrl = entry.key val users = entry.value @@ -542,7 +553,20 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere users.forEach { user -> val preference = Preference(preferenceScreen.context) - preference.title = user.username + preference.title = user.user.username + preference.summary = if (user.topics.isEmpty()) { + getString(R.string.settings_users_prefs_user_not_used) + } else if (user.topics.size == 1) { + getString(R.string.settings_users_prefs_user_used_by_one, user.topics[0]) + } else { + getString(R.string.settings_users_prefs_user_used_by_many, user.topics.joinToString(", ")) + } + preference.onPreferenceClickListener = OnPreferenceClickListener { _ -> + activity?.let { + UserFragment().show(it.supportFragmentManager, UserFragment.TAG) + } + true + } preferenceCategory.addPreference(preference) } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt new file mode 100644 index 0000000..b76af6c --- /dev/null +++ b/app/src/main/java/io/heckel/ntfy/ui/UserFragment.kt @@ -0,0 +1,57 @@ +package io.heckel.ntfy.ui + +import android.app.AlertDialog +import android.app.Dialog +import android.os.Bundle +import android.view.WindowManager +import android.widget.TextView +import androidx.fragment.app.DialogFragment +import io.heckel.ntfy.R + +class UserFragment : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + if (activity == null) { + throw IllegalStateException("Activity cannot be null") + } + + // Build root view + val view = requireActivity().layoutInflater.inflate(R.layout.fragment_user_dialog, null) + + val addMode = false // FIXME + val positiveButtonTextResId = if (addMode) R.string.user_dialog_button_add else R.string.user_dialog_button_save + val titleText = view.findViewById(R.id.user_dialog_title) as TextView + titleText.text = if (addMode) { + getString(R.string.user_dialog_title_add) + } else { + getString(R.string.user_dialog_title_edit) + } + + // Build dialog + val dialog = AlertDialog.Builder(activity) + .setView(view) + .setPositiveButton(positiveButtonTextResId) { _, _ -> + // This will be overridden below to avoid closing the dialog immediately + } + .setNegativeButton(R.string.user_dialog_button_cancel) { _, _ -> + // This will be overridden below + } + .setNeutralButton(R.string.user_dialog_button_delete) { _, _ -> + // This will be overridden below + } + .create() + + // Show keyboard when the dialog is shown (see https://stackoverflow.com/a/19573049/1440785) + dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + + // Add logic to disable "Subscribe" button on invalid input + dialog.setOnShowListener { + + } + + return dialog + } + + companion object { + const val TAG = "NtfyUserFragment" + } +} diff --git a/app/src/main/res/layout/fragment_user_dialog.xml b/app/src/main/res/layout/fragment_user_dialog.xml new file mode 100644 index 0000000..3676206 --- /dev/null +++ b/app/src/main/res/layout/fragment_user_dialog.xml @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3708ade..5782d45 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -243,6 +243,9 @@ Manage users Add or remove users used for protected topics Users + Not used by any topics + Used by topic %1$s + Used by topics %1$s UnifiedPush Allows other apps to use ntfy as a message distributor. Find out more at unifiedpush.org. UnifiedPushEnabled @@ -290,4 +293,14 @@ Version ntfy %1$s (%2$s) Copied to clipboard + + + Add user + Edit user + Username + Password + Add user + Cancel + Delete user + Save