Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class SystemMessageContentMapper @Inject constructor(
content,
members
)

is MessageContent.AdminlessDeleteReminder ->
UIMessageContent.SystemMessage.AdminlessDeleteReminder(content.deletionScheduledFor)
}

private fun mapConversationConversationAppsAccessChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package com.wire.android.ui.home.conversations.messages.item

import android.text.format.DateFormat
import androidx.annotation.DrawableRes
import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
Expand Down Expand Up @@ -63,6 +64,7 @@ import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography
import com.wire.android.util.CustomTabsHelper
import com.wire.android.util.SupportPage
import com.wire.android.util.formatMonthDayShortTime
import com.wire.android.util.supportUrlResource
import com.wire.android.util.ui.MarkdownTextStyle
import com.wire.android.util.ui.UIText
Expand Down Expand Up @@ -610,6 +612,26 @@ private fun SystemMessage.buildContent(isWireCellsEnabled: Boolean) = when (this
}
}
}

is SystemMessage.AdminlessDeleteReminder -> buildContent(
iconResId = commonR.drawable.ic_info,
iconTintColor = MaterialTheme.wireColorScheme.error,
learnMorePage = SupportPage.ADMINLESS_GROUP_DELETE,
) {
val is24Hour = DateFormat.is24HourFormat(LocalContext.current)
val markdownTextStyle = DefaultMarkdownTextStyle.copy(
normalColor = MaterialTheme.wireColorScheme.error,
boldColor = MaterialTheme.wireColorScheme.error
)
buildAnnotatedString {
append(
stringResource(
id = R.string.label_system_message_adminless_delete_reminder,
formatArgs = arrayOf(deletionScheduledFor.formatMonthDayShortTime(is24Hour))
).toMarkdownAnnotatedString(markdownTextStyle)
)
}
}
}

private fun AnnotatedString.Builder.appendVerticalSpace() = withStyle(ParagraphStyle()) { append(" ") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.wire.android.util.ui.PreviewMultipleThemes
import com.wire.android.util.ui.UIText
import com.wire.android.util.ui.toUIText
import com.wire.kalium.logic.data.conversation.Conversation
import kotlinx.datetime.Instant

@PreviewMultipleThemes
@Composable
Expand Down Expand Up @@ -486,3 +487,17 @@ fun PreviewSystemMessageConversationMessageAppsAccessEnabled() {
)
}
}

