diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt index 730fe0c02e..f27ae8eb51 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt @@ -39,7 +39,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDownward -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -65,6 +64,8 @@ import io.element.android.features.messages.timeline.components.TimelineItemReac import io.element.android.features.messages.timeline.components.TimelineItemRedactedView import io.element.android.features.messages.timeline.components.TimelineItemTextView import io.element.android.features.messages.timeline.components.TimelineItemUnknownView +import io.element.android.features.messages.timeline.components.virtual.TimelineItemDaySeparatorView +import io.element.android.features.messages.timeline.components.virtual.TimelineLoadingMoreIndicator import io.element.android.features.messages.timeline.model.AggregatedReaction import io.element.android.features.messages.timeline.model.MessagesItemGroupPosition import io.element.android.features.messages.timeline.model.TimelineItem @@ -77,6 +78,7 @@ import io.element.android.features.messages.timeline.model.event.TimelineItemIma import io.element.android.features.messages.timeline.model.event.TimelineItemRedactedContent import io.element.android.features.messages.timeline.model.event.TimelineItemTextBasedContent import io.element.android.features.messages.timeline.model.event.TimelineItemUnknownContent +import io.element.android.features.messages.timeline.model.virtual.TimelineItemDaySeparatorModel import io.element.android.features.messages.timeline.model.virtual.TimelineItemLoadingModel import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -178,6 +180,7 @@ fun TimelineItemVirtualRow( ) { when (virtual.model) { is TimelineItemLoadingModel -> TimelineLoadingMoreIndicator(modifier) + is TimelineItemDaySeparatorModel -> TimelineItemDaySeparatorView(virtual.model, modifier) else -> return } } @@ -351,22 +354,6 @@ internal fun BoxScope.TimelineScrollHelper( } } -@Composable -internal fun TimelineLoadingMoreIndicator(modifier: Modifier) { - Box( - modifier - .fillMaxWidth() - .wrapContentHeight() - .padding(8.dp), - contentAlignment = Alignment.Center, - ) { - CircularProgressIndicator( - strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.primary - ) - } -} - class MessagesItemGroupPositionToMessagesTimelineItemContentProvider : PairCombinedPreviewParameter( TimelineItemGroupPositionProvider() to MessagesTimelineItemContentProvider() diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/virtual/TimelineItemDaySeparatorView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/virtual/TimelineItemDaySeparatorView.kt new file mode 100644 index 0000000000..0c57c9e242 --- /dev/null +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/virtual/TimelineItemDaySeparatorView.kt @@ -0,0 +1,46 @@ +/* + * 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.timeline.components.virtual + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.element.android.features.messages.timeline.model.virtual.TimelineItemDaySeparatorModel + +@Composable +internal fun TimelineItemDaySeparatorView( + model: TimelineItemDaySeparatorModel, + modifier: Modifier = Modifier +) { + Box( + modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(8.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = model.formattedDate + ) + } +} diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/virtual/TimelineItemLoadingMoreIndicator.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/virtual/TimelineItemLoadingMoreIndicator.kt new file mode 100644 index 0000000000..7588192c6e --- /dev/null +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/virtual/TimelineItemLoadingMoreIndicator.kt @@ -0,0 +1,44 @@ +/* + * 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.timeline.components.virtual + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +internal fun TimelineLoadingMoreIndicator(modifier: Modifier = Modifier) { + Box( + modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(8.dp), + contentAlignment = Alignment.Center, + ) { + CircularProgressIndicator( + strokeWidth = 2.dp, + color = MaterialTheme.colorScheme.primary + ) + } +} diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/factories/virtual/TimelineItemDaySeparatorFactory.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/factories/virtual/TimelineItemDaySeparatorFactory.kt index 5bb213b617..00a36c06e5 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/factories/virtual/TimelineItemDaySeparatorFactory.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/factories/virtual/TimelineItemDaySeparatorFactory.kt @@ -18,14 +18,30 @@ package io.element.android.features.messages.timeline.factories.virtual import io.element.android.features.messages.timeline.model.virtual.TimelineItemDaySeparatorModel import io.element.android.features.messages.timeline.model.virtual.TimelineItemVirtualModel +import kotlinx.datetime.Instant +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toJavaLocalDateTime +import kotlinx.datetime.toLocalDateTime import org.matrix.rustcomponents.sdk.VirtualTimelineItem +import java.time.format.DateTimeFormatter +import java.util.Locale import javax.inject.Inject class TimelineItemDaySeparatorFactory @Inject constructor() { + //TODO use proper formatter + private val locale: Locale = Locale.getDefault() + + private val dateWithYearFormatter: DateTimeFormatter by lazy { + val pattern = android.text.format.DateFormat.getBestDateTimePattern(locale, "dd.MM.yyyy") + DateTimeFormatter.ofPattern(pattern) + } + fun create(virtualItem: VirtualTimelineItem.DayDivider): TimelineItemVirtualModel { + val tsInstant = Instant.fromEpochMilliseconds(virtualItem.ts.toLong()) + val tsDateTime = tsInstant.toLocalDateTime(TimeZone.currentSystemDefault()) return TimelineItemDaySeparatorModel( - day = "${virtualItem.ts}" + formattedDate = dateWithYearFormatter.format(tsDateTime.toJavaLocalDateTime()) ) } } diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/model/virtual/TimelineItemDaySeparatorModel.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/model/virtual/TimelineItemDaySeparatorModel.kt index e169033df3..c6e762a235 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/model/virtual/TimelineItemDaySeparatorModel.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/model/virtual/TimelineItemDaySeparatorModel.kt @@ -17,5 +17,5 @@ package io.element.android.features.messages.timeline.model.virtual data class TimelineItemDaySeparatorModel( - val day: String + val formattedDate: String ) : TimelineItemVirtualModel