Make better
This commit is contained in:
parent
c2396dd1a3
commit
7cfef864a2
5 changed files with 38 additions and 73 deletions
|
|
@ -574,6 +574,19 @@ interface NotificationDao {
|
|||
@Query("SELECT * FROM notification WHERE subscriptionId = :subscriptionId AND deleted != 1 ORDER BY timestamp DESC")
|
||||
fun listFlow(subscriptionId: Long): Flow<List<Notification>>
|
||||
|
||||
@Query("""
|
||||
SELECT * FROM notification
|
||||
WHERE subscriptionId = :subscriptionId
|
||||
AND deleted != 1
|
||||
AND (
|
||||
title LIKE '%' || :query || '%' COLLATE NOCASE
|
||||
OR message LIKE '%' || :query || '%' COLLATE NOCASE
|
||||
OR tags LIKE '%' || :query || '%' COLLATE NOCASE
|
||||
)
|
||||
ORDER BY timestamp DESC
|
||||
""")
|
||||
fun listFlowFiltered(subscriptionId: Long, query: String): Flow<List<Notification>>
|
||||
|
||||
@Query("SELECT * FROM notification WHERE deleted = 1 AND attachment_contentUri <> ''")
|
||||
fun listDeletedWithAttachments(): List<Notification>
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ class Repository(private val sharedPrefs: SharedPreferences, database: Database)
|
|||
return notificationDao.listFlow(subscriptionId).asLiveData()
|
||||
}
|
||||
|
||||
fun getNotificationsFilteredLiveData(subscriptionId: Long, query: String): LiveData<List<Notification>> {
|
||||
return notificationDao.listFlowFiltered(subscriptionId, query).asLiveData()
|
||||
}
|
||||
|
||||
fun getNotification(notificationId: String): Notification? {
|
||||
return notificationDao.get(notificationId)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
// Search state
|
||||
private var searchView: SearchView? = null
|
||||
private var isSearchActive: Boolean = false
|
||||
private lateinit var toolbar: com.google.android.material.appbar.MaterialToolbar
|
||||
private var toolbarTextColor: Int = 0
|
||||
|
||||
// Action mode stuff
|
||||
private var actionMode: ActionMode? = null
|
||||
|
|
@ -147,13 +149,17 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
val dynamicColors = repository.getDynamicColorsEnabled()
|
||||
val darkMode = isDarkThemeOn(this)
|
||||
val statusBarColor = Colors.statusBarNormal(this, dynamicColors, darkMode)
|
||||
val toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode)
|
||||
toolbarTextColor = Colors.toolbarTextColor(this, dynamicColors, darkMode)
|
||||
toolbarLayout.setBackgroundColor(statusBarColor)
|
||||
|
||||
val toolbar = toolbarLayout.findViewById<com.google.android.material.appbar.MaterialToolbar>(R.id.toolbar)
|
||||
toolbar = toolbarLayout.findViewById(R.id.toolbar)
|
||||
toolbar.setTitleTextColor(toolbarTextColor)
|
||||
toolbar.setNavigationIconTint(toolbarTextColor)
|
||||
toolbar.overflowIcon?.setTint(toolbarTextColor)
|
||||
// Set collapse icon (back arrow when search is expanded) with proper tint
|
||||
val collapseIcon = ContextCompat.getDrawable(this, R.drawable.ic_arrow_back_white_24dp)?.mutate()
|
||||
collapseIcon?.setTint(toolbarTextColor)
|
||||
toolbar.collapseIcon = collapseIcon
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
// Set system status bar appearance
|
||||
|
|
@ -537,7 +543,6 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
subscriptionMutedUntil = subscription.mutedUntil
|
||||
subscriptionDisplayName = displayName(appBaseUrl, subscription)
|
||||
|
||||
showHideInstantMenuItems(subscriptionInstant)
|
||||
showHideMutedUntilMenuItems(subscriptionMutedUntil)
|
||||
showHideCopyMenuItems(subscription.baseUrl)
|
||||
showHideConnectionErrorMenuItem(repository.getConnectionDetails())
|
||||
|
|
@ -574,7 +579,6 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
this.menu = menu
|
||||
|
||||
// Tint menu icons based on theme
|
||||
val toolbarTextColor = Colors.toolbarTextColor(this, repository.getDynamicColorsEnabled(), isDarkThemeOn(this))
|
||||
for (i in 0 until menu.size) {
|
||||
menu[i].icon?.setTint(toolbarTextColor)
|
||||
}
|
||||
|
|
@ -584,6 +588,7 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
searchView = searchItem?.actionView as? SearchView
|
||||
searchView?.let { sv ->
|
||||
sv.queryHint = getString(R.string.detail_search_hint)
|
||||
sv.maxWidth = Integer.MAX_VALUE // Make SearchView expand fully
|
||||
|
||||
// Tint SearchView icons and text
|
||||
val searchIcon = sv.findViewById<ImageView>(androidx.appcompat.R.id.search_button)
|
||||
|
|
@ -612,6 +617,8 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
isSearchActive = true
|
||||
// Hide other menu items when search is expanded
|
||||
setMenuItemsVisibility(false)
|
||||
// Ensure collapse icon is tinted (back arrow when search is expanded)
|
||||
toolbar.collapseIcon?.setTint(toolbarTextColor)
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -621,7 +628,6 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
viewModel.setSearchQuery("")
|
||||
// Restore menu items visibility
|
||||
setMenuItemsVisibility(true)
|
||||
showHideInstantMenuItems(subscriptionInstant)
|
||||
showHideMutedUntilMenuItems(subscriptionMutedUntil)
|
||||
showHideCopyMenuItems(subscriptionBaseUrl)
|
||||
showHideConnectionErrorMenuItem(repository.getConnectionDetails())
|
||||
|
|
@ -631,7 +637,6 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
}
|
||||
|
||||
// Show and hide buttons
|
||||
showHideInstantMenuItems(subscriptionInstant)
|
||||
showHideMutedUntilMenuItems(subscriptionMutedUntil)
|
||||
showHideCopyMenuItems(subscriptionBaseUrl)
|
||||
showHideConnectionErrorMenuItem(repository.getConnectionDetails())
|
||||
|
|
@ -692,14 +697,6 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
onMutedUntilClick(enable = true)
|
||||
true
|
||||
}
|
||||
R.id.detail_menu_enable_instant -> {
|
||||
onInstantEnableClick(enable = true)
|
||||
true
|
||||
}
|
||||
R.id.detail_menu_disable_instant -> {
|
||||
onInstantEnableClick(enable = false)
|
||||
true
|
||||
}
|
||||
R.id.detail_menu_connection_error -> {
|
||||
onConnectionErrorClick()
|
||||
true
|
||||
|
|
@ -833,46 +830,6 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
|
|||
}
|
||||
}
|
||||
|
||||
private fun onInstantEnableClick(enable: Boolean) {
|
||||
Log.d(TAG, "Toggling instant delivery setting for ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}")
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val subscription = repository.getSubscription(subscriptionId)
|
||||
val newSubscription = subscription?.copy(instant = enable)
|
||||
newSubscription?.let { repository.updateSubscription(newSubscription) }
|
||||
showHideInstantMenuItems(enable)
|
||||
runOnUiThread {
|
||||
if (enable) {
|
||||
Toast.makeText(this@DetailActivity, getString(R.string.detail_instant_delivery_enabled), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
} else {
|
||||
Toast.makeText(this@DetailActivity, getString(R.string.detail_instant_delivery_disabled), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHideInstantMenuItems(enable: Boolean) {
|
||||
if (!this::menu.isInitialized) {
|
||||
return
|
||||
}
|
||||
subscriptionInstant = enable
|
||||
runOnUiThread {
|
||||
val appBaseUrl = getString(R.string.app_base_url)
|
||||
val enableInstantItem = menu.findItem(R.id.detail_menu_enable_instant)
|
||||
val disableInstantItem = menu.findItem(R.id.detail_menu_disable_instant)
|
||||
val allowToggleInstant = BuildConfig.FIREBASE_AVAILABLE && subscriptionBaseUrl == appBaseUrl
|
||||
if (allowToggleInstant) {
|
||||
enableInstantItem?.isVisible = !subscriptionInstant
|
||||
disableInstantItem?.isVisible = subscriptionInstant
|
||||
} else {
|
||||
enableInstantItem?.isVisible = false
|
||||
disableInstantItem?.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHideMutedUntilMenuItems(mutedUntilTimestamp: Long) {
|
||||
if (!this::menu.isInitialized) {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.switchMap
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.heckel.ntfy.db.Notification
|
||||
import io.heckel.ntfy.db.Repository
|
||||
import io.heckel.ntfy.db.combineWith
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -15,6 +15,8 @@ class DetailViewModel(private val repository: Repository) : ViewModel() {
|
|||
private val _searchQuery = MutableLiveData("")
|
||||
val searchQuery: LiveData<String> = _searchQuery
|
||||
|
||||
private var currentSubscriptionId: Long = 0
|
||||
|
||||
fun setSearchQuery(query: String) {
|
||||
_searchQuery.value = query
|
||||
}
|
||||
|
|
@ -24,19 +26,14 @@ class DetailViewModel(private val repository: Repository) : ViewModel() {
|
|||
}
|
||||
|
||||
fun listFiltered(subscriptionId: Long): LiveData<List<Notification>> {
|
||||
return repository.getNotificationsLiveData(subscriptionId)
|
||||
.combineWith(_searchQuery) { notifications, query ->
|
||||
if (query.isNullOrBlank()) {
|
||||
notifications.orEmpty()
|
||||
} else {
|
||||
val q = query.lowercase()
|
||||
notifications.orEmpty().filter { n ->
|
||||
n.title.lowercase().contains(q) ||
|
||||
n.message.lowercase().contains(q) ||
|
||||
n.tags.lowercase().contains(q)
|
||||
}
|
||||
}
|
||||
currentSubscriptionId = subscriptionId
|
||||
return _searchQuery.switchMap { query ->
|
||||
if (query.isNullOrBlank()) {
|
||||
repository.getNotificationsLiveData(subscriptionId)
|
||||
} else {
|
||||
repository.getNotificationsFilteredLiveData(subscriptionId, query)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun markAsDeleted(notificationId: String) = viewModelScope.launch(Dispatchers.IO) {
|
||||
|
|
|
|||
|
|
@ -28,12 +28,6 @@
|
|||
android:icon="@drawable/ic_notifications_off_white_outline_24dp"
|
||||
android:title="@string/detail_menu_notifications_disabled_forever"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/detail_menu_enable_instant"
|
||||
android:title="@string/detail_menu_enable_instant" />
|
||||
<item
|
||||
android:id="@+id/detail_menu_disable_instant"
|
||||
android:title="@string/detail_menu_disable_instant" />
|
||||
<item
|
||||
android:id="@+id/detail_menu_settings"
|
||||
android:title="@string/detail_menu_settings" />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue