Skip to content

Commit 9976b3b

Browse files
authored
Merge pull request #6567 from vector-im/feature/ons/share_location_with_other_apps
Share location with other apps (PSG-242)
2 parents 70c6223 + c408f82 commit 9976b3b

File tree

7 files changed

+133
-0
lines changed

7 files changed

+133
-0
lines changed

changelog.d/6567.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Share location with other apps
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.location.live.map
18+
19+
import android.content.Context
20+
import android.view.View
21+
import android.view.ViewGroup
22+
import android.widget.PopupWindow
23+
import im.vector.app.R
24+
import im.vector.app.databinding.ViewLiveLocationMarkerPopupBinding
25+
26+
class LocationLiveMapMarkerOptionsDialog(
27+
context: Context,
28+
) : PopupWindow() {
29+
30+
interface Callback {
31+
fun onShareLocationClicked()
32+
}
33+
34+
private val views: ViewLiveLocationMarkerPopupBinding
35+
36+
var callback: Callback? = null
37+
38+
init {
39+
contentView = View.inflate(context, R.layout.view_live_location_marker_popup, null)
40+
41+
views = ViewLiveLocationMarkerPopupBinding.bind(contentView)
42+
43+
width = ViewGroup.LayoutParams.WRAP_CONTENT
44+
height = ViewGroup.LayoutParams.WRAP_CONTENT
45+
inputMethodMode = INPUT_METHOD_NOT_NEEDED
46+
isFocusable = true
47+
isTouchable = true
48+
49+
contentView.setOnClickListener {
50+
callback?.onShareLocationClicked()
51+
}
52+
}
53+
54+
fun show(anchorView: View) {
55+
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
56+
// By default the left side of the dialog is aligned with the pin. We need shift it to the left to make it's center aligned with the pin.
57+
showAsDropDown(anchorView, -contentView.measuredWidth / 2, 0)
58+
}
59+
}

vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap
3333
import com.mapbox.mapboxsdk.maps.MapboxMapOptions
3434
import com.mapbox.mapboxsdk.maps.Style
3535
import com.mapbox.mapboxsdk.maps.SupportMapFragment
36+
import com.mapbox.mapboxsdk.plugins.annotation.Symbol
3637
import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager
3738
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
3839
import com.mapbox.mapboxsdk.style.layers.Property
@@ -42,6 +43,7 @@ import im.vector.app.core.extensions.addChildFragment
4243
import im.vector.app.core.extensions.configureWith
4344
import im.vector.app.core.platform.VectorBaseFragment
4445
import im.vector.app.core.utils.DimensionConverter
46+
import im.vector.app.core.utils.openLocation
4547
import im.vector.app.databinding.FragmentLocationLiveMapViewBinding
4648
import im.vector.app.features.location.UrlMapProvider
4749
import im.vector.app.features.location.zoomToBounds
@@ -120,6 +122,10 @@ class LocationLiveMapViewFragment @Inject constructor() : VectorBaseFragment<Fra
120122
this@LocationLiveMapViewFragment.mapboxMap = WeakReference(mapboxMap)
121123
symbolManager = SymbolManager(mapFragment.view as MapView, mapboxMap, style).apply {
122124
iconAllowOverlap = true
125+
addClickListener {
126+
onSymbolClicked(it)
127+
true
128+
}
123129
}
124130
pendingLiveLocations
125131
.takeUnless { it.isEmpty() }
@@ -129,6 +135,31 @@ class LocationLiveMapViewFragment @Inject constructor() : VectorBaseFragment<Fra
129135
}
130136
}
131137

138+
private fun onSymbolClicked(symbol: Symbol?) {
139+
symbol?.let {
140+
val screenLocation = mapboxMap?.get()?.projection?.toScreenLocation(it.latLng)
141+
views.liveLocationPopupAnchor.apply {
142+
x = screenLocation?.x ?: 0f
143+
y = (screenLocation?.y ?: 0f) - views.liveLocationPopupAnchor.height
144+
}
145+
146+
LocationLiveMapMarkerOptionsDialog(requireContext())
147+
.apply {
148+
callback = object : LocationLiveMapMarkerOptionsDialog.Callback {
149+
override fun onShareLocationClicked() {
150+
shareLocation(symbol)
151+
dismiss()
152+
}
153+
}
154+
}
155+
.show(views.liveLocationPopupAnchor)
156+
}
157+
}
158+
159+
private fun shareLocation(symbol: Symbol) {
160+
openLocation(requireActivity(), symbol.latLng.latitude, symbol.latLng.longitude)
161+
}
162+
132163
private fun getOrCreateSupportMapFragment() =
133164
childFragmentManager.findFragmentByTag(MAP_FRAGMENT_TAG) as? SupportMapFragment
134165
?: run {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android">
3+
<corners android:radius="8dp" />
4+
<solid android:color="?android:colorBackground" />
5+
</shape>

vector/src/main/res/layout/fragment_location_live_map_view.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
android:layout_height="match_parent"
77
android:background="@drawable/bg_live_location_users_bottom_sheet">
88

9+
<View
10+
android:id="@+id/liveLocationPopupAnchor"
11+
android:layout_width="40dp"
12+
android:layout_height="40dp" />
13+
914
<FrameLayout
1015
android:id="@+id/liveLocationMapFragmentContainer"
1116
android:layout_width="match_parent"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:layout_width="wrap_content"
5+
android:layout_height="wrap_content"
6+
android:background="@drawable/bg_live_location_marker_popup"
7+
android:elevation="8dp"
8+
android:padding="8dp">
9+
10+
<ImageView
11+
android:id="@+id/shareLocationImageView"
12+
android:layout_width="wrap_content"
13+
android:layout_height="wrap_content"
14+
android:importantForAccessibility="no"
15+
android:src="@drawable/ic_share_external"
16+
app:layout_constraintBottom_toBottomOf="parent"
17+
app:layout_constraintStart_toStartOf="parent"
18+
app:layout_constraintTop_toTopOf="parent"
19+
app:tint="?vctr_content_tertiary" />
20+
21+
<TextView
22+
style="@style/TextAppearance.Vector.Caption"
23+
android:layout_width="wrap_content"
24+
android:layout_height="wrap_content"
25+
android:layout_marginStart="4dp"
26+
android:text="@string/live_location_share_location_item_share"
27+
app:layout_constraintBottom_toBottomOf="parent"
28+
app:layout_constraintStart_toEndOf="@id/shareLocationImageView"
29+
app:layout_constraintTop_toTopOf="parent" />
30+
31+
</androidx.constraintlayout.widget.ConstraintLayout>

vector/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,6 +3116,7 @@
31163116
<!-- TODO remove key -->
31173117
<string name="live_location_bottom_sheet_stop_sharing" tools:ignore="UnusedResources">Stop sharing</string>
31183118
<string name="live_location_bottom_sheet_last_updated_at">Updated %1$s ago</string>
3119+
<string name="live_location_share_location_item_share">Share location</string>
31193120

31203121
<string name="message_bubbles">Show Message bubbles</string>
31213122

0 commit comments

Comments
 (0)