WIP: Manage user settings

This commit is contained in:
Philipp Heckel 2022-01-28 14:40:09 -05:00
parent 437bc76b8c
commit 678e5625dd
6 changed files with 110 additions and 6 deletions

View file

@ -65,9 +65,9 @@ dependencies {
implementation "androidx.core:core-ktx:1.7.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.3"
implementation "androidx.activity:activity-ktx:1.4.0"
implementation "androidx.fragment:fragment-ktx:1.4.0"
implementation "androidx.fragment:fragment-ktx:1.4.1"
implementation "androidx.work:work-runtime-ktx:2.7.1"
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.preference:preference-ktx:1.2.0'
// JSON serialization
implementation 'com.google.code.gson:gson:2.8.9'

View file

@ -22,10 +22,12 @@ import com.google.gson.Gson
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.User
import io.heckel.ntfy.log.Log
import io.heckel.ntfy.service.SubscriberService
import io.heckel.ntfy.util.formatBytes
import io.heckel.ntfy.util.formatDateShort
import io.heckel.ntfy.util.shortUrl
import io.heckel.ntfy.util.toPriorityString
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -35,7 +37,13 @@ import okhttp3.RequestBody.Companion.toRequestBody
import java.util.*
import java.util.concurrent.TimeUnit
class SettingsActivity : AppCompatActivity() {
/**
* Main settings
*
* The "nested screen" navigation stuff (for user management) has been taken from
* https://github.com/googlearchive/android-preferences/blob/master/app/src/main/java/com/example/androidx/preference/sample/MainActivity.kt
*/
class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
private lateinit var fragment: SettingsFragment
override fun onCreate(savedInstanceState: Bundle?) {
@ -50,15 +58,58 @@ class SettingsActivity : AppCompatActivity() {
.beginTransaction()
.replace(R.id.settings_layout, fragment)
.commit()
} else {
title = savedInstanceState.getCharSequence(TITLE_TAG)
}
supportFragmentManager.addOnBackStackChangedListener {
if (supportFragmentManager.backStackEntryCount == 0) {
setTitle(R.string.settings_title)
}
}
// Action bar
title = getString(R.string.settings_title)
//title = getString(R.string.settings_title)
// Show 'Back' button
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
// Save current activity title so we can set it again after a configuration change
outState.putCharSequence(TITLE_TAG, title)
}
override fun onSupportNavigateUp(): Boolean {
if (supportFragmentManager.popBackStackImmediate()) {
return true
}
return super.onSupportNavigateUp()
}
override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat,
pref: Preference
): Boolean {
// Instantiate the new Fragment
val args = pref.extras
val fragment = supportFragmentManager.fragmentFactory.instantiate(
classLoader,
pref.fragment!!
).apply {
arguments = args
setTargetFragment(caller, 0)
}
// Replace the existing Fragment with the new Fragment
supportFragmentManager.beginTransaction()
.replace(R.id.settings_layout, fragment)
.addToBackStack(null)
.commit()
title = pref.title
return true
}
class SettingsFragment : PreferenceFragmentCompat() {
private lateinit var repository: Repository
private var autoDownloadSelection = AUTO_DOWNLOAD_SELECTION_NOT_SET
@ -463,6 +514,41 @@ class SettingsActivity : AppCompatActivity() {
data class NopasteResponse(val url: String)
}
class UserSettingsFragment : PreferenceFragmentCompat() {
private lateinit var repository: Repository
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.user_preferences, rootKey)
// Dependencies (Fragments need a default constructor)
repository = Repository.getInstance(requireActivity())
lifecycleScope.launch(Dispatchers.IO) {
val usersByBaseUrl = repository.getUsers().groupBy { it.baseUrl }
activity?.runOnUiThread {
addUserPreferences(usersByBaseUrl)
}
}
}
private fun addUserPreferences(usersByBaseUrl: Map<String, List<User>>) {
usersByBaseUrl.forEach { entry ->
val baseUrl = entry.key
val users = entry.value
val preferenceCategory = PreferenceCategory(preferenceScreen.context)
preferenceCategory.title = shortUrl(baseUrl)
preferenceScreen.addPreference(preferenceCategory)
users.forEach { user ->
val preference = Preference(preferenceScreen.context)
preference.title = user.username
preferenceCategory.addPreference(preference)
}
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION_FOR_AUTO_DOWNLOAD) {
@ -479,6 +565,7 @@ class SettingsActivity : AppCompatActivity() {
companion object {
private const val TAG = "NtfySettingsActivity"
private const val TITLE_TAG = "title"
private const val REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION_FOR_AUTO_DOWNLOAD = 2586
private const val AUTO_DOWNLOAD_SELECTION_NOT_SET = -99L
private const val EXPORT_LOGS_COPY = "copy"

View file

@ -238,6 +238,11 @@
<string name="settings_appearance_dark_mode_entry_system">Use system default</string>
<string name="settings_appearance_dark_mode_entry_light">Light mode</string>
<string name="settings_appearance_dark_mode_entry_dark">Dark mode</string>
<string name="settings_users_header">Users</string>
<string name="settings_users_key">ManageUsers</string>
<string name="settings_users_title">Manage users</string>
<string name="settings_users_summary">Add or remove users used for protected topics</string>
<string name="settings_users_prefs_title">Users</string>
<string name="settings_unified_push_header">UnifiedPush</string>
<string name="settings_unified_push_header_summary">Allows other apps to use ntfy as a message distributor. Find out more at unifiedpush.org.</string>
<string name="settings_unified_push_enabled_key">UnifiedPushEnabled</string>

View file

@ -32,6 +32,15 @@
app:entryValues="@array/settings_appearance_dark_mode_values"
app:defaultValue="-1"/>
</PreferenceCategory>
<PreferenceCategory
app:title="@string/settings_users_header"
app:layout="@layout/preference_category_material_edited">
<Preference
app:key="@string/settings_users_key"
app:title="@string/settings_users_title"
app:summary="@string/settings_users_summary"
app:fragment="io.heckel.ntfy.ui.SettingsActivity$UserSettingsFragment"/>
</PreferenceCategory>
<PreferenceCategory
app:title="@string/settings_unified_push_header"
app:summary="@string/settings_unified_push_header_summary"

View file

@ -0,0 +1,3 @@
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
app:title="@string/settings_users_prefs_title">
</PreferenceScreen>

View file

@ -1,3 +1,3 @@
Bug fixes:
* Fix download issues on SDK 29 "Movement not allowed" (#116)
* Fix for Android 12 crashes (#124)
* Fix download issues on SDK 29 "Movement not allowed" (#116, thanks Jakob)
* Fix for Android 12 crashes (#124, thanks @eskilop)