Display notification filter/clear actions as menu items (#3877)

Previously the notification filter and clear actions were shown as
buttons in the UI, with a preference that determined whether they were
displayed.

Remove this preference, and display them as menu items.

- "Filter notifications" is shown as an icon, if possible
- "Clear notifications" is only ever shown as a menu item, to reduce the
chance the user inadvertently selects it

To ensure that the options menu appears correctly, remove the code that
creates a "fake" action bar, and adjust the layouts so that there are
three toolbars;

- mainToolbar -- displays the icons, and the current "location" (Home,
Notifications, etc)
- topNav -- displays the row of tabs at the top
- bottomNav -- displays the row of tabs at the bottom

Only one of them is set as the support action bar (depending on the
user's preferences). This provides the "show a logo" and "show the
options menu" functionality as standard, without needing to re-implement
as the previous code did.
This commit is contained in:
Nik Clayton 2023-08-19 14:41:10 +02:00 committed by GitHub
commit 059352f471
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 152 additions and 304 deletions

View file

@ -28,7 +28,6 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
@ -46,7 +45,6 @@ import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import androidx.recyclerview.widget.SimpleItemAnimator
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import at.connyduck.sparkbutton.helpers.Utils
import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior
import com.google.android.material.color.MaterialColors
import com.google.android.material.snackbar.Snackbar
import com.keylesspalace.tusky.R
@ -123,21 +121,6 @@ class NotificationsFragment :
return inflater.inflate(R.layout.fragment_timeline_notifications, container, false)
}
private fun updateFilterVisibility(showFilter: Boolean) {
val params = binding.swipeRefreshLayout.layoutParams as CoordinatorLayout.LayoutParams
if (showFilter) {
binding.appBarOptions.setExpanded(true, false)
binding.appBarOptions.visibility = View.VISIBLE
// Set content behaviour to hide filter on scroll
params.behavior = ScrollingViewBehavior()
} else {
binding.appBarOptions.setExpanded(false, false)
binding.appBarOptions.visibility = View.GONE
// Clear behaviour to hide app bar
params.behavior = null
}
}
private fun confirmClearNotifications() {
AlertDialog.Builder(requireContext())
.setMessage(R.string.notification_clear_text)
@ -215,8 +198,6 @@ class NotificationsFragment :
footer = NotificationsLoadStateAdapter { adapter.retry() }
)
binding.buttonClear.setOnClickListener { confirmClearNotifications() }
binding.buttonFilter.setOnClickListener { showFilterDialog() }
(binding.recyclerView.itemAnimator as SimpleItemAnimator?)!!.supportsChangeAnimations =
false
@ -369,10 +350,10 @@ class NotificationsFragment :
}
}
// Update filter option visibility from uiState
launch {
viewModel.uiState.collectLatest { updateFilterVisibility(it.showFilterOptions) }
}
// Collect the uiState. Nothing is done with it, but if you don't collect it then
// accessing viewModel.uiState.value (e.g., when the filter dialog is created)
// returns an empty object.
launch { viewModel.uiState.collect() }
// Update status display from statusDisplayOptions. If the new options request
// relative time display collect the flow to periodically update the timestamp in the list gui elements.
@ -439,10 +420,17 @@ class NotificationsFragment :
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.fragment_notifications, menu)
val iconColor = MaterialColors.getColor(binding.root, android.R.attr.textColorPrimary)
menu.findItem(R.id.action_refresh)?.apply {
icon = IconicsDrawable(requireContext(), GoogleMaterial.Icon.gmd_refresh).apply {
sizeDp = 20
colorInt = MaterialColors.getColor(binding.root, android.R.attr.textColorPrimary)
colorInt = iconColor
}
}
menu.findItem(R.id.action_edit_notification_filter)?.apply {
icon = IconicsDrawable(requireContext(), GoogleMaterial.Icon.gmd_tune).apply {
sizeDp = 20
colorInt = iconColor
}
}
}
@ -458,6 +446,14 @@ class NotificationsFragment :
viewModel.accept(InfallibleUiAction.LoadNewest)
true
}
R.id.action_edit_notification_filter -> {
showFilterDialog()
true
}
R.id.action_clear_notifications -> {
confirmClearNotifications()
true
}
else -> false
}
}
@ -625,7 +621,6 @@ class NotificationsFragment :
override fun onReselect() {
if (isAdded) {
binding.appBarOptions.setExpanded(true, false)
layoutManager.scrollToPosition(0)
}
}

View file

@ -74,23 +74,18 @@ data class UiState(
/** Filtered notification types */
val activeFilter: Set<Notification.Type> = emptySet(),
/** True if the UI to filter and clear notifications should be shown */
val showFilterOptions: Boolean = false,
/** True if the FAB should be shown while scrolling */
val showFabWhileScrolling: Boolean = true
)
/** Preferences the UI reacts to */
data class UiPrefs(
val showFabWhileScrolling: Boolean,
val showFilter: Boolean
val showFabWhileScrolling: Boolean
) {
companion object {
/** Relevant preference keys. Changes to any of these trigger a display update */
val prefKeys = setOf(
PrefKeys.FAB_HIDE,
PrefKeys.SHOW_NOTIFICATIONS_FILTER
PrefKeys.FAB_HIDE
)
}
}
@ -495,7 +490,6 @@ class NotificationsViewModel @Inject constructor(
uiState = combine(notificationFilter, getUiPrefs()) { filter, prefs ->
UiState(
activeFilter = filter.filter,
showFilterOptions = prefs.showFilter,
showFabWhileScrolling = prefs.showFabWhileScrolling
)
}.stateIn(
@ -544,8 +538,7 @@ class NotificationsViewModel @Inject constructor(
.onStart { emit(toPrefs()) }
private fun toPrefs() = UiPrefs(
showFabWhileScrolling = !preferences.getBoolean(PrefKeys.FAB_HIDE, false),
showFilter = preferences.getBoolean(PrefKeys.SHOW_NOTIFICATIONS_FILTER, true)
showFabWhileScrolling = !preferences.getBoolean(PrefKeys.FAB_HIDE, false)
)
companion object {

View file

@ -208,13 +208,6 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
isSingleLineTitle = false
}
switchPreference {
setDefaultValue(true)
key = PrefKeys.SHOW_NOTIFICATIONS_FILTER
setTitle(R.string.pref_title_show_notifications_filter)
isSingleLineTitle = false
}
switchPreference {
setDefaultValue(true)
key = PrefKeys.CONFIRM_REBLOGS