diff --git a/features/createroom/impl/src/main/res/values-de/translations.xml b/features/createroom/impl/src/main/res/values-de/translations.xml index 210f7f4cb4..6c3a7c8130 100644 --- a/features/createroom/impl/src/main/res/values-de/translations.xml +++ b/features/createroom/impl/src/main/res/values-de/translations.xml @@ -6,4 +6,4 @@ "Privater Raum (nur auf Einladung)" "Raumname" "Thema (optional)" - + \ No newline at end of file diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index a55ea1021d..c1708d3086 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -63,6 +63,7 @@ import io.element.android.features.messages.impl.actionlist.model.TimelineItemAc import io.element.android.features.messages.impl.textcomposer.AttachmentSourcePicker import io.element.android.features.messages.impl.textcomposer.MessageComposerEvents import io.element.android.features.messages.impl.textcomposer.MessageComposerView +import io.element.android.features.messages.impl.timeline.TimelineEvents import io.element.android.features.messages.impl.timeline.TimelineView import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView @@ -139,6 +140,11 @@ fun MessagesView( } } + fun onExpandGroupClick(event: TimelineItem.GroupedEvents) { + Timber.v("onExpandGroupClick= ${event.id}") + state.timelineState.eventSink(TimelineEvents.ToggleExpandGroup(event)) + } + fun onActionSelected(action: TimelineItemAction, event: TimelineItem.Event) { state.eventSink(MessagesEvents.HandleAction(action, event)) } @@ -189,7 +195,8 @@ fun MessagesView( .padding(padding) .consumeWindowInsets(padding), onMessageClicked = ::onMessageClicked, - onMessageLongClicked = ::onMessageLongClicked + onMessageLongClicked = ::onMessageLongClicked, + onExpandGroupClick = ::onExpandGroupClick, ) }, snackbarHost = { @@ -214,6 +221,7 @@ fun MessagesViewContent( modifier: Modifier = Modifier, onMessageClicked: (TimelineItem.Event) -> Unit = {}, onMessageLongClicked: (TimelineItem.Event) -> Unit = {}, + onExpandGroupClick: (TimelineItem.GroupedEvents) -> Unit = {}, ) { Column( modifier = modifier @@ -227,7 +235,8 @@ fun MessagesViewContent( state = state.timelineState, modifier = Modifier.weight(1f), onMessageClicked = onMessageClicked, - onMessageLongClicked = onMessageLongClicked + onMessageLongClicked = onMessageLongClicked, + onExpandGroupClick = onExpandGroupClick, ) } MessageComposerView( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt index ff64441198..11f1a1a483 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt @@ -16,9 +16,11 @@ package io.element.android.features.messages.impl.timeline +import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.libraries.matrix.api.core.EventId sealed interface TimelineEvents { object LoadMore : TimelineEvents data class SetHighlightedEvent(val eventId: EventId?) : TimelineEvents + data class ToggleExpandGroup(val event: TimelineItem.GroupedEvents) : TimelineEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 9418e59edc..1693a623f3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -17,15 +17,18 @@ package io.element.android.features.messages.impl.timeline import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory +import io.element.android.features.messages.impl.timeline.groups.TimelineItemGrouper import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.timeline.MatrixTimeline @@ -42,6 +45,7 @@ private const val backPaginationPageSize = 50 class TimelinePresenter @Inject constructor( private val timelineItemsFactory: TimelineItemsFactory, + private val timelineItemGrouper: TimelineItemGrouper, room: MatrixRoom, ) : Presenter { @@ -53,6 +57,8 @@ class TimelinePresenter @Inject constructor( val highlightedEventId: MutableState = rememberSaveable { mutableStateOf(null) } + val expandedGroups = remember { mutableStateMapOf() } + val timelineItems = timelineItemsFactory .flow() .collectAsState() @@ -65,6 +71,9 @@ class TimelinePresenter @Inject constructor( when (event) { TimelineEvents.LoadMore -> localCoroutineScope.loadMore(paginationState.value) is TimelineEvents.SetHighlightedEvent -> highlightedEventId.value = event.eventId + is TimelineEvents.ToggleExpandGroup -> { + expandedGroups[event.event.identifier()] = expandedGroups[event.event.identifier()].orFalse().not() + } } } @@ -83,7 +92,7 @@ class TimelinePresenter @Inject constructor( return TimelineState( highlightedEventId = highlightedEventId.value, paginationState = paginationState.value, - timelineItems = timelineItems.value.toImmutableList(), + timelineItems = timelineItemGrouper.group(timelineItems.value, expandedGroups).toImmutableList(), eventSink = ::handleEvents ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 954b1321f7..4b8a1b4869 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -50,14 +50,17 @@ import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.LastBaseline +import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex +import io.element.android.features.messages.impl.R import io.element.android.features.messages.impl.timeline.components.MessageEventBubble import io.element.android.features.messages.impl.timeline.components.MessageStateEventContainer import io.element.android.features.messages.impl.timeline.components.TimelineItemReactionsView import io.element.android.features.messages.impl.timeline.components.event.TimelineItemEventContentView +import io.element.android.features.messages.impl.timeline.components.group.GroupHeaderView import io.element.android.features.messages.impl.timeline.components.virtual.TimelineItemDaySeparatorView import io.element.android.features.messages.impl.timeline.components.virtual.TimelineLoadingMoreIndicator import io.element.android.features.messages.impl.timeline.model.TimelineItem @@ -84,6 +87,7 @@ fun TimelineView( modifier: Modifier = Modifier, onMessageClicked: (TimelineItem.Event) -> Unit = {}, onMessageLongClicked: (TimelineItem.Event) -> Unit = {}, + onExpandGroupClick: (TimelineItem.GroupedEvents) -> Unit = {}, ) { fun onReachedLoadMore() { @@ -106,9 +110,10 @@ fun TimelineView( ) { index, timelineItem -> TimelineItemRow( timelineItem = timelineItem, - isHighlighted = timelineItem.identifier() == state.highlightedEventId?.value, + highlightedItem = state.highlightedEventId?.value, onClick = onMessageClicked, - onLongClick = onMessageLongClicked + onLongClick = onMessageLongClicked, + onExpandGroupClick = onExpandGroupClick, ) if (index == state.timelineItems.lastIndex) { onReachedLoadMore() @@ -127,9 +132,10 @@ fun TimelineView( @Composable fun TimelineItemRow( timelineItem: TimelineItem, - isHighlighted: Boolean, + highlightedItem: String?, onClick: (TimelineItem.Event) -> Unit, onLongClick: (TimelineItem.Event) -> Unit, + onExpandGroupClick: (TimelineItem.GroupedEvents) -> Unit, ) { when (timelineItem) { is TimelineItem.Virtual -> { @@ -149,19 +155,48 @@ fun TimelineItemRow( if (timelineItem.content is TimelineItemStateContent) { TimelineItemStateEventRow( event = timelineItem, - isHighlighted = isHighlighted, + isHighlighted = highlightedItem == timelineItem.identifier(), onClick = ::onClick, onLongClick = ::onLongClick ) } else { TimelineItemEventRow( event = timelineItem, - isHighlighted = isHighlighted, + isHighlighted = highlightedItem == timelineItem.identifier(), onClick = ::onClick, onLongClick = ::onLongClick ) } } + is TimelineItem.GroupedEvents -> { + fun onExpandGroupClick() { + onExpandGroupClick(timelineItem) + } + + if (timelineItem.expanded) { + Column { + timelineItem.events.forEach { subGroupEvent -> + TimelineItemRow( + timelineItem = subGroupEvent, + highlightedItem = highlightedItem, + onClick = onClick, + onLongClick = onLongClick, + onExpandGroupClick = {} + ) + } + } + } + GroupHeaderView( + text = pluralStringResource( + id = R.plurals.room_timeline_state_changes, + count = timelineItem.events.size, + timelineItem.events.size + ), + isExpanded = timelineItem.expanded, + isHighlighted = !timelineItem.expanded && timelineItem.events.any { it.identifier() == highlightedItem }, + onClick = ::onExpandGroupClick, + ) + } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt new file mode 100644 index 0000000000..d952d573f9 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.messages.impl.timeline.components.group + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +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.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material.icons.filled.ArrowRight +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Surface +import io.element.android.libraries.designsystem.theme.components.Text + +private val CORNER_RADIUS = 8.dp + +@Composable +fun GroupHeaderView( + text: String, + isExpanded: Boolean, + isHighlighted: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + val backgroundColor = if (isHighlighted) { + ElementTheme.colors.messageHighlightedBackground + } else { + Color.Companion.Transparent + } + val shape = RoundedCornerShape(CORNER_RADIUS) + + Box( + modifier = modifier + .fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Surface( + modifier = Modifier + .clip(shape) + .clickable(onClick = onClick), + color = backgroundColor, + shape = shape, + ) { + Row( + modifier = Modifier + .padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = text, + color = MaterialTheme.colorScheme.secondary, + fontSize = 13.sp + ) + val icon = if (isExpanded) { + Icons.Default.ArrowDropDown + } else { + Icons.Default.ArrowRight + } + Icon(icon, "", tint = MaterialTheme.colorScheme.secondary) + } + } + } +} + +@Preview +@Composable +fun GroupHeaderViewLightPreview() = + ElementPreviewLight { ContentToPreview() } + +@Preview +@Composable +fun GroupHeaderViewDarkPreview() = + ElementPreviewDark { ContentToPreview() } + +@Composable +private fun ContentToPreview() { + Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { + GroupHeaderView( + text = "8 room changes (expanded)", + isExpanded = true, + isHighlighted = false, + onClick = {} + ) + GroupHeaderView( + text = "8 room changes (not expanded)", + isExpanded = false, + isHighlighted = false, + onClick = {} + ) + GroupHeaderView( + text = "8 room changes (expanded/h)", + isExpanded = true, + isHighlighted = true, + onClick = {} + ) + GroupHeaderView( + text = "8 room changes (not expanded/h)", + isExpanded = false, + isHighlighted = true, + onClick = {} + ) + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt new file mode 100644 index 0000000000..1ec382a4e5 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.messages.impl.timeline.groups + +import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEmoteContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemNoticeContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemProfileChangeContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRoomMembershipContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateEventContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent +import io.element.android.libraries.core.bool.orFalse +import kotlinx.collections.immutable.toImmutableList + +import javax.inject.Inject + +/** + * Create a new list of [TimelineItem] by grouping some of them into [TimelineItem.GroupedEvents]. + */ +class TimelineItemGrouper @Inject constructor() { + fun group(from: List, expandedGroups: Map): List { + val result = mutableListOf() + val currentGroup = mutableListOf() + from.forEach { timelineItem -> + if (timelineItem is TimelineItem.Event && timelineItem.canBeGrouped()) { + currentGroup.add(0, timelineItem) + } else { + // timelineItem cannot be grouped + if (currentGroup.isNotEmpty()) { + // There is a pending group, create a TimelineItem.GroupedEvents if there is more than 1 Event in the pending group. + if (currentGroup.size == 1) { + // Do not create a group with just 1 item, just add the item to the result + result.add(currentGroup.first()) + } else { + result.add( + TimelineItem.GroupedEvents( + expanded = expandedGroups[currentGroup.first().id + "_group"].orFalse(), + events = currentGroup.toImmutableList() + ) + ) + } + currentGroup.clear() + } + result.add(timelineItem) + } + } + return result + } + + private fun TimelineItem.Event.canBeGrouped(): Boolean { + return when (content) { + is TimelineItemEncryptedContent, + is TimelineItemImageContent, + TimelineItemRedactedContent, + is TimelineItemEmoteContent, + is TimelineItemNoticeContent, + is TimelineItemTextContent, + TimelineItemUnknownContent -> false + is TimelineItemProfileChangeContent, + is TimelineItemRoomMembershipContent, + is TimelineItemStateEventContent -> true + } + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt index e1b6557f31..fe34cd5b1d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt @@ -22,6 +22,7 @@ import io.element.android.features.messages.impl.timeline.model.virtual.Timeline import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UserId +import kotlinx.collections.immutable.ImmutableList @Immutable sealed interface TimelineItem { @@ -29,11 +30,13 @@ sealed interface TimelineItem { fun identifier(): String = when (this) { is Event -> id is Virtual -> id + is GroupedEvents -> id } fun contentType(): String = when (this) { is Event -> content.type is Virtual -> model.type + is GroupedEvents -> "groupedEvent" } @Immutable @@ -60,4 +63,13 @@ sealed interface TimelineItem { val safeSenderName: String = senderDisplayName ?: senderId.value } + + @Immutable + data class GroupedEvents( + val expanded: Boolean, + val events: ImmutableList, + ) : TimelineItem { + // use first id with a suffix + val id = events.first().id + "_group" + } } diff --git a/features/messages/impl/src/main/res/values-es/translations.xml b/features/messages/impl/src/main/res/values-es/translations.xml new file mode 100644 index 0000000000..7cd4b6e764 --- /dev/null +++ b/features/messages/impl/src/main/res/values-es/translations.xml @@ -0,0 +1,7 @@ + + + + "%1$d cambio en la sala" + "%1$d cambios en la sala" + + \ No newline at end of file diff --git a/features/messages/impl/src/main/res/values-it/translations.xml b/features/messages/impl/src/main/res/values-it/translations.xml new file mode 100644 index 0000000000..649a91405b --- /dev/null +++ b/features/messages/impl/src/main/res/values-it/translations.xml @@ -0,0 +1,7 @@ + + + + "%1$d modifica alla stanza" + "%1$d modifiche alla stanza" + + \ No newline at end of file diff --git a/features/messages/impl/src/main/res/values-ro/translations.xml b/features/messages/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..68d83cacfe --- /dev/null +++ b/features/messages/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,8 @@ + + + + "%1$d schimbare a camerii" + "%1$d schimbări ale camerei" + "%1$d schimbări ale camerei" + + \ No newline at end of file diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index 8c53bca6c4..361e80a4de 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -1,5 +1,9 @@ + + "%1$d room change" + "%1$d room changes" + "Camera" "Take photo" "Record a video" diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml index 428d42ec14..2fb21016e5 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -26,6 +26,7 @@ "Raum verlassen" "Weiter" "Nein" + "Nicht jetzt" "OK" "Schnellantwort" "Zitieren" @@ -41,10 +42,11 @@ "Teilen" "Link teilen" "Überspringen" + "Chat starten" "Foto aufnehmen" "Ja" "Über" - "Analytik" + "Analyse" "Audio" "Blasen" "Entschlüsselungsfehler" @@ -61,6 +63,7 @@ "Offline" "Passwort" "Reaktionen" + "Fehler melden" "Suchergebnisse" "Sicherheit" "Server wird nicht unterstützt" @@ -87,6 +90,7 @@ "Reisen & Orte" "Symbole" "Fehler beim Laden der Nachrichten" + "Einige Nachrichten wurden nicht gesendet" "Entschuldigung, ein Fehler ist aufgetreten." "%1$s Android" @@ -96,6 +100,9 @@ "Grund für die Meldung dieses Inhalts" "Dies ist der Anfang von %1$s." "Neu" + "Wir erfassen und analysieren ""keine"" Account-Daten" + "Sie können die Analyse jederzeit in den Einstellungen deaktivieren" + "Wir geben ""keine"" Informationen an Dritte weiter" "Teile Analyse-Daten" "Medienauswahl fehlgeschlagen, bitte versuche es erneut." "Erkennungsschwelle" diff --git a/libraries/ui-strings/src/main/res/values-es/translations.xml b/libraries/ui-strings/src/main/res/values-es/translations.xml index 78a386f650..b1e73503fa 100644 --- a/libraries/ui-strings/src/main/res/values-es/translations.xml +++ b/libraries/ui-strings/src/main/res/values-es/translations.xml @@ -116,10 +116,6 @@ "%1$d miembro" "%1$d miembros" - - "%1$d cambio en la sala" - "%1$d cambios en la sala" - "Agitar con fuerza para informar de un error" "Parece que sacudes el teléfono con frustración. ¿Quieres abrir la pantalla de informe de errores?" "Este mensaje se notificará al administrador de su homeserver. No podrán leer ningún mensaje cifrado." diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index 20f255a21c..c8b16a7ea5 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -116,10 +116,6 @@ "%1$d membro" "%1$d membri" - - "%1$d modifica alla stanza" - "%1$d modifiche alla stanza" - "Scuoti per segnalare un problema" "Sembra che tu stia scuotendo il telefono per la frustrazione. Vuoi aprire la schermata di segnalazione dei problemi?" "Questo messaggio verrà segnalato all\'amministratore dell\'homeserver. Questi non sarà in grado di leggere i messaggi criptati." diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index d7b052badc..efcd69b3fc 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -125,11 +125,6 @@ "%1$d membri" "%1$d membri" - - "%1$d schimbare a camerii" - "%1$d schimbări ale camerei" - "%1$d schimbări ale camerei" - "Rageshake pentru a raporta erori" "Se pare că scuturați telefonul de frustrare. Doriți să deschdeți ecranul de raportare a unei erori?" "Acest mesaj va fi raportat administratorilor homeserver-ului tau. Ei nu vor putea citi niciun mesaj criptat." diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index ca2bcd1d28..163d65f19f 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -122,7 +122,7 @@ "Failed loading messages" "Some messages have not been sent" "Sorry, an error occurred" - "🔐️ Join me on %1$s" + "🔐️ Join me on %1$s" "Hey, talk to me on %1$s: %2$s" "Are you sure that you want to leave this room? You are the only person here. If you leave, no one will be able to join in the future, including you." "Are you sure that you want to leave this room? This room is not public and you will not be able to rejoin without an invite." @@ -132,10 +132,6 @@ "%1$d member" "%1$d members" - - "%1$d room change" - "%1$d room changes" - "Rageshake to report bug" "You seem to be shaking the phone in frustration. Would you like to open the bug report screen?" "This message will be reported to your homeserver’s administrator. They will not be able to read any encrypted messages." @@ -167,4 +163,4 @@ "You can read all our terms %1$s." "here" "Block user" - \ No newline at end of file + diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 1e0e125137..ef7110a160 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -57,7 +57,7 @@ ] }, { - "name": ":libraries:messageformatter:impl", + "name": ":libraries:eventformatter:impl", "includeRegex": [ "state_event_.*" ] @@ -95,7 +95,8 @@ "name": ":features:messages:impl", "includeRegex": [ "screen_room_.*", - "screen_dm_details_.*" + "screen_dm_details_.*", + "room_timeline_state_changes" ], "excludeRegex": [ "screen_room_details_.*",