Merge branch 'develop' into julioromano/poll_history_entry_point
This commit is contained in:
commit
4d3c6632cd
54 changed files with 220 additions and 153 deletions
1
changelog.d/1749.misc
Normal file
1
changelog.d/1749.misc
Normal 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
1
changelog.d/2031.misc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Only process content.json from Localazy.
|
||||||
|
|
@ -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 = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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 = {}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 = { },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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 = { },
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:78eab361860e4b4153a680fad703dc61c69c80a28af0a90b0a6add85178eea4f
|
||||||
|
size 49828
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:29160e672d2bda2cdb69b7a2c2357316696637db23dc1de0665cc80308303399
|
||||||
|
size 47051
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:695a934529456a82e99371e9b53231ac02f6d235174927fbb346bf2a5375aceb
|
||||||
|
size 33962
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:a128bd56c653706f65f20dac1e4110b21259e76821821057fe1e829044a1d36a
|
||||||
|
size 31523
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue