Skip to content

Commit

Permalink
feat: display received location messages - default placeholder (WPB-5…
Browse files Browse the repository at this point in the history
…483) (#2503)
  • Loading branch information
yamilmedina authored Dec 8, 2023
1 parent b7d4a58 commit d75f286
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ fun MessagePreview.uiLastMessageContent(): UILastMessageContent {

is WithUser.MembersCreationAdded -> UILastMessageContent.None
is WithUser.MembersFailedToAdd -> UILastMessageContent.None
is WithUser.Location -> UILastMessageContent.SenderWithMessage(
userUIText,
UIText.StringResource(
if (isSelfMessage) R.string.last_message_self_user_shared_location
else R.string.last_message_other_user_shared_location
)
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package com.wire.android.mapper
import com.wire.android.R
import com.wire.android.model.ImageAsset
import com.wire.android.ui.home.conversations.findUser
import com.wire.android.ui.home.conversations.model.DEFAULT_LOCATION_ZOOM
import com.wire.android.ui.home.conversations.model.DeliveryStatusContent
import com.wire.android.ui.home.conversations.model.MessageBody
import com.wire.android.ui.home.conversations.model.MessageButton
Expand Down Expand Up @@ -121,9 +122,23 @@ class RegularMessageMapper @Inject constructor(
)
}

is MessageContent.Location -> toLocation(content, userList, message)

else -> toText(message.conversationId, content, userList, message.deliveryStatus)
}

private fun toLocation(
content: MessageContent.Location,
userList: List<User>,
message: Message.Regular
) = UIMessageContent.Location(
latitude = content.latitude,
longitude = content.longitude,
name = content.name.orEmpty(),
zoom = content.zoom ?: DEFAULT_LOCATION_ZOOM,
deliveryStatus = mapRecipientsFailure(userList, message.deliveryStatus)
)

private fun mapAudio(
assetContent: AssetContent,
metadata: AssetContent.AssetMetadata.Audio,
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/kotlin/com/wire/android/notification/Models.kt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ enum class CommentResId(@StringRes val value: Int) {
MISSED_CALL(R.string.notification_missed_call),
NOT_SUPPORTED(R.string.notification_not_supported_issue),
KNOCK(R.string.notification_knock),
LOCATION(R.string.notification_shared_location),
}

fun LocalNotification.Conversation.intoNotificationConversation(): NotificationConversation {
Expand Down Expand Up @@ -233,4 +234,5 @@ fun LocalNotificationCommentType.intoCommentResId(): CommentResId =
LocalNotificationCommentType.REACTION -> CommentResId.REACTION
LocalNotificationCommentType.MISSED_CALL -> CommentResId.MISSED_CALL
LocalNotificationCommentType.NOT_SUPPORTED_YET -> CommentResId.NOT_SUPPORTED
LocalNotificationCommentType.LOCATION -> CommentResId.LOCATION
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ import com.wire.android.ui.home.conversations.model.messagetypes.asset.Restricte
import com.wire.android.ui.home.conversations.model.messagetypes.asset.RestrictedGenericFileMessage
import com.wire.android.ui.home.conversations.model.messagetypes.audio.AudioMessage
import com.wire.android.ui.home.conversations.model.messagetypes.image.ImageMessageParams
import com.wire.android.ui.home.conversations.model.messagetypes.location.LocationMessageContent
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireTypography
import com.wire.android.util.launchGeoIntent
import com.wire.kalium.logic.data.message.Message
import com.wire.kalium.logic.data.user.UserId

Expand Down Expand Up @@ -635,6 +637,23 @@ private fun MessageContent(
}
}

is UIMessageContent.Location -> with(messageContent) {
val context = LocalContext.current
val locationUrl = stringResource(urlCoordinates, zoom, latitude, longitude)
Column {
LocationMessageContent(
locationName = name,
locationUrl = locationUrl,
onLocationClick = Clickable(
enabled = message.isAvailable,
onClick = { launchGeoIntent(latitude, longitude, name, locationUrl, context) },
onLongClick = onLongClick
)
)
PartialDeliveryInformation(deliveryStatus)
}
}

UIMessageContent.Deleted -> {}
null -> {
throw NullPointerException("messageContent is null")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ sealed class UIMessageContent {
override val deliveryStatus: DeliveryStatusContent = DeliveryStatusContent.CompleteDelivery
) : Regular(), PartialDeliverable

@Stable
data class Location(
val latitude: Float,
val longitude: Float,
val name: String,
val zoom: Int = DEFAULT_LOCATION_ZOOM,
@StringRes val urlCoordinates: Int = R.string.url_maps_location_coordinates_fallback,
override val deliveryStatus: DeliveryStatusContent = DeliveryStatusContent.CompleteDelivery
) : Regular(), PartialDeliverable

sealed class SystemMessage(
@DrawableRes val iconResId: Int?,
@StringRes open val stringResId: Int,
Expand Down Expand Up @@ -558,3 +568,5 @@ data class MessageButton(
val text: String,
val isSelected: Boolean,
)

const val DEFAULT_LOCATION_ZOOM = 20
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.android.ui.home.conversations.model.messagetypes.location

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
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.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp
import com.wire.android.R
import com.wire.android.model.Clickable
import com.wire.android.ui.common.clickable
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography
import com.wire.android.util.ui.PreviewMultipleThemes

@Composable
fun LocationMessageContent(
locationName: String,
locationUrl: String,
onLocationClick: Clickable
) {
Column(
modifier = Modifier
.clickable(onLocationClick)
.padding(top = dimensions().spacing4x)
.clip(shape = RoundedCornerShape(dimensions().messageAssetBorderRadius))
.border(
width = dimensions().spacing1x,
color = MaterialTheme.wireColorScheme.secondaryButtonDisabledOutline,
shape = RoundedCornerShape(dimensions().messageAssetBorderRadius)
)
.background(
color = MaterialTheme.wireColorScheme.surfaceVariant,
shape = RoundedCornerShape(dimensions().messageAssetBorderRadius)
)
.height(dimensions().spacing64x),
verticalArrangement = Arrangement.SpaceEvenly,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(PaddingValues(horizontal = dimensions().spacing8x)),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.ic_location),
contentDescription = stringResource(id = R.string.content_description_location_icon),
modifier = Modifier.size(MaterialTheme.wireDimensions.wireIconButtonSize)
)
Spacer(modifier = Modifier.width(dimensions().spacing4x))
Text(
text = locationName,
style = MaterialTheme.wireTypography.body02,
fontSize = 15.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
Text(
text = locationUrl,
style = MaterialTheme.wireTypography.subline01.copy(color = MaterialTheme.wireColorScheme.secondaryText),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
modifier = Modifier.padding(
PaddingValues(
bottom = dimensions().spacing8x,
start = dimensions().spacing8x,
end = dimensions().spacing8x
)
)
)
}
}

@Composable
@PreviewMultipleThemes
fun PreviewLocationMessageContent() {
LocationMessageContent(
locationName = "Rapa Nui",
locationUrl = "https://www.google.com/maps/place/Rapa+Nui",
onLocationClick = Clickable()
)
}
49 changes: 49 additions & 0 deletions app/src/main/kotlin/com/wire/android/util/CommonIntentUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.android.util

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import com.wire.android.appLogger

// geo intent url scheme
internal const val GEO_INTENT_URL = "geo:0,0?q=%f,%f"

/**
* Launches a geo intent with the given latitude and longitude.
* If no app/activity can be found to handle the [GEO_INTENT_URL], a [fallbackUrl] is used.
*/
fun launchGeoIntent(
latitude: Float,
longitude: Float,
placeName: String?,
fallbackUrl: String,
context: Context
) {
val geoStringUrl = StringBuilder(String.format(GEO_INTENT_URL, latitude, longitude))
if (!placeName.isNullOrEmpty()) geoStringUrl.append("(${Uri.encode(placeName)})")
try {
context.startActivity(Intent(Intent.ACTION_VIEW, geoStringUrl.toString().toUri()))
} catch (e: ActivityNotFoundException) {
appLogger.e("No activity found to handle geo intent, fallback to url", e)
context.startActivity(Intent(Intent.ACTION_VIEW, fallbackUrl.toUri()))
}
}
8 changes: 6 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Wire
~ Copyright (C) 2023 Wire Swiss GmbH
~
Expand Down Expand Up @@ -174,6 +173,7 @@
<string name="content_description_mls_certificate_valid">All devices of all participants have a valid MLS certificate</string>
<string name="content_description_proteus_certificate_valid">All of all participants are verified (Proteus)</string>
<string name="content_description_jump_to_last_message">Scroll down to last message, button</string>
<string name="content_description_location_icon">Location item</string>
<!-- Non translatable strings-->
<string name="url_support" translatable="false">https://support.wire.com</string>
<string name="url_decryption_failure_learn_more" translatable="false">https://support.wire.com/hc/articles/207948115-Why-was-I-notified-that-a-message-from-a-contact-was-not-received-</string>
Expand All @@ -186,6 +186,7 @@
<string name="url_federation_support" translatable="false">https://support.wire.com/hc/categories/4719917054365-Federation</string>
<string name="url_create_account_learn_more" translatable="false">https://support.wire.com/hc/articles/115004082129</string>
<string name="url_android_release_notes" translatable="false">https://medium.com/wire-news/android-updates/home</string>
<string name="url_maps_location_coordinates_fallback" translatable="false">http://maps.google.com/maps?z=%1d&amp;q=loc:%2f+%2f</string>
<!-- Navigation -->
<string name="vault_screen_title">Vault</string>
<string name="archive_screen_title">Archive</string>
Expand Down Expand Up @@ -659,6 +660,8 @@
<string name="last_message_other_user_shared_video">shared a video.</string>
<string name="last_message_self_user_shared_audio">shared an audio message.</string>
<string name="last_message_other_user_shared_audio">shared an audio message.</string>
<string name="last_message_self_user_shared_location">shared a location.</string>
<string name="last_message_other_user_shared_location">shared a location.</string>
<string name="last_message_self_user_knock">pinged.</string>
<string name="last_message_other_user_knock">pinged.</string>
<string name="last_message_call">called.</string>
Expand Down Expand Up @@ -775,6 +778,7 @@
<string name="phone_label">Phone</string>
<!-- Notifications -->
<string name="notification_shared_picture">Shared a picture</string>
<string name="notification_shared_location">Shared a location</string>
<string name="notification_shared_file">Shared a file</string>
<string name="notification_reacted">Added a reaction</string>
<string name="notification_missed_call">Missed call</string>
Expand Down
2 changes: 1 addition & 1 deletion kalium
Submodule kalium updated 27 files
+2 βˆ’8 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepository.kt
+3 βˆ’3 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/keypackage/KeyPackageRepository.kt
+4 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/Message.kt
+9 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/MessageContent.kt
+21 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/MessageMapper.kt
+1 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/PersistMessageUseCase.kt
+28 βˆ’2 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapper.kt
+1 βˆ’1 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/notification/LocalNotification.kt
+1 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PersistMigratedMessagesUseCase.kt
+2 βˆ’0 ...src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandler.kt
+9 βˆ’70 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt
+2 βˆ’2 network/src/commonMain/kotlin/com/wire/kalium/network/api/base/authenticated/keypackage/KeyPackageApi.kt
+2 βˆ’2 network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/KeyPackageApiV0.kt
+4 βˆ’4 network/src/commonMain/kotlin/com/wire/kalium/network/api/v5/authenticated/KeyPackageApiV5.kt
+31 βˆ’10 network/src/commonMain/kotlin/com/wire/kalium/network/utils/NetworkUtils.kt
+77 βˆ’0 network/src/commonTest/kotlin/com/wire/kalium/api/v5/MLSMessageApiV5Test.kt
+6 βˆ’1 persistence/src/commonMain/db_user/com/wire/kalium/persistence/MessageDetailsView.sq
+1 βˆ’1 persistence/src/commonMain/db_user/com/wire/kalium/persistence/MessagePreview.sq
+18 βˆ’1 persistence/src/commonMain/db_user/com/wire/kalium/persistence/Messages.sq
+1 βˆ’1 persistence/src/commonMain/db_user/com/wire/kalium/persistence/Notification.sq
+171 βˆ’0 persistence/src/commonMain/db_user/migrations/68.sqm
+8 βˆ’1 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageEntity.kt
+11 βˆ’0 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageInsertExtension.kt
+12 βˆ’2 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageMapper.kt
+10 βˆ’1 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/TableMapper.kt
+2 βˆ’1 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/UserDatabaseBuilder.kt
+10 βˆ’2 persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/message/MessageMapperTest.kt

0 comments on commit d75f286

Please sign in to comment.