diff --git a/app/src/main/kotlin/com/flxrs/dankchat/data/notification/NotificationService.kt b/app/src/main/kotlin/com/flxrs/dankchat/data/notification/NotificationService.kt index f46cfc446..2aa96d5ce 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/data/notification/NotificationService.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/data/notification/NotificationService.kt @@ -104,12 +104,12 @@ class NotificationService : AppLifecycle.Background -> { combine( chatNotificationRepository.messageUpdates, - notificationsSettingsDataStore.showNotifications, - ) { items, enabled -> items to enabled } + notificationsSettingsDataStore.settings, + ) { items, settings -> items to settings } } } - }.collect { (items, enabled) -> - if (!enabled) { + }.collect { (items, settings) -> + if (!settings.showNotifications) { return@collect } @@ -122,7 +122,11 @@ class NotificationService : iterator.next() iterator.remove() } - message.toNotificationData()?.createMentionNotification() + val notificationData = message.toNotificationData() ?: return@forEach + if (!notificationData.isWhisper && !settings.areChannelNotificationsEnabled(notificationData.channel)) { + return@forEach + } + notificationData.createMentionNotification() } } } diff --git a/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettings.kt b/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettings.kt index 3c8e0b158..32c44daaf 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettings.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettings.kt @@ -1,5 +1,6 @@ package com.flxrs.dankchat.preferences.notifications +import com.flxrs.dankchat.data.UserName import kotlinx.serialization.Serializable @Serializable @@ -7,7 +8,24 @@ data class NotificationsSettings( val showNotifications: Boolean = true, val showWhisperNotifications: Boolean = true, val mentionFormat: MentionFormat = MentionFormat.Name, -) + val mutedChannels: Set = emptySet(), +) { + fun areChannelNotificationsEnabled(channel: UserName): Boolean = channel.lowercase() !in mutedChannels + + fun withChannelNotificationsEnabled( + channel: UserName, + enabled: Boolean, + ): NotificationsSettings { + val normalizedChannel = channel.lowercase() + return copy( + mutedChannels = + when { + enabled -> mutedChannels - normalizedChannel + else -> mutedChannels + normalizedChannel + }, + ) + } +} enum class MentionFormat( val template: String, diff --git a/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsDataStore.kt b/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsDataStore.kt index f9078636d..9f4825128 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsDataStore.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsDataStore.kt @@ -2,6 +2,7 @@ package com.flxrs.dankchat.preferences.notifications import android.content.Context import com.flxrs.dankchat.R +import com.flxrs.dankchat.data.UserName import com.flxrs.dankchat.di.DispatchersProvider import com.flxrs.dankchat.utils.datastore.PreferenceKeys import com.flxrs.dankchat.utils.datastore.booleanOrDefault @@ -78,6 +79,13 @@ class NotificationsSettingsDataStore( fun current() = currentSettings.value + suspend fun setChannelNotificationsEnabled( + channel: UserName, + enabled: Boolean, + ) { + update { it.withChannelNotificationsEnabled(channel, enabled) } + } + suspend fun update(transform: suspend (NotificationsSettings) -> NotificationsSettings) { runCatching { dataStore.updateData(transform) } } diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/FloatingToolbar.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/FloatingToolbar.kt index 7f2fd0e0f..26b9bb2e4 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/FloatingToolbar.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/FloatingToolbar.kt @@ -143,6 +143,7 @@ fun FloatingToolbar( totalMentionCount: Int, hasActivePinnedMessage: Boolean, isPinnedMessageShown: Boolean, + channelNotificationsEnabled: Boolean, onAction: (ToolbarAction) -> Unit, onAudioOnly: () -> Unit, onStreamClose: () -> Unit, @@ -879,6 +880,7 @@ fun FloatingToolbar( ) { InlineOverflowMenu( isLoggedIn = isLoggedIn, + channelNotificationsEnabled = channelNotificationsEnabled, onDismiss = { showOverflowMenu = false overflowInitialMenu = AppBarMenu.Main diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainAppBar.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainAppBar.kt index 2588f3378..966724ca9 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainAppBar.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainAppBar.kt @@ -40,11 +40,13 @@ import androidx.compose.material.icons.filled.EmojiEmotions import androidx.compose.material.icons.filled.Flag import androidx.compose.material.icons.filled.Image import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Notifications import androidx.compose.material.icons.filled.OpenInBrowser import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.RemoveCircleOutline import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Videocam +import androidx.compose.material3.Checkbox import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -145,6 +147,7 @@ internal data class CollapsedToolbarAction( @Composable internal fun InlineOverflowMenu( isLoggedIn: Boolean, + channelNotificationsEnabled: Boolean, onDismiss: () -> Unit, onAction: (ToolbarAction) -> Unit, initialMenu: AppBarMenu = AppBarMenu.Main, @@ -244,6 +247,7 @@ internal fun InlineOverflowMenu( AppBarMenu.Channel -> ChannelMenuContent( isLoggedIn = isLoggedIn, + notificationsEnabled = channelNotificationsEnabled, onAction = onAction, onDismiss = onDismiss, onBack = { currentMenu = AppBarMenu.Main }, @@ -283,6 +287,7 @@ private fun InlineMenuItem( modifier: Modifier = Modifier, maxLines: Int = 1, hasSubMenu: Boolean = false, + checked: Boolean? = null, ) { val registry = LocalInlineMenuItemRegistry.current val isPressed = registry?.pressedKey == text @@ -326,6 +331,12 @@ private fun InlineMenuItem( modifier = Modifier.size(20.dp), ) } + if (checked != null) { + Checkbox( + checked = checked, + onCheckedChange = null, + ) + } } } @@ -513,12 +524,21 @@ private fun ColumnScope.UploadMenuContent( @Composable private fun ColumnScope.ChannelMenuContent( isLoggedIn: Boolean, + notificationsEnabled: Boolean, onAction: (ToolbarAction) -> Unit, onDismiss: () -> Unit, onBack: () -> Unit, modifier: Modifier = Modifier, ) { InlineSubMenuHeader(title = stringResource(R.string.channel), onBack = onBack) + InlineMenuItem( + text = stringResource(R.string.channel_background_notifications), + icon = Icons.Default.Notifications, + onClick = { onAction(ToolbarAction.ToggleChannelNotifications) }, + modifier = modifier, + maxLines = 2, + checked = notificationsEnabled, + ) InlineMenuItem( text = stringResource(R.string.open_channel), icon = Icons.Default.OpenInBrowser, @@ -526,7 +546,6 @@ private fun ColumnScope.ChannelMenuContent( onAction(ToolbarAction.OpenChannel) onDismiss() }, - modifier = modifier, maxLines = 2, ) InlineMenuItem( diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainScreen.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainScreen.kt index a0bd2f3c1..426093b57 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainScreen.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/MainScreen.kt @@ -293,6 +293,7 @@ fun MainScreen( val tabState = channelTabViewModel.uiState.collectAsStateWithLifecycle().value val activeChannel = tabState.tabs.getOrNull(tabState.selectedIndex)?.channel + val channelNotificationsEnabled by channelManagementViewModel.activeChannelNotificationsEnabled.collectAsStateWithLifecycle() // The theater chat shows the streamed channel, so the input has to target it as well SideEffect(theaterStream, activeChannel) { @@ -688,6 +689,10 @@ fun MainScreen( dialogViewModel.showBlockChannel() } + ToolbarAction.ToggleChannelNotifications -> { + activeChannel?.let { channelManagementViewModel.toggleChannelNotifications(it) } + } + ToolbarAction.CaptureImage -> { if (preferenceStore.hasExternalHostingAcknowledged) onCaptureImage() else dialogViewModel.setPendingUploadAction(onCaptureImage) } @@ -733,6 +738,7 @@ fun MainScreen( totalMentionCount = tabState.tabs.sumOf { it.mentionCount } + tabState.whisperMentionCount, hasActivePinnedMessage = activePinnedMessageState != PinnedMessageUiState.Hidden, isPinnedMessageShown = activePinnedMessageState is PinnedMessageUiState.Expanded, + channelNotificationsEnabled = channelNotificationsEnabled, onAction = handleToolbarAction, onAudioOnly = { streamViewModel.toggleAudioOnly() }, onStreamClose = { streamViewModel.closeStream() }, diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/ToolbarAction.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/ToolbarAction.kt index 10021cd0d..86a73f09b 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/ToolbarAction.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/ToolbarAction.kt @@ -30,6 +30,8 @@ sealed interface ToolbarAction { data object BlockChannel : ToolbarAction + data object ToggleChannelNotifications : ToolbarAction + data object CaptureImage : ToolbarAction data object CaptureVideo : ToolbarAction diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/channel/ChannelManagementViewModel.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/channel/ChannelManagementViewModel.kt index f34c3c59f..9479c7168 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/channel/ChannelManagementViewModel.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/channel/ChannelManagementViewModel.kt @@ -13,11 +13,16 @@ import com.flxrs.dankchat.data.repo.chat.ChatRepository import com.flxrs.dankchat.domain.ChannelDataCoordinator import com.flxrs.dankchat.preferences.DankChatPreferenceStore import com.flxrs.dankchat.preferences.model.ChannelWithRename +import com.flxrs.dankchat.preferences.notifications.NotificationsSettingsDataStore import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -33,6 +38,7 @@ class ChannelManagementViewModel( private val chatNotificationRepository: ChatNotificationRepository, private val ignoresRepository: IgnoresRepository, private val channelRepository: ChannelRepository, + private val notificationsSettingsDataStore: NotificationsSettingsDataStore, channelSelectionDataStore: ChannelSelectionDataStore, ) : ViewModel() { val channels: StateFlow> = @@ -41,6 +47,19 @@ class ChannelManagementViewModel( .map { it.toImmutableList() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), persistentListOf()) + val mutedNotificationChannels: StateFlow> = + combine(channels, notificationsSettingsDataStore.settings) { channels, settings -> + channels + .map { it.channel } + .filterNot { settings.areChannelNotificationsEnabled(it) } + .toImmutableSet() + }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), persistentSetOf()) + + val activeChannelNotificationsEnabled: StateFlow = + combine(chatChannelProvider.activeChannel, notificationsSettingsDataStore.settings) { channel, settings -> + channel == null || settings.areChannelNotificationsEnabled(channel) + }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), true) + init { // Restore persisted channel selection, falling back to first channel viewModelScope.launch { @@ -122,6 +141,21 @@ class ChannelManagementViewModel( chatConnector.reconnect() } + fun setChannelNotificationsEnabled( + channel: UserName, + enabled: Boolean, + ) { + viewModelScope.launch { + notificationsSettingsDataStore.setChannelNotificationsEnabled(channel, enabled) + } + } + + fun toggleChannelNotifications(channel: UserName) { + viewModelScope.launch { + notificationsSettingsDataStore.update { it.withChannelNotificationsEnabled(channel, !it.areChannelNotificationsEnabled(channel)) } + } + } + fun blockChannel(channel: UserName) = viewModelScope.launch { runCatching { if (!preferenceStore.isLoggedIn) { diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/MainScreenDialogs.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/MainScreenDialogs.kt index 4507a5a52..8535d9df7 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/MainScreenDialogs.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/MainScreenDialogs.kt @@ -106,10 +106,13 @@ fun MainScreenDialogs( if (dialogState.showManageChannels) { val channels by channelManagementViewModel.channels.collectAsStateWithLifecycle() + val mutedNotificationChannels by channelManagementViewModel.mutedNotificationChannels.collectAsStateWithLifecycle() ManageChannelsDialog( channels = channels, + mutedNotificationChannels = mutedNotificationChannels, onApplyChanges = channelManagementViewModel::applyChanges, onChannelSelect = channelManagementViewModel::selectChannel, + onChannelNotificationsChange = channelManagementViewModel::setChannelNotificationsEnabled, onDismiss = dialogViewModel::dismissManageChannels, ) } diff --git a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/ManageChannelsDialog.kt b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/ManageChannelsDialog.kt index c26e9b575..214008743 100644 --- a/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/ManageChannelsDialog.kt +++ b/app/src/main/kotlin/com/flxrs/dankchat/ui/main/dialog/ManageChannelsDialog.kt @@ -29,6 +29,8 @@ import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.OpenInNew +import androidx.compose.material.icons.filled.Notifications +import androidx.compose.material.icons.filled.NotificationsOff import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api @@ -77,8 +79,10 @@ import sh.calvin.reorderable.rememberReorderableLazyListState @Composable fun ManageChannelsDialog( channels: List, + mutedNotificationChannels: Set, onApplyChanges: (List) -> Unit, onChannelSelect: (UserName) -> Unit, + onChannelNotificationsChange: (UserName, Boolean) -> Unit, onDismiss: () -> Unit, ) { var channelToDelete by remember { mutableStateOf(null) } @@ -149,6 +153,7 @@ fun ManageChannelsDialog( ChannelItem( channelWithRename = channelWithRename, isEditing = editingChannel == channelWithRename.channel, + notificationsEnabled = channelWithRename.channel !in mutedNotificationChannels, modifier = Modifier.longPressDraggableHandle( onDragStarted = { /* Optional haptic feedback here */ }, @@ -172,6 +177,9 @@ fun ManageChannelsDialog( editingChannel = null }, onDelete = { channelToDelete = channelWithRename.channel }, + onNotificationsChange = { enabled -> + onChannelNotificationsChange(channelWithRename.channel, enabled) + }, ) if (index < localChannels.lastIndex) { HorizontalDivider( @@ -216,10 +224,12 @@ fun ManageChannelsDialog( private fun ChannelItem( channelWithRename: ChannelWithRename, isEditing: Boolean, + notificationsEnabled: Boolean, onNavigate: () -> Unit, onEdit: () -> Unit, onRename: (String?) -> Unit, onDelete: () -> Unit, + onNotificationsChange: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { Column(modifier = modifier) { @@ -255,6 +265,24 @@ private fun ChannelItem( .padding(horizontal = 8.dp), ) + IconButton(onClick = { onNotificationsChange(!notificationsEnabled) }) { + Icon( + imageVector = + when { + notificationsEnabled -> Icons.Default.Notifications + else -> Icons.Default.NotificationsOff + }, + contentDescription = + stringResource( + when { + notificationsEnabled -> R.string.disable_channel_notifications + else -> R.string.enable_channel_notifications + }, + channelWithRename.channel.value, + ), + ) + } + IconButton(onClick = onNavigate) { Icon( imageVector = Icons.AutoMirrored.Filled.OpenInNew, diff --git a/app/src/main/res/values-b+zh+Hant+TW/strings.xml b/app/src/main/res/values-b+zh+Hant+TW/strings.xml index 4bdf57476..386193bee 100644 --- a/app/src/main/res/values-b+zh+Hant+TW/strings.xml +++ b/app/src/main/res/values-b+zh+Hant+TW/strings.xml @@ -26,6 +26,9 @@ 已封鎖此頻道 尚未新增頻道 新增頻道以開始聊天 + 為 %1$s 啟用背景通知 + 為 %1$s 停用背景通知 + 背景通知 確認登出 您確定要登出嗎? 登出? diff --git a/app/src/main/res/values-be-rBY/strings.xml b/app/src/main/res/values-be-rBY/strings.xml index 544847c27..4f1b38a6c 100644 --- a/app/src/main/res/values-be-rBY/strings.xml +++ b/app/src/main/res/values-be-rBY/strings.xml @@ -26,6 +26,9 @@ Канал заблакіраваны Няма дададзеных каналаў Дадайце канал, каб пачаць размову + Уключыць фонавыя апавяшчэнні для %1$s + Адключыць фонавыя апавяшчэнні для %1$s + Фонавыя апавяшчэнні Пацверджанне выхаду Вы ўпэўнены, што хочаце выйсці? Выйсці? diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index e08589e73..de2aa63e8 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -26,6 +26,9 @@ Canal bloquejat Cap canal afegit Afegeix un canal per començar a xatejar + Activa les notificacions en segon pla per a %1$s + Desactiva les notificacions en segon pla per a %1$s + Notificacions en segon pla Confirma tancar la sessió Estàs segur que vols tancar la sessió? Tancar sessió? diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 0be15426a..ab581a779 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -26,6 +26,9 @@ Kanál byl zablokován Žádné kanály nebyly přidány Přidejte kanál a začněte chatovat + Zapnout upozornění na pozadí pro %1$s + Vypnout upozornění na pozadí pro %1$s + Upozornění na pozadí Potvrdit odhlášení Jste si jistí, že se chcete odhlásit? Odhlásit se? diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 25b0ab1c7..5f643bfb4 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -26,6 +26,9 @@ Kanal blockiert Keine Kanäle hinzugefügt Füge einen Kanal hinzu, um zu chatten + Hintergrund-Benachrichtigungen für %1$s aktivieren + Hintergrund-Benachrichtigungen für %1$s deaktivieren + Hintergrund-Benachrichtigungen Abmeldung bestätigen Willst du dich wirklich abmelden? Abmelden? diff --git a/app/src/main/res/values-en-rAU/strings.xml b/app/src/main/res/values-en-rAU/strings.xml index 9d0a44538..447125f57 100644 --- a/app/src/main/res/values-en-rAU/strings.xml +++ b/app/src/main/res/values-en-rAU/strings.xml @@ -26,6 +26,9 @@ Channel blocked No channels added Add a channel to start chatting + Enable background notifications for %1$s + Disable background notifications for %1$s + Background notifications Confirm logout Are you sure you want to logout? Log out? diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 5d786f8bc..0fdd772e1 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -26,6 +26,9 @@ Channel blocked No channels added Add a channel to start chatting + Enable background notifications for %1$s + Disable background notifications for %1$s + Background notifications Confirm logout Are you sure you want to logout? Log out? diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index c903427d4..82344f9bb 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -26,6 +26,9 @@ Channel blocked No channels added Add a channel to start chatting + Enable background notifications for %1$s + Disable background notifications for %1$s + Background notifications Confirm logout Are you sure you want to logout? Log out? diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index ecb3369af..41744190f 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -26,6 +26,9 @@ Canal bloqueado No hay canales agregados Añade un canal para empezar a chatear + Activar notificaciones en segundo plano para %1$s + Desactivar notificaciones en segundo plano para %1$s + Notificaciones en segundo plano Confirmar cierre de sesión ¿Estás seguro de que quieres cerrar sesión? ¿Cerrar sesión? diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index 8f1294252..3f0f2f6eb 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -26,6 +26,9 @@ Kanava estetty Kanavia ei lisätty Lisää kanava aloittaaksesi keskustelun + Ota taustailmoitukset käyttöön kanavalle %1$s + Poista taustailmoitukset käytöstä kanavalta %1$s + Taustailmoitukset Vahvista uloskirjautuminen Haluatko varmasti kirjautua ulos? Kirjaudutaanko ulos? diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index ba6978f6e..3fae3d8e0 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -26,6 +26,9 @@ Chaîne bloquée Aucune chaîne ajoutée Ajoutez une chaîne pour commencer à discuter + Activer les notifications en arrière-plan pour %1$s + Désactiver les notifications en arrière-plan pour %1$s + Notifications en arrière-plan Confirmer la déconnexion Êtes-vous sûr de vouloir vous déconnecter ? Se déconnecter ? diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index 139203c96..bc8419b06 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -26,6 +26,9 @@ Csatorna letiltva Nincsenek csatornák hozzáadva Adj hozzá egy csatornát a csevegéshez + Háttérértesítések bekapcsolása: %1$s + Háttérértesítések kikapcsolása: %1$s + Háttérértesítések Kijelentkezés megerősítése Biztos ki akarsz jelentkezni? Kijelentkezés? diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 504183ae1..a866c52b9 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -26,6 +26,9 @@ Canale bloccato Nessun canale aggiunto Aggiungi un canale per iniziare a chattare + Attiva le notifiche in background per %1$s + Disattiva le notifiche in background per %1$s + Notifiche in background Conferma la disconnessione Sei sicuro di volerti disconnettere? Disconnettersi? diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 697a866f7..af95c8f9d 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -26,6 +26,9 @@ チャンネルをブロックしました チャンネルが追加されていません チャンネルを追加してチャットを始めましょう + %1$s のバックグラウンド通知を有効にする + %1$s のバックグラウンド通知を無効にする + バックグラウンド通知 ログアウトを確認 ログアウトしてもよろしいですか? ログアウトしますか? diff --git a/app/src/main/res/values-kk-rKZ/strings.xml b/app/src/main/res/values-kk-rKZ/strings.xml index 7a05063c2..24032af0e 100644 --- a/app/src/main/res/values-kk-rKZ/strings.xml +++ b/app/src/main/res/values-kk-rKZ/strings.xml @@ -26,6 +26,9 @@ Арна бұғатталды Қосылған арналар жоқ Сөйлесуді бастау үшін арна қосыңыз + %1$s үшін фондық хабарландыруларды қосу + %1$s үшін фондық хабарландыруларды өшіру + Фондық хабарландырулар Шығуды растау Шынымен шыққыңыз келе ме? Шығасыз ба? diff --git a/app/src/main/res/values-or-rIN/strings.xml b/app/src/main/res/values-or-rIN/strings.xml index 264d8e417..1956a1468 100644 --- a/app/src/main/res/values-or-rIN/strings.xml +++ b/app/src/main/res/values-or-rIN/strings.xml @@ -21,6 +21,9 @@ ଚ୍ୟାନେଲକୁ ହଟାନ୍ତୁ ଚ୍ୟାନେଲ ଅବରୋଧିତ ଚାଟିଂ ଆରମ୍ଭ କରିବାକୁ ଏକ ଚ୍ୟାନେଲ ଯୋଡନ୍ତୁ + %1$s ପାଇଁ ପୃଷ୍ଠଭୂମି ବିଜ୍ଞପ୍ତି ସକ୍ଷମ କରନ୍ତୁ + %1$s ପାଇଁ ପୃଷ୍ଠଭୂମି ବିଜ୍ଞପ୍ତି ଅକ୍ଷମ କରନ୍ତୁ + ପୃଷ୍ଠଭୂମି ବିଜ୍ଞପ୍ତି ଲଗଆଉଟ୍ ନିଶ୍ଚିତ କରନ୍ତୁ ଆପଣ ନିଶ୍ଚିତ କି ଆପଣ ଲଗଆଉଟ୍ କରିବାକୁ ଚାହୁଁଛନ୍ତି? ଲଗଆଉଟ୍ କରିବେ? diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index adae6cc34..c424b09a0 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -26,6 +26,9 @@ Zablokowano kanał Brak kanałów Dodaj kanał, aby zacząć czatować + Włącz powiadomienia w tle dla %1$s + Wyłącz powiadomienia w tle dla %1$s + Powiadomienia w tle Potwierdź wylogowanie Czy na pewno chcesz się wylogować? Wylogować się? diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 65e2ab1a2..672425cf8 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -26,6 +26,9 @@ Canal bloqueado Nenhum canal adicionado Adicione um canal para começar a conversar + Ativar notificações em segundo plano para %1$s + Desativar notificações em segundo plano para %1$s + Notificações em segundo plano Confirmar término da sessão Tem certeza que quer terminar a sessão? Sair? diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index bd0334c09..3ebc8e8f6 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -26,6 +26,9 @@ Canal bloqueado Sem canais adicionados Adicione um canal para começar a conversar + Ativar notificações em segundo plano para %1$s + Desativar notificações em segundo plano para %1$s + Notificações em segundo plano Confirmar encerramento de sessão Tens a certeza de que desejas terminar a sessão? Terminar sessão? diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 89f28350a..0e40b564a 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -26,6 +26,9 @@ Канал заблокирован Нет добавленных каналов Добавьте канал, чтобы начать общение + Включить фоновые уведомления для %1$s + Отключить фоновые уведомления для %1$s + Фоновые уведомления Подтверждение выхода Вы уверены, что хотите выйти? Выйти? diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 9c6c4ab73..3812a8752 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -21,6 +21,9 @@ Otvori kanal Nijedan kanal nije dodat Додајте канал да бисте почели да ћаскате + Укључи обавештења у позадини за %1$s + Искључи обавештења у позадини за %1$s + Обавештења у позадини Potvrdi odjavu Da li ste sigurni da želite da se odjavite? Odjaviti se? diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index c882b286f..f82d02cda 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -26,6 +26,9 @@ Kanal engellendi Eklenmiş kanal yok Sohbete başlamak için bir kanal ekleyin + %1$s için arka plan bildirimlerini aç + %1$s için arka plan bildirimlerini kapat + Arka plan bildirimleri Çıkışı onayla Çıkış yapmak istediğinize emin misiniz? Çıkış yapılsın mı? diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 8cd2330ca..72236c30a 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -26,6 +26,9 @@ Канал заблоковано Немає доданих каналів Додайте канал, щоб почати спілкування + Увімкнути фонові сповіщення для %1$s + Вимкнути фонові сповіщення для %1$s + Фонові сповіщення Підтвердити вихід Ви дійсно хочете вийти? Вийти? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 343197031..4db7b0dc4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -26,6 +26,9 @@ Channel blocked No channels added Add a channel to start chatting + Enable background notifications for %1$s + Disable background notifications for %1$s + Background notifications Confirm logout Are you sure you want to logout? Log out? diff --git a/app/src/test/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsTest.kt b/app/src/test/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsTest.kt new file mode 100644 index 000000000..1a439a099 --- /dev/null +++ b/app/src/test/kotlin/com/flxrs/dankchat/preferences/notifications/NotificationsSettingsTest.kt @@ -0,0 +1,19 @@ +package com.flxrs.dankchat.preferences.notifications + +import com.flxrs.dankchat.data.toUserName +import org.junit.jupiter.api.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +internal class NotificationsSettingsTest { + @Test + fun `channel notifications can be disabled and enabled`() { + val disabled = NotificationsSettings().withChannelNotificationsEnabled("forsen".toUserName(), enabled = false) + + assertFalse(disabled.areChannelNotificationsEnabled("forsen".toUserName())) + assertTrue(disabled.areChannelNotificationsEnabled("iore".toUserName())) + + val enabled = disabled.withChannelNotificationsEnabled("forsen".toUserName(), enabled = true) + assertTrue(enabled.areChannelNotificationsEnabled("forsen".toUserName())) + } +}