Merge pull request #2124 from vitorpamplona/claude/dismiss-poll-notifications-AEVw5
Add ability to dismiss poll notifications
This commit is contained in:
@@ -130,6 +130,7 @@ private object PrefKeys {
|
|||||||
const val LOGIN_WITH_EXTERNAL_SIGNER = "login_with_external_signer"
|
const val LOGIN_WITH_EXTERNAL_SIGNER = "login_with_external_signer"
|
||||||
const val SIGNER_PACKAGE_NAME = "signer_package_name"
|
const val SIGNER_PACKAGE_NAME = "signer_package_name"
|
||||||
const val HAS_DONATED_IN_VERSION = "has_donated_in_version"
|
const val HAS_DONATED_IN_VERSION = "has_donated_in_version"
|
||||||
|
const val DISMISSED_POLL_NOTE_IDS = "dismissed_poll_note_ids"
|
||||||
const val PENDING_ATTESTATIONS = "pending_attestations"
|
const val PENDING_ATTESTATIONS = "pending_attestations"
|
||||||
|
|
||||||
const val ALL_ACCOUNT_INFO = "all_saved_accounts_info"
|
const val ALL_ACCOUNT_INFO = "all_saved_accounts_info"
|
||||||
@@ -389,6 +390,7 @@ object LocalPreferences {
|
|||||||
JsonMapper.toJson(regularMap),
|
JsonMapper.toJson(regularMap),
|
||||||
)
|
)
|
||||||
putStringSet(PrefKeys.HAS_DONATED_IN_VERSION, settings.hasDonatedInVersion.value)
|
putStringSet(PrefKeys.HAS_DONATED_IN_VERSION, settings.hasDonatedInVersion.value)
|
||||||
|
putStringSet(PrefKeys.DISMISSED_POLL_NOTE_IDS, settings.dismissedPollNoteIds.value)
|
||||||
|
|
||||||
putString(
|
putString(
|
||||||
PrefKeys.PENDING_ATTESTATIONS,
|
PrefKeys.PENDING_ATTESTATIONS,
|
||||||
@@ -473,6 +475,7 @@ object LocalPreferences {
|
|||||||
val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false)
|
val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false)
|
||||||
val hideNIP17WarningDialog = getBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, false)
|
val hideNIP17WarningDialog = getBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, false)
|
||||||
val hasDonatedInVersion = getStringSet(PrefKeys.HAS_DONATED_IN_VERSION, null) ?: setOf()
|
val hasDonatedInVersion = getStringSet(PrefKeys.HAS_DONATED_IN_VERSION, null) ?: setOf()
|
||||||
|
val dismissedPollNoteIds = getStringSet(PrefKeys.DISMISSED_POLL_NOTE_IDS, null) ?: setOf()
|
||||||
val localRelayServers = getStringSet(PrefKeys.LOCAL_RELAY_SERVERS, null) ?: setOf()
|
val localRelayServers = getStringSet(PrefKeys.LOCAL_RELAY_SERVERS, null) ?: setOf()
|
||||||
|
|
||||||
val defaultHomeFollowListStr = getString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, null)
|
val defaultHomeFollowListStr = getString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, null)
|
||||||
@@ -594,6 +597,7 @@ object LocalPreferences {
|
|||||||
backupTrustProviderList = latestTrustProviderList.await(),
|
backupTrustProviderList = latestTrustProviderList.await(),
|
||||||
lastReadPerRoute = MutableStateFlow(lastReadPerRoute.await()),
|
lastReadPerRoute = MutableStateFlow(lastReadPerRoute.await()),
|
||||||
hasDonatedInVersion = MutableStateFlow(hasDonatedInVersion),
|
hasDonatedInVersion = MutableStateFlow(hasDonatedInVersion),
|
||||||
|
dismissedPollNoteIds = MutableStateFlow(dismissedPollNoteIds),
|
||||||
pendingAttestations = MutableStateFlow(pendingAttestations.await()),
|
pendingAttestations = MutableStateFlow(pendingAttestations.await()),
|
||||||
backupNipA3PaymentTargets = latestPaymentTargets.await(),
|
backupNipA3PaymentTargets = latestPaymentTargets.await(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2150,6 +2150,8 @@ class Account(
|
|||||||
|
|
||||||
fun markDonatedInThisVersion() = settings.markDonatedInThisVersion(BuildConfig.VERSION_NAME)
|
fun markDonatedInThisVersion() = settings.markDonatedInThisVersion(BuildConfig.VERSION_NAME)
|
||||||
|
|
||||||
|
fun dismissPollNotification(noteId: String) = settings.dismissPollNotification(noteId)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Log.d("AccountRegisterObservers", "Init")
|
Log.d("AccountRegisterObservers", "Init")
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ class AccountSettings(
|
|||||||
var backupTrustProviderList: TrustProviderListEvent? = null,
|
var backupTrustProviderList: TrustProviderListEvent? = null,
|
||||||
val lastReadPerRoute: MutableStateFlow<Map<String, MutableStateFlow<Long>>> = MutableStateFlow(mapOf()),
|
val lastReadPerRoute: MutableStateFlow<Map<String, MutableStateFlow<Long>>> = MutableStateFlow(mapOf()),
|
||||||
val hasDonatedInVersion: MutableStateFlow<Set<String>> = MutableStateFlow(setOf()),
|
val hasDonatedInVersion: MutableStateFlow<Set<String>> = MutableStateFlow(setOf()),
|
||||||
|
val dismissedPollNoteIds: MutableStateFlow<Set<String>> = MutableStateFlow(setOf()),
|
||||||
val pendingAttestations: MutableStateFlow<Map<HexKey, String>> = MutableStateFlow(mapOf()),
|
val pendingAttestations: MutableStateFlow<Map<HexKey, String>> = MutableStateFlow(mapOf()),
|
||||||
var backupNipA3PaymentTargets: PaymentTargetsEvent? = null,
|
var backupNipA3PaymentTargets: PaymentTargetsEvent? = null,
|
||||||
) : EphemeralChatRepository,
|
) : EphemeralChatRepository,
|
||||||
@@ -679,6 +680,21 @@ class AccountSettings(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
// dismissed polls
|
||||||
|
// ---
|
||||||
|
|
||||||
|
fun isDismissedPoll(noteId: String) = dismissedPollNoteIds.value.contains(noteId)
|
||||||
|
|
||||||
|
fun dismissPollNotification(noteId: String) {
|
||||||
|
if (!dismissedPollNoteIds.value.contains(noteId)) {
|
||||||
|
dismissedPollNoteIds.update {
|
||||||
|
it + noteId
|
||||||
|
}
|
||||||
|
saveAccountSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// last read flows
|
// last read flows
|
||||||
// ----
|
// ----
|
||||||
|
|||||||
+2
@@ -1126,6 +1126,8 @@ class AccountViewModel(
|
|||||||
|
|
||||||
fun markDonatedInThisVersion() = account.markDonatedInThisVersion()
|
fun markDonatedInThisVersion() = account.markDonatedInThisVersion()
|
||||||
|
|
||||||
|
fun dismissPollNotification(noteId: String) = account.dismissPollNotification(noteId)
|
||||||
|
|
||||||
fun dontTranslateFrom() = account.settings.syncedSettings.languages.dontTranslateFrom.value
|
fun dontTranslateFrom() = account.settings.syncedSettings.languages.dontTranslateFrom.value
|
||||||
|
|
||||||
fun translateTo() = account.settings.syncedSettings.languages.translateTo.value
|
fun translateTo() = account.settings.syncedSettings.languages.translateTo.value
|
||||||
|
|||||||
+14
@@ -36,6 +36,7 @@ import androidx.compose.foundation.lazy.LazyListState
|
|||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedButton
|
import androidx.compose.material3.OutlinedButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -59,6 +60,7 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.BadgeCompose
|
import com.vitorpamplona.amethyst.ui.note.BadgeCompose
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.CloseIcon
|
||||||
import com.vitorpamplona.amethyst.ui.note.MessageSetCompose
|
import com.vitorpamplona.amethyst.ui.note.MessageSetCompose
|
||||||
import com.vitorpamplona.amethyst.ui.note.MultiSetCompose
|
import com.vitorpamplona.amethyst.ui.note.MultiSetCompose
|
||||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||||
@@ -183,8 +185,20 @@ private fun FeedLoaded(
|
|||||||
Row(modifier = Modifier.padding(start = Size10dp, end = Size10dp, bottom = Size10dp)) {
|
Row(modifier = Modifier.padding(start = Size10dp, end = Size10dp, bottom = Size10dp)) {
|
||||||
Card(
|
Card(
|
||||||
modifier = MaterialTheme.colorScheme.imageModifier,
|
modifier = MaterialTheme.colorScheme.imageModifier,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
OpenPollsSectionHeader()
|
OpenPollsSectionHeader()
|
||||||
|
IconButton(
|
||||||
|
modifier = Modifier.padding(end = Size10dp),
|
||||||
|
onClick = { accountViewModel.dismissPollNotification(note.idHex) },
|
||||||
|
) {
|
||||||
|
CloseIcon()
|
||||||
|
}
|
||||||
|
}
|
||||||
Row(Modifier.fillMaxWidth().animateItem()) {
|
Row(Modifier.fillMaxWidth().animateItem()) {
|
||||||
NoteCompose(
|
NoteCompose(
|
||||||
baseNote = note,
|
baseNote = note,
|
||||||
|
|||||||
+7
-2
@@ -31,6 +31,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
@@ -47,10 +48,14 @@ class OpenPollsState(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val flow: StateFlow<List<Note>> =
|
val flow: StateFlow<List<Note>> =
|
||||||
|
combine(
|
||||||
account.cache
|
account.cache
|
||||||
.observeNotes(filter)
|
.observeNotes(filter)
|
||||||
.map { notes -> filterOpenPolls(notes) }
|
.map { notes -> filterOpenPolls(notes) },
|
||||||
.flowOn(Dispatchers.IO)
|
account.settings.dismissedPollNoteIds,
|
||||||
|
) { polls, dismissed ->
|
||||||
|
polls.filter { it.idHex !in dismissed }
|
||||||
|
}.flowOn(Dispatchers.IO)
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope,
|
scope,
|
||||||
SharingStarted.Eagerly,
|
SharingStarted.Eagerly,
|
||||||
|
|||||||
Reference in New Issue
Block a user