Merge branch 'develop' into julioromano/poll_history_entry_point

This commit is contained in:
Benoit Marty 2023-12-14 17:34:49 +01:00 committed by GitHub
commit 4d3c6632cd
54 changed files with 220 additions and 153 deletions

1
changelog.d/1749.misc Normal file
View file

@ -0,0 +1 @@
Add a warning for 'mentions and keywords only' notification option if your homeserver does not support it

1
changelog.d/2031.misc Normal file
View file

@ -0,0 +1 @@
Only process content.json from Localazy.

View file

@ -16,67 +16,43 @@
package io.element.android.features.preferences.impl.notifications.edit package io.element.android.features.preferences.impl.notifications.edit
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.selectable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import io.element.android.features.preferences.impl.R import io.element.android.features.preferences.impl.R
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.theme.components.RadioButton
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.theme.components.ListItem
@Composable @Composable
fun DefaultNotificationSettingOption( fun DefaultNotificationSettingOption(
mode: RoomNotificationMode, mode: RoomNotificationMode,
onOptionSelected: (RoomNotificationMode) -> Unit, onOptionSelected: (RoomNotificationMode) -> Unit,
displayMentionsOnlyDisclaimer: Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
isSelected: Boolean = false, isSelected: Boolean = false,
) { ) {
val subtitle = when(mode) { val title = when (mode) {
RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_notification_settings_edit_mode_all_messages) RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_notification_settings_edit_mode_all_messages)
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> stringResource(id = R.string.screen_notification_settings_edit_mode_mentions_and_keywords) RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> stringResource(id = R.string.screen_notification_settings_edit_mode_mentions_and_keywords)
else -> "" else -> ""
} }
Row( val subtitle = when {
modifier mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY && displayMentionsOnlyDisclaimer -> {
.fillMaxWidth() stringResource(id = R.string.screen_notification_settings_mentions_only_disclaimer)
.selectable(
selected = isSelected,
onClick = { onOptionSelected(mode) },
role = Role.RadioButton,
)
.padding(8.dp),
) {
Column(
Modifier
.weight(1f)
.padding(horizontal = 8.dp)
.align(Alignment.CenterVertically)
) {
Text(
text = subtitle,
style = ElementTheme.typography.fontBodyLgRegular,
)
} }
else -> null
RadioButton(
modifier = Modifier
.align(Alignment.CenterVertically)
.size(48.dp),
selected = isSelected,
onClick = null // null recommended for accessibility with screenreaders
)
} }
ListItem(
modifier = modifier,
headlineContent = { Text(title) },
supportingContent = subtitle?.let { { Text(it) } },
trailingContent = ListItemContent.RadioButton(selected = isSelected),
onClick = { onOptionSelected(mode) },
)
} }
@PreviewsDayNight @PreviewsDayNight
@ -86,11 +62,19 @@ internal fun DefaultNotificationSettingOptionPreview() = ElementPreview {
DefaultNotificationSettingOption( DefaultNotificationSettingOption(
mode = RoomNotificationMode.ALL_MESSAGES, mode = RoomNotificationMode.ALL_MESSAGES,
isSelected = true, isSelected = true,
displayMentionsOnlyDisclaimer = false,
onOptionSelected = {}, onOptionSelected = {},
) )
DefaultNotificationSettingOption( DefaultNotificationSettingOption(
mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
isSelected = false, isSelected = false,
displayMentionsOnlyDisclaimer = false,
onOptionSelected = {},
)
DefaultNotificationSettingOption(
mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
isSelected = false,
displayMentionsOnlyDisclaimer = true,
onOptionSelected = {}, onOptionSelected = {},
) )
} }

View file

@ -19,9 +19,11 @@ package io.element.android.features.preferences.impl.notifications.edit
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
@ -55,6 +57,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
} }
@Composable @Composable
override fun present(): EditDefaultNotificationSettingState { override fun present(): EditDefaultNotificationSettingState {
var displayMentionsOnlyDisclaimer by remember { mutableStateOf(false) }
val mode: MutableState<RoomNotificationMode?> = remember { val mode: MutableState<RoomNotificationMode?> = remember {
mutableStateOf(null) mutableStateOf(null)
@ -71,6 +74,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
fetchSettings(mode) fetchSettings(mode)
observeNotificationSettings(mode) observeNotificationSettings(mode)
observeRoomSummaries(roomsWithUserDefinedMode) observeRoomSummaries(roomsWithUserDefinedMode)
displayMentionsOnlyDisclaimer = !notificationSettingsService.canHomeServerPushEncryptedEventsToDevice().getOrDefault(true)
} }
fun handleEvents(event: EditDefaultNotificationSettingStateEvents) { fun handleEvents(event: EditDefaultNotificationSettingStateEvents) {
@ -87,6 +91,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
mode = mode.value, mode = mode.value,
roomsWithUserDefinedMode = roomsWithUserDefinedMode.value.toImmutableList(), roomsWithUserDefinedMode = roomsWithUserDefinedMode.value.toImmutableList(),
changeNotificationSettingAction = changeNotificationSettingAction.value, changeNotificationSettingAction = changeNotificationSettingAction.value,
displayMentionsOnlyDisclaimer = displayMentionsOnlyDisclaimer,
eventSink = ::handleEvents eventSink = ::handleEvents
) )
} }

View file

@ -26,5 +26,6 @@ data class EditDefaultNotificationSettingState(
val mode: RoomNotificationMode?, val mode: RoomNotificationMode?,
val roomsWithUserDefinedMode: ImmutableList<RoomSummary.Filled>, val roomsWithUserDefinedMode: ImmutableList<RoomSummary.Filled>,
val changeNotificationSettingAction: Async<Unit>, val changeNotificationSettingAction: Async<Unit>,
val displayMentionsOnlyDisclaimer: Boolean,
val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit, val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit,
) )

View file

@ -31,17 +31,20 @@ open class EditDefaultNotificationSettingStateProvider: PreviewParameterProvider
anEditDefaultNotificationSettingsState(isOneToOne = true), anEditDefaultNotificationSettingsState(isOneToOne = true),
anEditDefaultNotificationSettingsState(changeNotificationSettingAction = Async.Loading(Unit)), anEditDefaultNotificationSettingsState(changeNotificationSettingAction = Async.Loading(Unit)),
anEditDefaultNotificationSettingsState(changeNotificationSettingAction = Async.Failure(Throwable("error"))), anEditDefaultNotificationSettingsState(changeNotificationSettingAction = Async.Failure(Throwable("error"))),
anEditDefaultNotificationSettingsState(displayMentionsOnlyDisclaimer = true),
) )
} }
private fun anEditDefaultNotificationSettingsState( private fun anEditDefaultNotificationSettingsState(
isOneToOne: Boolean = false, isOneToOne: Boolean = false,
changeNotificationSettingAction: Async<Unit> = Async.Uninitialized changeNotificationSettingAction: Async<Unit> = Async.Uninitialized,
displayMentionsOnlyDisclaimer: Boolean = false,
) = EditDefaultNotificationSettingState( ) = EditDefaultNotificationSettingState(
isOneToOne = isOneToOne, isOneToOne = isOneToOne,
mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
roomsWithUserDefinedMode = persistentListOf(aRoomSummary()), roomsWithUserDefinedMode = persistentListOf(aRoomSummary()),
changeNotificationSettingAction = changeNotificationSettingAction, changeNotificationSettingAction = changeNotificationSettingAction,
displayMentionsOnlyDisclaimer = displayMentionsOnlyDisclaimer,
eventSink = {} eventSink = {}
) )

View file

@ -76,6 +76,7 @@ fun EditDefaultNotificationSettingView(
DefaultNotificationSettingOption( DefaultNotificationSettingOption(
mode = item, mode = item,
isSelected = state.mode == item, isSelected = state.mode == item,
displayMentionsOnlyDisclaimer = state.displayMentionsOnlyDisclaimer,
onOptionSelected = { state.eventSink(EditDefaultNotificationSettingStateEvents.SetNotificationMode(it)) } onOptionSelected = { state.eventSink(EditDefaultNotificationSettingStateEvents.SetNotificationMode(it)) }
) )
} }

View file

@ -31,6 +31,7 @@ import io.element.android.libraries.matrix.test.notificationsettings.FakeNotific
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetail import io.element.android.libraries.matrix.test.room.aRoomSummaryDetail
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.tests.testutils.awaitLastSequentialItem
import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilPredicate
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
@ -51,6 +52,8 @@ class EditDefaultNotificationSettingsPresenterTests {
it.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY it.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
}.last() }.last()
assertThat(loadedState.mode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) assertThat(loadedState.mode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
assertThat(loadedState.displayMentionsOnlyDisclaimer).isFalse()
} }
} }
@ -112,6 +115,19 @@ class EditDefaultNotificationSettingsPresenterTests {
} }
} }
@Test
fun `present - display mentions only warning if homeserver does not support it`() = runTest {
val notificationSettingsService = FakeNotificationSettingsService().apply {
givenCanHomeServerPushEncryptedEventsToDeviceResult(Result.success(false))
}
val presenter = createEditDefaultNotificationSettingPresenter(notificationSettingsService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
assertThat(awaitLastSequentialItem().displayMentionsOnlyDisclaimer).isTrue()
}
}
private fun createEditDefaultNotificationSettingPresenter( private fun createEditDefaultNotificationSettingPresenter(
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
roomListService: FakeRoomListService = FakeRoomListService(), roomListService: FakeRoomListService = FakeRoomListService(),

View file

@ -31,7 +31,7 @@ data class RoomNotificationSettingsItem(
@Composable @Composable
fun roomNotificationSettingsItems(): ImmutableList<RoomNotificationSettingsItem> { fun roomNotificationSettingsItems(): ImmutableList<RoomNotificationSettingsItem> {
return RoomNotificationMode.values() return RoomNotificationMode.entries
.map { .map {
when (it) { when (it) {
RoomNotificationMode.ALL_MESSAGES -> RoomNotificationSettingsItem( RoomNotificationMode.ALL_MESSAGES -> RoomNotificationSettingsItem(

View file

@ -17,80 +17,56 @@
package io.element.android.features.roomdetails.impl.notificationsettings package io.element.android.features.roomdetails.impl.notificationsettings
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.selectable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import io.element.android.features.roomdetails.impl.R
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.theme.components.RadioButton import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.toEnabledColor import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.compound.theme.ElementTheme
@Composable @Composable
fun RoomNotificationSettingsOption( fun RoomNotificationSettingsOption(
roomNotificationSettingsItem: RoomNotificationSettingsItem, roomNotificationSettingsItem: RoomNotificationSettingsItem,
onOptionSelected: (RoomNotificationSettingsItem) -> Unit, onOptionSelected: (RoomNotificationSettingsItem) -> Unit,
displayMentionsOnlyDisclaimer: Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true, enabled: Boolean = true,
isSelected: Boolean = false, isSelected: Boolean = false,
) { ) {
Row( val mode = roomNotificationSettingsItem.mode
modifier val title = roomNotificationSettingsItem.title
.fillMaxWidth() val subtitle = when {
.selectable( mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY && displayMentionsOnlyDisclaimer -> {
selected = isSelected, stringResource(id = R.string.screen_notification_settings_mentions_only_disclaimer)
enabled = enabled,
onClick = { onOptionSelected(roomNotificationSettingsItem) },
role = Role.RadioButton,
)
.padding(8.dp),
) {
Column(
Modifier
.weight(1f)
.padding(horizontal = 8.dp)
.align(Alignment.CenterVertically)
) {
Text(
text = roomNotificationSettingsItem.title,
style = ElementTheme.typography.fontBodyLgRegular,
color = enabled.toEnabledColor(),
)
} }
else -> null
RadioButton(
modifier = Modifier
.align(Alignment.CenterVertically)
.size(48.dp),
selected = isSelected,
enabled = enabled,
onClick = null // null recommended for accessibility with screenreaders
)
} }
ListItem(
modifier = modifier,
enabled = enabled,
headlineContent = { Text(title) },
supportingContent = subtitle?.let { { Text(it) } },
trailingContent = ListItemContent.RadioButton(selected = isSelected),
onClick = { onOptionSelected(roomNotificationSettingsItem) },
)
} }
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun RoomPrivacyOptionPreview() = ElementPreview { internal fun RoomPrivacyOptionPreview() = ElementPreview {
Column { Column {
RoomNotificationSettingsOption( for ((index, item) in roomNotificationSettingsItems().withIndex()) {
roomNotificationSettingsItem = roomNotificationSettingsItems().first(), RoomNotificationSettingsOption(
onOptionSelected = {}, roomNotificationSettingsItem = item,
isSelected = true, onOptionSelected = {},
) isSelected = index == 0,
RoomNotificationSettingsOption( enabled = index != 2,
roomNotificationSettingsItem = roomNotificationSettingsItems().last(), displayMentionsOnlyDisclaimer = index == 1,
onOptionSelected = {}, )
isSelected = false, }
enabled = false,
)
} }
} }

View file

@ -27,6 +27,7 @@ fun RoomNotificationSettingsOptions(
selected: RoomNotificationMode?, selected: RoomNotificationMode?,
enabled: Boolean, enabled: Boolean,
onOptionSelected: (RoomNotificationSettingsItem) -> Unit, onOptionSelected: (RoomNotificationSettingsItem) -> Unit,
displayMentionsOnlyDisclaimer: Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val items = roomNotificationSettingsItems() val items = roomNotificationSettingsItems()
@ -36,6 +37,7 @@ fun RoomNotificationSettingsOptions(
roomNotificationSettingsItem = item, roomNotificationSettingsItem = item,
isSelected = selected == item.mode, isSelected = selected == item.mode,
onOptionSelected = onOptionSelected, onOptionSelected = onOptionSelected,
displayMentionsOnlyDisclaimer = displayMentionsOnlyDisclaimer,
enabled = enabled enabled = enabled
) )
} }

View file

@ -19,10 +19,12 @@ package io.element.android.features.roomdetails.impl.notificationsettings
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
@ -54,6 +56,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
@Composable @Composable
override fun present(): RoomNotificationSettingsState { override fun present(): RoomNotificationSettingsState {
var shouldDisplayMentionsOnlyDisclaimer by remember { mutableStateOf(false) }
val defaultRoomNotificationMode: MutableState<RoomNotificationMode?> = rememberSaveable { val defaultRoomNotificationMode: MutableState<RoomNotificationMode?> = rememberSaveable {
mutableStateOf(null) mutableStateOf(null)
} }
@ -87,6 +90,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
getDefaultRoomNotificationMode(defaultRoomNotificationMode) getDefaultRoomNotificationMode(defaultRoomNotificationMode)
fetchNotificationSettings(pendingRoomNotificationMode, roomNotificationSettings) fetchNotificationSettings(pendingRoomNotificationMode, roomNotificationSettings)
observeNotificationSettings(pendingRoomNotificationMode, roomNotificationSettings) observeNotificationSettings(pendingRoomNotificationMode, roomNotificationSettings)
shouldDisplayMentionsOnlyDisclaimer = room.isEncrypted && !notificationSettingsService.canHomeServerPushEncryptedEventsToDevice().getOrDefault(true)
} }
fun handleEvents(event: RoomNotificationSettingsEvents) { fun handleEvents(event: RoomNotificationSettingsEvents) {
@ -124,6 +128,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
defaultRoomNotificationMode = defaultRoomNotificationMode.value, defaultRoomNotificationMode = defaultRoomNotificationMode.value,
setNotificationSettingAction = setNotificationSettingAction.value, setNotificationSettingAction = setNotificationSettingAction.value,
restoreDefaultAction = restoreDefaultAction.value, restoreDefaultAction = restoreDefaultAction.value,
displayMentionsOnlyDisclaimer = shouldDisplayMentionsOnlyDisclaimer,
eventSink = ::handleEvents, eventSink = ::handleEvents,
) )
} }

View file

@ -29,6 +29,7 @@ data class RoomNotificationSettingsState(
val defaultRoomNotificationMode: RoomNotificationMode?, val defaultRoomNotificationMode: RoomNotificationMode?,
val setNotificationSettingAction: Async<Unit>, val setNotificationSettingAction: Async<Unit>,
val restoreDefaultAction: Async<Unit>, val restoreDefaultAction: Async<Unit>,
val displayMentionsOnlyDisclaimer: Boolean,
val eventSink: (RoomNotificationSettingsEvents) -> Unit val eventSink: (RoomNotificationSettingsEvents) -> Unit
) )

View file

@ -30,12 +30,14 @@ internal class RoomNotificationSettingsStateProvider : PreviewParameterProvider<
aRoomNotificationSettingsState(setNotificationSettingAction = Async.Failure(Throwable("error"))), aRoomNotificationSettingsState(setNotificationSettingAction = Async.Failure(Throwable("error"))),
aRoomNotificationSettingsState(restoreDefaultAction = Async.Loading(Unit)), aRoomNotificationSettingsState(restoreDefaultAction = Async.Loading(Unit)),
aRoomNotificationSettingsState(restoreDefaultAction = Async.Failure(Throwable("error"))), aRoomNotificationSettingsState(restoreDefaultAction = Async.Failure(Throwable("error"))),
aRoomNotificationSettingsState(displayMentionsOnlyDisclaimer = true)
) )
private fun aRoomNotificationSettingsState( private fun aRoomNotificationSettingsState(
isDefault: Boolean = true, isDefault: Boolean = true,
setNotificationSettingAction: Async<Unit> = Async.Uninitialized, setNotificationSettingAction: Async<Unit> = Async.Uninitialized,
restoreDefaultAction: Async<Unit> = Async.Uninitialized, restoreDefaultAction: Async<Unit> = Async.Uninitialized,
displayMentionsOnlyDisclaimer: Boolean = false,
): RoomNotificationSettingsState { ): RoomNotificationSettingsState {
return RoomNotificationSettingsState( return RoomNotificationSettingsState(
showUserDefinedSettingStyle = false, showUserDefinedSettingStyle = false,
@ -48,6 +50,7 @@ internal class RoomNotificationSettingsStateProvider : PreviewParameterProvider<
defaultRoomNotificationMode = RoomNotificationMode.ALL_MESSAGES, defaultRoomNotificationMode = RoomNotificationMode.ALL_MESSAGES,
setNotificationSettingAction = setNotificationSettingAction, setNotificationSettingAction = setNotificationSettingAction,
restoreDefaultAction = restoreDefaultAction, restoreDefaultAction = restoreDefaultAction,
displayMentionsOnlyDisclaimer = displayMentionsOnlyDisclaimer,
eventSink = { }, eventSink = { },
) )
} }

View file

@ -133,10 +133,13 @@ private fun RoomSpecificNotificationSettingsView(
} }
RoomNotificationMode.MUTE -> stringResource(id = CommonStrings.common_mute) RoomNotificationMode.MUTE -> stringResource(id = CommonStrings.common_mute)
} }
val displayMentionsOnlyDisclaimer = state.displayMentionsOnlyDisclaimer
&& state.defaultRoomNotificationMode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
RoomNotificationSettingsOption( RoomNotificationSettingsOption(
roomNotificationSettingsItem = RoomNotificationSettingsItem(state.defaultRoomNotificationMode, defaultModeTitle), roomNotificationSettingsItem = RoomNotificationSettingsItem(state.defaultRoomNotificationMode, defaultModeTitle),
isSelected = true, isSelected = true,
onOptionSelected = { }, onOptionSelected = { },
displayMentionsOnlyDisclaimer = displayMentionsOnlyDisclaimer,
enabled = true enabled = true
) )
} }
@ -146,6 +149,7 @@ private fun RoomSpecificNotificationSettingsView(
RoomNotificationSettingsOptions( RoomNotificationSettingsOptions(
selected = state.displayNotificationMode, selected = state.displayNotificationMode,
enabled = !state.displayIsDefault.orTrue(), enabled = !state.displayIsDefault.orTrue(),
displayMentionsOnlyDisclaimer = state.displayMentionsOnlyDisclaimer,
onOptionSelected = { onOptionSelected = {
state.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(it.mode)) state.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(it.mode))
}, },

View file

@ -37,6 +37,7 @@ internal class UserDefinedRoomNotificationSettingsStateProvider : PreviewParamet
defaultRoomNotificationMode = RoomNotificationMode.ALL_MESSAGES, defaultRoomNotificationMode = RoomNotificationMode.ALL_MESSAGES,
setNotificationSettingAction = Async.Uninitialized, setNotificationSettingAction = Async.Uninitialized,
restoreDefaultAction = Async.Uninitialized, restoreDefaultAction = Async.Uninitialized,
displayMentionsOnlyDisclaimer = false,
eventSink = { }, eventSink = { },
), ),
) )

View file

@ -66,6 +66,7 @@ fun UserDefinedRoomNotificationSettingsView(
RoomNotificationSettingsOptions( RoomNotificationSettingsOptions(
selected = state.displayNotificationMode, selected = state.displayNotificationMode,
enabled = !state.displayIsDefault.orTrue(), enabled = !state.displayIsDefault.orTrue(),
displayMentionsOnlyDisclaimer = state.displayMentionsOnlyDisclaimer,
onOptionSelected = { onOptionSelected = {
state.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(it.mode)) state.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(it.mode))
}, },

View file

@ -6,6 +6,7 @@
</plurals> </plurals>
<string name="screen_notification_settings_edit_failed_updating_default_mode">"An error occurred while updating the notification setting."</string> <string name="screen_notification_settings_edit_failed_updating_default_mode">"An error occurred while updating the notification setting."</string>
<string name="screen_polls_history_title">"Polls"</string> <string name="screen_polls_history_title">"Polls"</string>
<string name="screen_notification_settings_mentions_only_disclaimer">"Your homeserver does not support this option in encrypted rooms, you may not get notified in some rooms."</string>
<string name="screen_room_details_add_topic_title">"Add topic"</string> <string name="screen_room_details_add_topic_title">"Add topic"</string>
<string name="screen_room_details_already_a_member">"Already a member"</string> <string name="screen_room_details_already_a_member">"Already a member"</string>
<string name="screen_room_details_already_invited">"Already invited"</string> <string name="screen_room_details_already_invited">"Already invited"</string>

View file

@ -27,6 +27,8 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.tests.testutils.awaitLastSequentialItem
import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilPredicate
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
@ -41,6 +43,8 @@ class RoomNotificationSettingsPresenterTests {
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.roomNotificationSettings.dataOrNull()).isNull() assertThat(initialState.roomNotificationSettings.dataOrNull()).isNull()
assertThat(initialState.defaultRoomNotificationMode).isNull() assertThat(initialState.defaultRoomNotificationMode).isNull()
val loadedState = awaitItem()
assertThat(loadedState.displayMentionsOnlyDisclaimer).isFalse()
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
} }
} }
@ -159,10 +163,39 @@ class RoomNotificationSettingsPresenterTests {
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
} }
} }
@Test
fun `present - display mentions only warning for a room if homeserver does not support it and it's encrypted`() = runTest {
val notificationService = FakeNotificationSettingsService().apply {
givenCanHomeServerPushEncryptedEventsToDeviceResult(Result.success(false))
}
val room = aMatrixRoom(notificationSettingsService = notificationService, isEncrypted = true)
val presenter = createRoomNotificationSettingsPresenter(notificationService, room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
assertThat(awaitLastSequentialItem().displayMentionsOnlyDisclaimer).isTrue()
}
}
@Test
fun `present - do not display mentions only warning for a room it's not encrypted`() = runTest {
val notificationService = FakeNotificationSettingsService().apply {
givenCanHomeServerPushEncryptedEventsToDeviceResult(Result.success(false))
}
val room = aMatrixRoom(notificationSettingsService = notificationService, isEncrypted = false)
val presenter = createRoomNotificationSettingsPresenter(notificationService, room)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
assertThat(awaitLastSequentialItem().displayMentionsOnlyDisclaimer).isFalse()
}
}
private fun createRoomNotificationSettingsPresenter( private fun createRoomNotificationSettingsPresenter(
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService() notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
room: FakeMatrixRoom = aMatrixRoom(notificationSettingsService = notificationSettingsService),
): RoomNotificationSettingsPresenter{ ): RoomNotificationSettingsPresenter{
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
return RoomNotificationSettingsPresenter( return RoomNotificationSettingsPresenter(
room = room, room = room,
notificationSettingsService = notificationSettingsService, notificationSettingsService = notificationSettingsService,

View file

@ -41,4 +41,5 @@ interface NotificationSettingsService {
suspend fun isInviteForMeEnabled(): Result<Boolean> suspend fun isInviteForMeEnabled(): Result<Boolean>
suspend fun setInviteForMeEnabled(enabled: Boolean): Result<Unit> suspend fun setInviteForMeEnabled(enabled: Boolean): Result<Unit>
suspend fun getRoomsWithUserDefinedRules(): Result<List<String>> suspend fun getRoomsWithUserDefinedRules(): Result<List<String>>
suspend fun canHomeServerPushEncryptedEventsToDevice(): Result<Boolean>
} }

View file

@ -140,4 +140,9 @@ class RustNotificationSettingsService(
runCatching { runCatching {
notificationSettings.getRoomsWithUserDefinedRules(enabled = true) notificationSettings.getRoomsWithUserDefinedRules(enabled = true)
} }
override suspend fun canHomeServerPushEncryptedEventsToDevice(): Result<Boolean> =
runCatching {
notificationSettings.canHomeserverPushEncryptedEventToDevice()
}
} }

View file

@ -47,6 +47,7 @@ class FakeNotificationSettingsService(
private var restoreDefaultNotificationModeError: Throwable? = null private var restoreDefaultNotificationModeError: Throwable? = null
private var setDefaultNotificationModeError: Throwable? = null private var setDefaultNotificationModeError: Throwable? = null
private var setAtRoomError: Throwable? = null private var setAtRoomError: Throwable? = null
private var canHomeServerPushEncryptedEventsToDeviceResult = Result.success(true)
override val notificationSettingsChangeFlow: SharedFlow<Unit> override val notificationSettingsChangeFlow: SharedFlow<Unit>
get() = _notificationSettingsStateFlow get() = _notificationSettingsStateFlow
@ -163,6 +164,10 @@ class FakeNotificationSettingsService(
return Result.success(if (roomNotificationModeIsDefault) listOf() else listOf(A_ROOM_ID.value)) return Result.success(if (roomNotificationModeIsDefault) listOf() else listOf(A_ROOM_ID.value))
} }
override suspend fun canHomeServerPushEncryptedEventsToDevice(): Result<Boolean> {
return canHomeServerPushEncryptedEventsToDeviceResult
}
fun givenSetNotificationModeError(throwable: Throwable?) { fun givenSetNotificationModeError(throwable: Throwable?) {
setNotificationModeError = throwable setNotificationModeError = throwable
} }
@ -178,4 +183,8 @@ class FakeNotificationSettingsService(
fun givenSetDefaultNotificationModeError(throwable: Throwable?) { fun givenSetDefaultNotificationModeError(throwable: Throwable?) {
setDefaultNotificationModeError = throwable setDefaultNotificationModeError = throwable
} }
fun givenCanHomeServerPushEncryptedEventsToDeviceResult(result: Result<Boolean>) {
canHomeServerPushEncryptedEventsToDeviceResult = result
}
} }

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:954c763c082f8e4016247643408a61a038a221bb84643ba7e80f3389818528ba oid sha256:decba5aecbaf17385c6b92396b48ba7e8cb1d68c8319bef3334415cd42fee828
size 15587 size 36034

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:30886fbb00695077a80e046cd6c6c134375be8ecb8c3962e72fdc0dff60d7069 oid sha256:97aec529c58486f1686e6c15f0cb9ed5286ed169115d8053b734bc491f724a28
size 14194 size 33309

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d7d9e27ba7e11c0bb8ccbc79ad1a0f36bfa9dcbd32de930fe7c5daddba9fdd23 oid sha256:b927c63f95092c5345ceb35506e160c9ce6ce0348bba33d258c390cd8bd158de
size 35942 size 35825

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:15107ee39b3e1ea4d3a21b7b1abadaf8ebf2b0487073790ceefff5c02581d193 oid sha256:6886af0b4f9e674aafd2674c6b77e707a08fb4a0f626169581ed3245b4241972
size 35869 size 35751

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:a8c45197aff11763468432a96e6870c022398d26560629e7f84ea643506044f0 oid sha256:ef4a2ee8e94f57164b5834fa331c37a3bf7bee15aae17fa3c5fb2a9c82e3e3a9
size 32283 size 33508

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:9db4f92f89959facb236f9e4f8c64fae0daba27fcab8351a93511a68c2906810 oid sha256:c1acca39f67a574b9b467827515b2f3442b4bb532a6d2cf3ad611ae79098815d
size 36825 size 36659

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:78eab361860e4b4153a680fad703dc61c69c80a28af0a90b0a6add85178eea4f
size 49828

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:4d286e663c1c3969ce66304064c5e1c54bde8488b5f71076e3056d00c7fe2d1c oid sha256:99b99dd9caaecaf34f5a354251833375456c43e4c31bb2dc020b8caa396fe7e3
size 33108 size 33088

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:fd4758ac4bb9c62815b33f726f0c8e7183e0474224e9dbd9225e78793a67b1c7 oid sha256:c427f18e4dcb5539069bcb6cb2d81160208a21fa5d1ca0c4086aed27b92013e8
size 33068 size 33043

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:076fc1b1f9d0a23e639f86ca191cbc3e14603ba0f2dd1beffb5519e710247e49 oid sha256:5d3d53b374e9b59ec860951fbcd1ddb566c90b3debe335c5cba8f2d9e55f508d
size 29047 size 30346

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:be15f96a3c48b5ea7ddb30919ff5dab2afd3780fa792dda9a4b4a266d2d5c8b8 oid sha256:0c85782934a98034a75e507f9c4e8316c1aa00e5628ae7fe3092b7f58ae3540c
size 32310 size 32286

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:29160e672d2bda2cdb69b7a2c2357316696637db23dc1de0665cc80308303399
size 47051

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:99c766b057e9a18cb0126af3da9a921fc3c3f85d0c7bb7ce5bab8d3c684be640 oid sha256:695a934529456a82e99371e9b53231ac02f6d235174927fbb346bf2a5375aceb
size 33829 size 33962

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:4d79ba52e50a3bab13633c83a4196c229f8b40e10c4f00ff4469b68c5bbbdcc2 oid sha256:4e406c5e173add3b29c3ad7a10e968d3bffc4627c7895bd2080826b832652ce1
size 38018 size 37783

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:13c58f6fb3d875d31d2c72e67f859bf5b4e1496a05de36ea1dc2601fe882f7f6 oid sha256:52fe76d305e114d5eeab85b608c5d86307ccd6fa0f283f4a806d64163d17c7b0
size 33868 size 33985

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:60dbf7ac48dc77b79f80c15ea811381ee5885e2c5f702e522e789f16672c694b oid sha256:6e91c8c83e1a793bb8e0d306b98a4737187a5a5df7a47c67ac6a716696cff3fc
size 41164 size 41208

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:13c58f6fb3d875d31d2c72e67f859bf5b4e1496a05de36ea1dc2601fe882f7f6 oid sha256:52fe76d305e114d5eeab85b608c5d86307ccd6fa0f283f4a806d64163d17c7b0
size 33868 size 33985

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:60dbf7ac48dc77b79f80c15ea811381ee5885e2c5f702e522e789f16672c694b oid sha256:6e91c8c83e1a793bb8e0d306b98a4737187a5a5df7a47c67ac6a716696cff3fc
size 41164 size 41208

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:695a934529456a82e99371e9b53231ac02f6d235174927fbb346bf2a5375aceb
size 33962

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:6992afacc7a2b2927258d9a8183c016df9f92c06616291eab2ffe55dddf3d149 oid sha256:a128bd56c653706f65f20dac1e4110b21259e76821821057fe1e829044a1d36a
size 31451 size 31523

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:721a167934d333cac37e16c0114238ec80a56afa9eac04bd4ee96642f09a85e8 oid sha256:65bd05d8176f7d65f10ee3183f221afc73a759962a2e6b95067d3830a93d876c
size 35126 size 34766

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:2fe6a53eeb683a6e22ddef38481800489747ecd0d7875247f0014928e83a85f8 oid sha256:f00202b17ca6c89dfdefc616888ceeb7272cfdb452745e8e034d556764983f7d
size 30597 size 30717

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:052a42e15095538d05231b73fd7f5259bd3782d1b280ef0726a0445a9dd719ad oid sha256:fec18df4d767d669a62d9adcef3d919332fb3af72f5bf2df349acc3e964fa78e
size 36640 size 36634

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:2fe6a53eeb683a6e22ddef38481800489747ecd0d7875247f0014928e83a85f8 oid sha256:f00202b17ca6c89dfdefc616888ceeb7272cfdb452745e8e034d556764983f7d
size 30597 size 30717

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:052a42e15095538d05231b73fd7f5259bd3782d1b280ef0726a0445a9dd719ad oid sha256:fec18df4d767d669a62d9adcef3d919332fb3af72f5bf2df349acc3e964fa78e
size 36640 size 36634

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a128bd56c653706f65f20dac1e4110b21259e76821821057fe1e829044a1d36a
size 31523

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:62418ebe7afa2c1c7eda2b1251fb189a75527aa7a4289a9478c531fac7dee8bd oid sha256:aa7de6ce541afcabc79fc1554809c217fd4f8bc83ed2c324342a9d28b9f34717
size 10666 size 31001

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:e5a32b1baaaad0bf266e190084a64b3d382a2d6d472a55b1c3653ee948e100c9 oid sha256:9c7bdc732cc76ffcded6903e533ccb64d57d671f02a62093e63d0375fe0c680c
size 9756 size 29016

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:f91d546db2397cb0fd90a200c916e4ff26db0de5c55d6c0eab4b25c3380377a6 oid sha256:78cb940e6edfe0591071224fc7a8dcf32472633f56c38d55647dff40b042894b
size 24070 size 24303

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:16e46bb87e1f4ef3a71a2e64029075c26b2b6f9699a7b756492db2378f604152 oid sha256:52992127004c26595f2bfeb50c657a5628b18ffc10b8e6b260203504f44756fa
size 22643 size 22787

View file

@ -117,6 +117,7 @@
"screen_room_notification_settings_.*", "screen_room_notification_settings_.*",
"screen_notification_settings_edit_failed_updating_default_mode", "screen_notification_settings_edit_failed_updating_default_mode",
"screen_polls_history_title", "screen_polls_history_title",
"screen_notification_settings_mentions_only_disclaimer",
"screen_start_chat_error_starting_chat" "screen_start_chat_error_starting_chat"
] ]
}, },

View file

@ -47,7 +47,7 @@ for entry in config["modules"]:
"includeKeys": list(map(lambda i: "REGEX:" + i, entry["includeRegex"])), "includeKeys": list(map(lambda i: "REGEX:" + i, entry["includeRegex"])),
"excludeKeys": list(map(lambda i: "REGEX:" + i, excludeRegex)), "excludeKeys": list(map(lambda i: "REGEX:" + i, excludeRegex)),
"conditions": [ "conditions": [
"equals: ${languageCode}, en" "equals: ${languageCode}, en | equals: ${file}, content.json"
] ]
} }
# print(action) # print(action)
@ -59,7 +59,7 @@ for entry in config["modules"]:
"includeKeys": list(map(lambda i: "REGEX:" + i, entry["includeRegex"])), "includeKeys": list(map(lambda i: "REGEX:" + i, entry["includeRegex"])),
"excludeKeys": list(map(lambda i: "REGEX:" + i, excludeRegex)), "excludeKeys": list(map(lambda i: "REGEX:" + i, excludeRegex)),
"conditions": [ "conditions": [
"!equals: ${languageCode}, en" "!equals: ${languageCode}, en | equals: ${file}, content.json"
] ]
} }
allActions.append(actionTranslation) allActions.append(actionTranslation)
@ -70,7 +70,7 @@ mainAction = baseAction | {
"output": "libraries/ui-strings/src/main/res/values/localazy.xml", "output": "libraries/ui-strings/src/main/res/values/localazy.xml",
"excludeKeys": list(map(lambda i: "REGEX:" + i, allRegexToExcludeFromMainModule + regexToAlwaysExclude)), "excludeKeys": list(map(lambda i: "REGEX:" + i, allRegexToExcludeFromMainModule + regexToAlwaysExclude)),
"conditions": [ "conditions": [
"equals: ${languageCode}, en" "equals: ${languageCode}, en | equals: ${file}, content.json"
] ]
} }
# print(mainAction) # print(mainAction)
@ -82,7 +82,7 @@ if allFiles:
"output": "libraries/ui-strings/src/main/res/values-${langAndroidResNoScript}/translations.xml", "output": "libraries/ui-strings/src/main/res/values-${langAndroidResNoScript}/translations.xml",
"excludeKeys": list(map(lambda i: "REGEX:" + i, allRegexToExcludeFromMainModule + regexToAlwaysExclude)), "excludeKeys": list(map(lambda i: "REGEX:" + i, allRegexToExcludeFromMainModule + regexToAlwaysExclude)),
"conditions": [ "conditions": [
"!equals: ${languageCode}, en" "!equals: ${languageCode}, en | equals: ${file}, content.json"
] ]
} }
allActions.append(mainActionTranslation) allActions.append(mainActionTranslation)