From 3da3589d5c152f297dcc4577c1c86626410f397a Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Thu, 7 Apr 2022 17:50:29 +0200 Subject: [PATCH] Creating factory for live location items --- .../factory/LiveLocationMessageItemFactory.kt | 82 +++++++++++++++++++ .../timeline/factory/MessageItemFactory.kt | 16 +--- 2 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt new file mode 100644 index 0000000000..7310ecec80 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 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 im.vector.app.features.home.room.detail.timeline.factory + +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.resources.DateProvider +import im.vector.app.core.utils.DimensionConverter +import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvider +import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider +import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem +import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocationStartItem +import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocationStartItem_ +import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.extensions.orTrue +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent +import org.threeten.bp.LocalDateTime +import org.threeten.bp.temporal.ChronoUnit +import javax.inject.Inject + +class LiveLocationMessageItemFactory @Inject constructor( + private val dimensionConverter: DimensionConverter, + private val timelineMediaSizeProvider: TimelineMediaSizeProvider, + private val avatarSizeProvider: AvatarSizeProvider, +) { + + fun create( + liveLocationContent: LiveLocationBeaconContent, + highlight: Boolean, + attributes: AbsMessageItem.Attributes, + ): VectorEpoxyModel<*>? { + // TODO handle location received and stopped states + return when { + isLiveRunning(liveLocationContent) -> buildStartLiveItem(highlight, attributes) + else -> null + } + } + + private fun isLiveRunning(liveLocationContent: LiveLocationBeaconContent): Boolean { + return liveLocationContent.getBestBeaconInfo()?.isLive.orFalse() && hasTimeoutElapsed(liveLocationContent).not() + } + + private fun hasTimeoutElapsed(liveLocationContent: LiveLocationBeaconContent): Boolean { + return liveLocationContent + .getBestTimestampAsMilliseconds() + ?.let { startTimestamp -> + val now = LocalDateTime.now() + val startOfLive = DateProvider.toLocalDateTime(startTimestamp) + val timeout = liveLocationContent.getBestBeaconInfo()?.timeout ?: 0L + val endOfLive = startOfLive.plus(timeout, ChronoUnit.MILLIS) + now.isAfter(endOfLive) + }.orTrue() + } + + private fun buildStartLiveItem( + highlight: Boolean, + attributes: AbsMessageItem.Attributes, + ): MessageLiveLocationStartItem { + val width = timelineMediaSizeProvider.getMaxSize().first + val height = dimensionConverter.dpToPx(200) + + return MessageLiveLocationStartItem_() + .attributes(attributes) + .mapWidth(width) + .mapHeight(height) + .highlighted(highlight) + .leftGuideline(avatarSizeProvider.leftGuideline) + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 1564490ccd..78913985c8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -50,7 +50,6 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageImageVideoItem import im.vector.app.features.home.room.detail.timeline.item.MessageImageVideoItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData -import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocationStartItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageLocationItem import im.vector.app.features.home.room.detail.timeline.item.MessageLocationItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem @@ -147,6 +146,7 @@ class MessageItemFactory @Inject constructor( private val locationPinProvider: LocationPinProvider, private val vectorPreferences: VectorPreferences, private val urlMapProvider: UrlMapProvider, + private val liveLocationMessageItemFactory: LiveLocationMessageItemFactory, ) { // TODO inject this properly? @@ -214,19 +214,7 @@ class MessageItemFactory @Inject constructor( buildMessageTextItem(messageContent.body, false, informationData, highlight, callback, attributes) } } - is LiveLocationBeaconContent -> { - // TODO extract in method and in a dedicated factory class - // TODO check if it is still live and that the timeout has not elapsed - val width = timelineMediaSizeProvider.getMaxSize().first - val height = dimensionConverter.dpToPx(200) - - return MessageLiveLocationStartItem_() - .attributes(attributes) - .mapWidth(width) - .mapHeight(height) - .highlighted(highlight) - .leftGuideline(avatarSizeProvider.leftGuideline) - } + is LiveLocationBeaconContent -> liveLocationMessageItemFactory.create(messageContent, highlight, attributes) else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes) } return messageItem?.apply {