Simplify and organize settings pages

This commit is contained in:
ajp_anton
2026-07-27 12:59:26 +00:00
parent 3dc87b417a
commit cad73e33a0
21 changed files with 293 additions and 426 deletions
@@ -11,7 +11,6 @@ import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
@@ -22,24 +21,20 @@ import se.ajpanton.notificationlog.settings.AppListItem
import se.ajpanton.notificationlog.settings.AppListOrdering
import se.ajpanton.notificationlog.settings.AppRuleMode
import se.ajpanton.notificationlog.settings.ListedApp
import se.ajpanton.notificationlog.settings.LoggingRule
import se.ajpanton.notificationlog.settings.LoggingRuleStore
import se.ajpanton.notificationlog.settings.LoggingType
import se.ajpanton.notificationlog.settings.AppFilterSettings
import se.ajpanton.notificationlog.settings.AppFilterSettingsStore
class EventSettingsFragment : Fragment(R.layout.fragment_event_settings) {
class FilterAppsFragment : Fragment(R.layout.fragment_event_settings) {
private var binding: FragmentEventSettingsBinding? = null
private lateinit var type: LoggingType
private lateinit var store: LoggingRuleStore
private lateinit var store: AppFilterSettingsStore
private lateinit var appAdapter: AppListAdapter
private var appLoadGeneration = 0
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentEventSettingsBinding.bind(view)
type = requireArguments().getSerializable(ARG_TYPE, LoggingType::class.java)!!
store = LoggingRuleStore(requireContext())
store = AppFilterSettingsStore(requireContext())
appAdapter = AppListAdapter(::setPackageSelected)
binding!!.pageTitle.setText(requireArguments().getInt(ARG_TITLE))
binding!!.appList.layoutManager = LinearLayoutManager(requireContext())
binding!!.appList.adapter = appAdapter
binding!!.appListRefresh.setOnRefreshListener(::reloadAppList)
@@ -66,40 +61,32 @@ class EventSettingsFragment : Fragment(R.layout.fragment_event_settings) {
}
private fun bindRule() {
val rule = store.ruleFor(type)
val rule = store.load()
listOf(
binding!!.masterToggle,
binding!!.appRuleToggle,
binding!!.onlySeenToggle,
binding!!.seenFirstToggle,
binding!!.routineUpdatesToggle,
).forEach { it.setOnCheckedChangeListener(null) }
binding!!.masterToggle.isChecked = rule.enabled
binding!!.appRuleToggle.isChecked = rule.appRuleMode == AppRuleMode.WHITELIST
binding!!.appRuleToggle.isChecked = rule.mode == AppRuleMode.WHITELIST
binding!!.onlySeenToggle.isChecked = rule.onlySeenApps
binding!!.seenFirstToggle.isChecked = rule.seenAppsFirst
binding!!.seenFirstToggle.isEnabled = !rule.onlySeenApps
binding!!.routineUpdatesToggle.visibility = if (type == LoggingType.EDITS) View.VISIBLE else View.GONE
binding!!.routineUpdatesToggle.isChecked = rule.ignoreRoutineUpdates
updateRuleLabels(rule)
binding!!.masterToggle.setOnCheckedChangeListener { _, checked -> save { copy(enabled = checked) } }
binding!!.appRuleToggle.setOnCheckedChangeListener { _, checked ->
save { copy(appRuleMode = if (checked) AppRuleMode.WHITELIST else AppRuleMode.BLACKLIST) }
save { copy(mode = if (checked) AppRuleMode.WHITELIST else AppRuleMode.BLACKLIST) }
}
binding!!.onlySeenToggle.setOnCheckedChangeListener { _, checked -> save { copy(onlySeenApps = checked) } }
binding!!.seenFirstToggle.setOnCheckedChangeListener { _, checked -> save { copy(seenAppsFirst = checked) } }
binding!!.routineUpdatesToggle.setOnCheckedChangeListener { _, checked -> save { copy(ignoreRoutineUpdates = checked) } }
reloadAppList()
}
private fun save(change: LoggingRule.() -> LoggingRule) {
store.save(type, store.ruleFor(type).change())
private fun save(change: AppFilterSettings.() -> AppFilterSettings) {
store.save(store.load().change())
bindRule()
}
private fun updateRuleLabels(rule: LoggingRule) {
binding!!.masterToggle.text = "Enable logging"
binding!!.appRuleToggle.text = modeLabel(rule.appRuleMode)
private fun updateRuleLabels(rule: AppFilterSettings) {
binding!!.appRuleToggle.text = modeLabel(rule.mode)
binding!!.onlySeenToggle.text = "Show only seen apps"
binding!!.seenFirstToggle.text = "Show seen apps first"
}
@@ -122,7 +109,7 @@ class EventSettingsFragment : Fragment(R.layout.fragment_event_settings) {
val generation = ++appLoadGeneration
currentBinding.appListLoading.visibility = View.VISIBLE
currentBinding.appListRefresh.isRefreshing = true
val rule = store.ruleFor(type)
val rule = store.load()
val seen = SeenApps.snapshot()
val context = requireContext().applicationContext
Thread {
@@ -146,11 +133,11 @@ class EventSettingsFragment : Fragment(R.layout.fragment_event_settings) {
}
private fun setPackageSelected(packageName: String, selected: Boolean) {
val current = store.ruleFor(type)
val current = store.load()
val packages = current.selectedPackages.toMutableSet().apply {
if (selected) add(packageName) else remove(packageName)
}
store.save(type, current.copy(selectedPackages = packages))
store.save(current.copy(selectedPackages = packages))
// Do not reload: an unchecked unseen row remains visible until the next requested refresh.
}
@@ -231,14 +218,6 @@ class EventSettingsFragment : Fragment(R.layout.fragment_event_settings) {
}
companion object {
private const val ARG_TITLE = "title"
private const val ARG_TYPE = "type"
fun newInstance(@StringRes title: Int, type: LoggingType) = EventSettingsFragment().apply {
arguments = Bundle().apply {
putInt(ARG_TITLE, title)
putSerializable(ARG_TYPE, type)
}
}
fun newInstance() = FilterAppsFragment()
}
}