diff --git a/changelog.d/6635.misc b/changelog.d/6635.misc
new file mode 100644
index 0000000000..6546659d11
--- /dev/null
+++ b/changelog.d/6635.misc
@@ -0,0 +1 @@
+[Location Share] - Expanded map state when no more live location shares
diff --git a/library/ui-styles/src/main/res/values/stylable_location_live_ended_banner_view.xml b/library/ui-styles/src/main/res/values/stylable_location_live_ended_banner_view.xml
new file mode 100644
index 0000000000..81e377d39b
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_location_live_ended_banner_view.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationInactiveItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationInactiveItem.kt
index bc6e96b0ee..fae8091f06 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationInactiveItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationInactiveItem.kt
@@ -42,7 +42,7 @@ abstract class MessageLiveLocationInactiveItem :
override fun getViewStubId() = STUB_ID
class Holder : AbsMessageItem.Holder(STUB_ID) {
- val bannerImageView by bind(R.id.locationLiveInactiveBanner)
+ val bannerImageView by bind(R.id.locationLiveEndedBannerBackground)
val noLocationMapImageView by bind(R.id.locationLiveInactiveMap)
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationItem.kt
index 84080eaad9..b35b4dff8b 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationItem.kt
@@ -26,8 +26,8 @@ import im.vector.app.core.resources.toTimestamp
import im.vector.app.core.utils.DimensionConverter
import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout
-import im.vector.app.features.location.live.LocationLiveMessageBannerView
import im.vector.app.features.location.live.LocationLiveMessageBannerViewState
+import im.vector.app.features.location.live.LocationLiveRunningBannerView
import org.threeten.bp.LocalDateTime
@EpoxyModelClass
@@ -52,9 +52,9 @@ abstract class MessageLiveLocationItem : AbsMessageLocationItem(R.id.locationLiveMessageBanner)
+ val locationLiveRunningBanner by bind(R.id.locationLiveRunningBanner)
}
companion object {
diff --git a/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt b/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt
index 1f9cb44c91..491386ba64 100644
--- a/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt
+++ b/vector/src/main/java/im/vector/app/features/location/MapTilerMapView.kt
@@ -22,6 +22,7 @@ import android.util.AttributeSet
import android.view.Gravity
import android.widget.ImageView
import androidx.core.content.ContextCompat
+import androidx.core.content.res.use
import androidx.core.view.marginBottom
import androidx.core.view.marginTop
import androidx.core.view.updateLayoutParams
@@ -60,17 +61,13 @@ class MapTilerMapView @JvmOverloads constructor(
private var dimensionConverter: DimensionConverter? = null
init {
- context.theme.obtainStyledAttributes(
+ context.obtainStyledAttributes(
attrs,
R.styleable.MapTilerMapView,
0,
0
- ).run {
- try {
- setLocateButtonVisibility(this)
- } finally {
- recycle()
- }
+ ).use {
+ setLocateButtonVisibility(it)
}
dimensionConverter = DimensionConverter(resources)
}
diff --git a/vector/src/main/java/im/vector/app/features/location/live/LocationLiveEndedBannerView.kt b/vector/src/main/java/im/vector/app/features/location/live/LocationLiveEndedBannerView.kt
new file mode 100644
index 0000000000..82fa17a625
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/location/live/LocationLiveEndedBannerView.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.location.live
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.res.use
+import androidx.core.view.updateLayoutParams
+import im.vector.app.R
+import im.vector.app.databinding.ViewLocationLiveEndedBannerBinding
+
+private const val BACKGROUND_ALPHA = 0.75f
+
+class LocationLiveEndedBannerView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+ private val binding = ViewLocationLiveEndedBannerBinding.inflate(
+ LayoutInflater.from(context),
+ this
+ )
+
+ init {
+ context.obtainStyledAttributes(
+ attrs,
+ R.styleable.LocationLiveEndedBannerView,
+ 0,
+ 0
+ ).use {
+ setBackgroundAlpha(it)
+ setIconMarginStart(it)
+ }
+ }
+
+ private fun setBackgroundAlpha(typedArray: TypedArray) {
+ val withAlpha = typedArray.getBoolean(R.styleable.LocationLiveEndedBannerView_locLiveEndedBkgWithAlpha, false)
+ binding.locationLiveEndedBannerBackground.alpha = if (withAlpha) BACKGROUND_ALPHA else 1f
+ }
+
+ private fun setIconMarginStart(typedArray: TypedArray) {
+ val margin = typedArray.getDimensionPixelOffset(R.styleable.LocationLiveEndedBannerView_locLiveEndedIconMarginStart, 0)
+ binding.locationLiveEndedBannerIcon.updateLayoutParams {
+ marginStart = margin
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/location/live/LocationLiveMessageBannerView.kt b/vector/src/main/java/im/vector/app/features/location/live/LocationLiveRunningBannerView.kt
similarity index 87%
rename from vector/src/main/java/im/vector/app/features/location/live/LocationLiveMessageBannerView.kt
rename to vector/src/main/java/im/vector/app/features/location/live/LocationLiveRunningBannerView.kt
index 51c7caed3a..4ca8475da1 100644
--- a/vector/src/main/java/im/vector/app/features/location/live/LocationLiveMessageBannerView.kt
+++ b/vector/src/main/java/im/vector/app/features/location/live/LocationLiveRunningBannerView.kt
@@ -31,34 +31,34 @@ import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners
import im.vector.app.R
import im.vector.app.core.glide.GlideApp
import im.vector.app.core.utils.TextUtils
-import im.vector.app.databinding.ViewLocationLiveMessageBannerBinding
+import im.vector.app.databinding.ViewLocationLiveRunningBannerBinding
import im.vector.app.features.themes.ThemeUtils
import org.threeten.bp.Duration
private const val REMAINING_TIME_COUNTER_INTERVAL_IN_MS = 1000L
-class LocationLiveMessageBannerView @JvmOverloads constructor(
+class LocationLiveRunningBannerView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
- private val binding = ViewLocationLiveMessageBannerBinding.inflate(
+ private val binding = ViewLocationLiveRunningBannerBinding.inflate(
LayoutInflater.from(context),
this
)
val stopButton: Button
- get() = binding.locationLiveMessageBannerStop
+ get() = binding.locationLiveRunningBannerStop
private val background: ImageView
- get() = binding.locationLiveMessageBannerBackground
+ get() = binding.locationLiveRunningBannerBackground
private val title: TextView
- get() = binding.locationLiveMessageBannerTitle
+ get() = binding.locationLiveRunningBannerTitle
private val subTitle: TextView
- get() = binding.locationLiveMessageBannerSubTitle
+ get() = binding.locationLiveRunningBannerSubTitle
private var countDownTimer: CountDownTimer? = null
@@ -70,7 +70,7 @@ class LocationLiveMessageBannerView @JvmOverloads constructor(
GlideApp.with(context)
.load(ColorDrawable(ThemeUtils.getColor(context, android.R.attr.colorBackground)))
- .placeholder(binding.locationLiveMessageBannerBackground.drawable)
+ .placeholder(binding.locationLiveRunningBannerBackground.drawable)
.transform(GranularRoundedCorners(0f, 0f, viewState.bottomEndCornerRadiusInDp, viewState.bottomStartCornerRadiusInDp))
.into(background)
}
@@ -109,14 +109,14 @@ class LocationLiveMessageBannerView @JvmOverloads constructor(
if (viewState.isStopButtonCenteredVertically) {
constraintSet.connect(
- R.id.locationLiveMessageBannerStop,
+ R.id.locationLiveRunningBannerStop,
ConstraintSet.BOTTOM,
- R.id.locationLiveMessageBannerBackground,
+ R.id.locationLiveRunningBannerBackground,
ConstraintSet.BOTTOM,
0
)
} else {
- constraintSet.clear(R.id.locationLiveMessageBannerStop, ConstraintSet.BOTTOM)
+ constraintSet.clear(R.id.locationLiveRunningBannerStop, ConstraintSet.BOTTOM)
}
constraintSet.applyTo(parentLayout)
diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt
index e19580f13b..3aacd70f0e 100644
--- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt
@@ -22,6 +22,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.drawable.toBitmap
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
@@ -57,7 +59,6 @@ import javax.inject.Inject
/**
* Screen showing a map with all the current users sharing their live location in a room.
*/
-
@AndroidEntryPoint
class LocationLiveMapViewFragment @Inject constructor() : VectorBaseFragment() {
@@ -110,13 +111,6 @@ class LocationLiveMapViewFragment @Inject constructor() : VectorBaseFragment
- val bottomSheetHeight = BottomSheetBehavior.from(views.bottomSheet).peekHeight
- mapboxMap.uiSettings.apply {
- // Place copyright above the user list bottom sheet
- setLogoMargins(dimensionConverter.dpToPx(8), 0, 0, bottomSheetHeight + dimensionConverter.dpToPx(8))
- setAttributionMargins(dimensionConverter.dpToPx(96), 0, 0, bottomSheetHeight + dimensionConverter.dpToPx(8))
- }
-
lifecycleScope.launch {
mapboxMap.setStyle(urlMapProvider.getMapUrl()) { style ->
mapStyle = style
@@ -173,9 +167,47 @@ class LocationLiveMapViewFragment @Inject constructor() : VectorBaseFragment) {
+ if (userLocations.isEmpty()) {
+ showEndedLiveBanner()
+ } else {
+ showUserList(userLocations)
+ }
+ }
+
+ private fun showEndedLiveBanner() {
+ views.bottomSheet.isGone = true
+ views.liveLocationMapFragmentEndedBanner.isVisible = true
+ updateCopyrightMargin(bottomOffset = views.liveLocationMapFragmentEndedBanner.height)
+ }
+
+ private fun showUserList(userLocations: List) {
+ val bottomSheetHeight = BottomSheetBehavior.from(views.bottomSheet).peekHeight
+ updateCopyrightMargin(bottomOffset = bottomSheetHeight)
+ views.bottomSheet.isVisible = true
+ views.liveLocationMapFragmentEndedBanner.isGone = true
bottomSheetController.setData(userLocations)
}
+ private fun updateCopyrightMargin(bottomOffset: Int) {
+ getOrCreateSupportMapFragment().getMapAsync { mapboxMap ->
+ mapboxMap.uiSettings.apply {
+ // Place copyright above the user list bottom sheet
+ setLogoMargins(
+ dimensionConverter.dpToPx(COPYRIGHT_MARGIN_DP),
+ 0,
+ 0,
+ bottomOffset + dimensionConverter.dpToPx(COPYRIGHT_MARGIN_DP)
+ )
+ setAttributionMargins(
+ dimensionConverter.dpToPx(COPYRIGHT_ATTRIBUTION_MARGIN_DP),
+ 0,
+ 0,
+ bottomOffset + dimensionConverter.dpToPx(COPYRIGHT_MARGIN_DP)
+ )
+ }
+ }
+ }
+
private fun updateMap(userLiveLocations: List) {
symbolManager?.let { sManager ->
val latLngBoundsBuilder = LatLngBounds.Builder()
@@ -278,5 +310,7 @@ class LocationLiveMapViewFragment @Inject constructor() : VectorBaseFragment
+ android:layout_gravity="center" />
+
+
diff --git a/vector/src/main/res/layout/item_timeline_event_live_location_inactive_stub.xml b/vector/src/main/res/layout/item_timeline_event_live_location_inactive_stub.xml
index ba0ff33230..53b740bb4e 100644
--- a/vector/src/main/res/layout/item_timeline_event_live_location_inactive_stub.xml
+++ b/vector/src/main/res/layout/item_timeline_event_live_location_inactive_stub.xml
@@ -15,16 +15,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
+ app:locLiveEndedBkgWithAlpha="true"
+ app:locLiveEndedIconMarginStart="8dp" />
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/layout/view_location_live_message_banner.xml b/vector/src/main/res/layout/view_location_live_running_banner.xml
similarity index 71%
rename from vector/src/main/res/layout/view_location_live_message_banner.xml
rename to vector/src/main/res/layout/view_location_live_running_banner.xml
index f13696a5c7..5bf8c8258d 100644
--- a/vector/src/main/res/layout/view_location_live_message_banner.xml
+++ b/vector/src/main/res/layout/view_location_live_running_banner.xml
@@ -7,7 +7,7 @@
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
+ app:layout_constraintTop_toTopOf="@id/locationLiveRunningBannerBackground" />