@PreviewMultipleThemes
@Composable
fun PreviewSystemMessageAdminlessDeleteReminder() {
WireTheme {
SystemMessageItem(
message = mockMessageWithKnock.copy(
messageContent = UIMessageContent.SystemMessage.AdminlessDeleteReminder(
deletionScheduledFor = Instant.parse("2026-04-23T12:00:00Z")
)
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,11 @@ sealed interface UIMessageContent {
val isAuthorSelfUser: Boolean = false,
val isAccessEnabled: Boolean
) : SystemMessage

@Serializable
data class AdminlessDeleteReminder(
val deletionScheduledFor: Instant
) : SystemMessage
}
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1903,6 +1903,7 @@ In group conversations, the group admin can overwrite this setting.</string>
<string name="label_system_message_apps_access_disabled_by_other">%1$s disabled **apps** for this conversation</string>
<string name="label_system_message_apps_access_enabled_disclaimer">Added apps have access to the content of this conversation.</string>
<string name="label_system_message_admin_role_assigned">You were promoted to group admin</string>
<string name="label_system_message_adminless_delete_reminder">This group will be automatically deleted on %1$s, as there are no eligible group admins.</string>
<string name="more_information_about_this_server">More information about this backend</string>

<!-- Pending messages service notification -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import java.util.Locale
import kotlinx.datetime.Instant

@OptIn(ExperimentalCoroutinesApi::class)
@ExtendWith(CoroutineTestExtension::class)
Expand Down Expand Up @@ -75,6 +76,18 @@ class SystemMessageContentMapperTest {
assertTrue(uiContent is SystemMessage.ConversationMessageTimerDeactivated)
}

@Test
fun givenAdminlessDeleteReminder_whenMappingToSystemMessage_thenScheduledDeletionIsPreserved() = runTest {
val (_, mapper) = Arrangement().arrange()
val scheduledDeletion = Instant.parse("2026-04-23T12:00:00Z")
val content = MessageContent.AdminlessDeleteReminder(scheduledDeletion)

val uiContent = mapper.mapMessage(TestMessage.SYSTEM_MESSAGE.copy(content = content), emptyList())

assertIs<SystemMessage.AdminlessDeleteReminder>(uiContent!!)
assertEquals(scheduledDeletion, uiContent.deletionScheduledFor)
}

@Test
fun givenMemberDetails_whenMappingToSystemMessageMemberName_thenCorrectValuesShouldBeReturned() = runTest {
// Given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
*/
package com.wire.android.util

import android.text.format.DateFormat
import androidx.compose.runtime.Stable
import kotlinx.datetime.Instant
import kotlinx.datetime.toJavaInstant
import java.text.SimpleDateFormat
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
Expand All @@ -39,6 +41,10 @@
@Stable
fun Instant.formatFullDateShortTime(): String = DateAndTimeParsers.formatFullDateShortTime(this)

@Stable
fun Instant.formatMonthDayShortTime(is24Hour: Boolean): String =
DateAndTimeParsers.formatMonthDayShortTime(this, is24Hour)

Check warning on line 46 in core/ui-common/src/main/kotlin/com/wire/android/util/DateAndTimeParsers.kt

View check run for this annotation

Codecov / codecov/patch

core/ui-common/src/main/kotlin/com/wire/android/util/DateAndTimeParsers.kt#L46

Added line #L46 was not covered by tests

@Stable
fun Instant.uiMessageDateTime(): String = DateAndTimeParsers.uiMessageDateTime(this)

Expand Down Expand Up @@ -107,6 +113,16 @@

fun formatFullDateShortTime(instant: Instant): String = fullDateShortTimeFormatter.format(instant.toJavaInstant())

fun formatMonthDayShortTime(instant: Instant, is24Hour: Boolean): String {
val locale = Locale.getDefault()
val date = Date.from(instant.toJavaInstant())
val datePattern = DateFormat.getBestDateTimePattern(locale, "MMMMd")

Check warning on line 119 in core/ui-common/src/main/kotlin/com/wire/android/util/DateAndTimeParsers.kt

View check run for this annotation

Codecov / codecov/patch

core/ui-common/src/main/kotlin/com/wire/android/util/DateAndTimeParsers.kt#L117-L119

Added lines #L117 - L119 were not covered by tests
val timePattern = DateFormat.getBestDateTimePattern(locale, if (is24Hour) "Hm" else "hm")
val formattedDate = SimpleDateFormat(datePattern, locale).format(date)
val formattedTime = SimpleDateFormat(timePattern, locale).format(date)
return "$formattedDate, $formattedTime"

Check warning on line 123 in core/ui-common/src/main/kotlin/com/wire/android/util/DateAndTimeParsers.kt

View check run for this annotation

Codecov / codecov/patch

core/ui-common/src/main/kotlin/com/wire/android/util/DateAndTimeParsers.kt#L121-L123

Added lines #L121 - L123 were not covered by tests
}

fun cellTimeFormat(instant: Instant): String {
val timeFormatter = java.text.DateFormat.getTimeInstance(
java.text.DateFormat.SHORT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,6 @@ enum class SupportPage(
LEGAL_HOLD("legal_hold", R.string.url_legal_hold_learn_more),
SEARCH("search", R.string.url_learn_about_search),
CELLS_CONVERSATION("cells_conversation", R.string.empty_screen_learn_more_link_conversation),
CELLS_ALL_FILES("cells_all_files", R.string.empty_screen_learn_more_link_all_files_screen)
CELLS_ALL_FILES("cells_all_files", R.string.empty_screen_learn_more_link_all_files_screen),
ADMINLESS_GROUP_DELETE("adminless_group_delete", R.string.url_system_message_adminless_group_delete),
}
1 change: 1 addition & 0 deletions core/ui-common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<string name="url_legal_hold_learn_more" translatable="false">https://support.wire.com/hc/articles/360002018278</string>
<string name="empty_screen_learn_more_link_conversation" translatable="false">https://support.wire.com/hc/articles/32207745256221</string>
<string name="empty_screen_learn_more_link_all_files_screen" translatable="false">https://support.wire.com/hc/articles/32207800433309</string>
<string name="url_system_message_adminless_group_delete" translatable="false">https://support.wire.com/hc/en-us/articles/37518608388125-Prevent-adminless-groups</string>
<string name="legal_hold_learn_more_button">Learn more about legal hold</string>
<string name="legal_hold_connection_failed_dialog_title">Connecting not possible</string>
<string name="legal_hold_connection_failed_dialog_description">You can not connect to this user due to legal hold.</string>
Expand Down
2 changes: 1 addition & 1 deletion kalium
Submodule kalium updated 32 files
+5 −0 core/data/src/commonMain/kotlin/com/wire/kalium/logic/data/message/Message.kt
+5 −0 core/data/src/commonMain/kotlin/com/wire/kalium/logic/data/message/MessageContent.kt
+49 −0 ...twork-model/src/commonMain/kotlin/com/wire/kalium/network/api/authenticated/notification/EventContentDTO.kt
+128 −0 ...lin/com/wire/kalium/network/api/authenticated/notification/AdminlessDeleteReminderEventSerializationTest.kt
+117 −0 ...t/kotlin/com/wire/kalium/network/api/authenticated/notification/SystemConversationEventSerializationTest.kt
+1 −1 data/persistence/src/commonMain/db_user/com/wire/kalium/persistence/MessageDetailsView.sq
+6 −0 data/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Messages.sq
+188 −0 data/persistence/src/commonMain/db_user/migrations/142.sqm
+3 −1 data/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageEntity.kt
+8 −0 data/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageInsertExtension.kt
+10 −0 data/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageMapper.kt
+2 −0 data/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/message/MessageMapperTest.kt
+2 −0 ...rsistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/message/MessageMapperUserTypeMappingTest.kt
+23 −0 data/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/message/MessageSystemContentTest.kt
+34 −28 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt
+103 −22 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt
+3 −0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/MessageMapper.kt
+2 −0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/PersistMessageUseCase.kt
+1 −3 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/notification/LocalNotificationMessageMapper.kt
+10 −0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt
+7 −0 logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/ConversationEventReceiver.kt
+57 −0 ...ommonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/DeleteConversationReminderEventHandler.kt
+1 −1 ...c/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/DeletedConversationEventHandler.kt
+1 −2 logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MemberChangeEventHandler.kt
+0 −1 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt
+159 −0 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/event/EventMapperTest.kt
+20 −0 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/MessageMapperTest.kt
+10 −6 logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt
+21 −0 logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/ConversationEventReceiverTest.kt
+105 −0 ...nTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/DeleteConversationReminderEventHandlerTest.kt
+37 −6 ...c/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/DeletedConversationEventHandlerTest.kt
+0 −1 logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MLSWelcomeEventHandlerTest.kt
Loading