Show descriptions for locations.
Descriptions show in the same message bubble above the map in the timeline, and in a bar at the top of the expanded map view.
This commit is contained in:
parent
02fa8aaf46
commit
77470b9a97
8 changed files with 31 additions and 15 deletions
|
|
@ -17,7 +17,6 @@
|
||||||
package io.element.android.features.location.impl.show
|
package io.element.android.features.location.impl.show
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
package io.element.android.features.messages.impl.timeline.components.event
|
package io.element.android.features.messages.impl.timeline.components.event
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -28,26 +30,36 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
||||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContentProvider
|
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContentProvider
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TimelineItemLocationView(
|
fun TimelineItemLocationView(
|
||||||
content: TimelineItemLocationContent,
|
content: TimelineItemLocationContent,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
StaticMapView(
|
Column(modifier = modifier.fillMaxWidth()) {
|
||||||
modifier = modifier
|
content.description?.let {
|
||||||
.fillMaxWidth()
|
Text(
|
||||||
.heightIn(max = 188.dp),
|
text = it,
|
||||||
lat = content.location.lat,
|
modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp),
|
||||||
lon = content.location.lon,
|
)
|
||||||
zoom = 15.0,
|
}
|
||||||
contentDescription = content.body
|
|
||||||
)
|
StaticMapView(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.heightIn(max = 188.dp),
|
||||||
|
lat = content.location.lat,
|
||||||
|
lon = content.location.lon,
|
||||||
|
zoom = 15.0,
|
||||||
|
contentDescription = content.body
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
internal fun TimelineItemLocationViewLightPreview(@PreviewParameter(TimelineItemLocationContentProvider::class) content: TimelineItemLocationContent) =
|
internal fun TimelineItemLocationViewPreview(@PreviewParameter(TimelineItemLocationContentProvider::class) content: TimelineItemLocationContent) =
|
||||||
ElementPreviewLight { ContentToPreview(content) }
|
ElementPreviewLight { ContentToPreview(content) }
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||||
TimelineItemLocationContent(
|
TimelineItemLocationContent(
|
||||||
body = messageType.body,
|
body = messageType.body,
|
||||||
location = location,
|
location = location,
|
||||||
|
description = messageType.description
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ class TimelineItemEventContentProvider : PreviewParameterProvider<TimelineItemEv
|
||||||
aTimelineItemFileContent("A file.pdf"),
|
aTimelineItemFileContent("A file.pdf"),
|
||||||
aTimelineItemFileContent("A bigger file name which doesn't fit.pdf"),
|
aTimelineItemFileContent("A bigger file name which doesn't fit.pdf"),
|
||||||
aTimelineItemLocationContent(),
|
aTimelineItemLocationContent(),
|
||||||
|
aTimelineItemLocationContent("Location description"),
|
||||||
aTimelineItemNoticeContent(),
|
aTimelineItemNoticeContent(),
|
||||||
aTimelineItemRedactedContent(),
|
aTimelineItemRedactedContent(),
|
||||||
aTimelineItemTextContent(),
|
aTimelineItemTextContent(),
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,16 @@ open class TimelineItemLocationContentProvider : PreviewParameterProvider<Timeli
|
||||||
override val values: Sequence<TimelineItemLocationContent>
|
override val values: Sequence<TimelineItemLocationContent>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aTimelineItemLocationContent(),
|
aTimelineItemLocationContent(),
|
||||||
|
aTimelineItemLocationContent("This is a description!"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun aTimelineItemLocationContent() = TimelineItemLocationContent(
|
fun aTimelineItemLocationContent(description: String? = null) = TimelineItemLocationContent(
|
||||||
body = "User location geo:52.2445,0.7186;u=5000",
|
body = "User location geo:52.2445,0.7186;u=5000",
|
||||||
location = Location(
|
location = Location(
|
||||||
lat = 52.2445,
|
lat = 52.2445,
|
||||||
lon = 0.7186,
|
lon = 0.7186,
|
||||||
accuracy = 5000f,
|
accuracy = 5000f,
|
||||||
)
|
),
|
||||||
|
description = description,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ class DefaultRoomLastMessageFormatterTests {
|
||||||
AudioMessageType(body, MediaSource("url"), null),
|
AudioMessageType(body, MediaSource("url"), null),
|
||||||
ImageMessageType(body, MediaSource("url"), null),
|
ImageMessageType(body, MediaSource("url"), null),
|
||||||
FileMessageType(body, MediaSource("url"), null),
|
FileMessageType(body, MediaSource("url"), null),
|
||||||
LocationMessageType(body, "geo:1,2"),
|
LocationMessageType(body, "geo:1,2", null),
|
||||||
NoticeMessageType(body, null),
|
NoticeMessageType(body, null),
|
||||||
EmoteMessageType(body, null),
|
EmoteMessageType(body, null),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ data class ImageMessageType(
|
||||||
data class LocationMessageType(
|
data class LocationMessageType(
|
||||||
val body: String,
|
val body: String,
|
||||||
val geoUri: String,
|
val geoUri: String,
|
||||||
|
val description: String?,
|
||||||
) : MessageType
|
) : MessageType
|
||||||
|
|
||||||
data class AudioMessageType(
|
data class AudioMessageType(
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class EventMessageMapper {
|
||||||
ImageMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
ImageMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
|
||||||
}
|
}
|
||||||
is MessageType.Location -> {
|
is MessageType.Location -> {
|
||||||
LocationMessageType(type.content.body, type.content.geoUri)
|
LocationMessageType(type.content.body, type.content.geoUri, type.content.description)
|
||||||
}
|
}
|
||||||
is MessageType.Notice -> {
|
is MessageType.Notice -> {
|
||||||
NoticeMessageType(type.content.body, type.content.formatted?.map())
|
NoticeMessageType(type.content.body, type.content.formatted?.map())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue