Merge pull request #6092 from vector-im/feature/mna/PSF-888-navigation

[Location sharing] - Navigation to Map view from live location message (PSF-888)
This commit is contained in:
Maxime NATUREL 2022-05-23 13:54:04 +02:00 committed by GitHub
commit 9a38d59f9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 180 additions and 3 deletions

1
changelog.d/6012.wip Normal file
View File

@ -0,0 +1 @@
Live location sharing: navigation from timeline to map screen

View File

@ -343,6 +343,7 @@
<activity android:name=".features.spaces.leave.SpaceLeaveAdvancedActivity" /> <activity android:name=".features.spaces.leave.SpaceLeaveAdvancedActivity" />
<activity android:name=".features.poll.create.CreatePollActivity" /> <activity android:name=".features.poll.create.CreatePollActivity" />
<activity android:name=".features.location.LocationSharingActivity" /> <activity android:name=".features.location.LocationSharingActivity" />
<activity android:name=".features.location.live.map.LocationLiveMapViewActivity" />
<!-- Services --> <!-- Services -->

View File

@ -36,9 +36,10 @@ fun Fragment.registerStartForActivityResult(onResult: (ActivityResult) -> Unit):
fun Fragment.addFragment( fun Fragment.addFragment(
frameId: Int, frameId: Int,
fragment: Fragment, fragment: Fragment,
tag: String? = null,
allowStateLoss: Boolean = false allowStateLoss: Boolean = false
) { ) {
parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) } parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment, tag) }
} }
fun <T : Fragment> Fragment.addFragment( fun <T : Fragment> Fragment.addFragment(

View File

@ -221,6 +221,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent
import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.model.message.MessageFormat import org.matrix.android.sdk.api.session.room.model.message.MessageFormat
import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoContent import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoContent
@ -647,6 +648,13 @@ class TimelineFragment @Inject constructor(
) )
} }
private fun navigateToLocationLiveMap() {
navigator.openLocationLiveMap(
context = requireContext(),
roomId = timelineArgs.roomId
)
}
private fun handleChangeLocationIndicator(event: RoomDetailViewEvents.ChangeLocationIndicator) { private fun handleChangeLocationIndicator(event: RoomDetailViewEvents.ChangeLocationIndicator) {
views.locationLiveStatusIndicator.isVisible = event.isVisible views.locationLiveStatusIndicator.isVisible = event.isVisible
} }
@ -2015,6 +2023,9 @@ class TimelineFragment @Inject constructor(
is MessageLocationContent -> { is MessageLocationContent -> {
handleShowLocationPreview(messageContent, informationData.senderId) handleShowLocationPreview(messageContent, informationData.senderId)
} }
is MessageBeaconInfoContent -> {
navigateToLocationLiveMap()
}
else -> { else -> {
val handled = onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) val handled = onThreadSummaryClicked(informationData.eventId, isRootThreadEvent)
if (!handled) { if (!handled) {

View File

@ -75,7 +75,8 @@ class LiveLocationShareMessageItemFactory @Inject constructor(
val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP)
return MessageLiveLocationInactiveItem_() return MessageLiveLocationInactiveItem_()
.attributes(attributes) // disable the click on this state item
.attributes(attributes.copy(itemClickListener = null))
.mapWidth(width) .mapWidth(width)
.mapHeight(height) .mapHeight(height)
.highlighted(highlight) .highlighted(highlight)
@ -90,7 +91,8 @@ class LiveLocationShareMessageItemFactory @Inject constructor(
val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP)
return MessageLiveLocationStartItem_() return MessageLiveLocationStartItem_()
.attributes(attributes) // disable the click on this state item
.attributes(attributes.copy(itemClickListener = null))
.mapWidth(width) .mapWidth(width)
.mapHeight(height) .mapHeight(height)
.highlighted(highlight) .highlighted(highlight)

View File

@ -0,0 +1,68 @@
/*
* 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.map
import android.content.Context
import android.content.Intent
import android.os.Parcelable
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityLocationSharingBinding
import kotlinx.parcelize.Parcelize
@Parcelize
data class LocationLiveMapViewArgs(
val roomId: String
) : Parcelable
@AndroidEntryPoint
class LocationLiveMapViewActivity : VectorBaseActivity<ActivityLocationSharingBinding>() {
override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater)
override fun initUiAndData() {
val mapViewArgs: LocationLiveMapViewArgs? = intent?.extras?.getParcelable(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS)
if (mapViewArgs == null) {
finish()
return
}
setupToolbar(views.toolbar)
.setTitle(getString(R.string.location_activity_title_preview))
.allowBack()
if (isFirstCreation()) {
addFragment(
views.fragmentContainer,
LocationLiveMapViewFragment::class.java,
mapViewArgs
)
}
}
companion object {
private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS"
fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent {
return Intent(context, LocationLiveMapViewActivity::class.java).apply {
putExtra(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS, locationLiveMapViewArgs)
}
}
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.map
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.args
import com.mapbox.mapboxsdk.maps.MapboxMapOptions
import com.mapbox.mapboxsdk.maps.SupportMapFragment
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.addChildFragment
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentSimpleContainerBinding
import im.vector.app.features.location.UrlMapProvider
import javax.inject.Inject
/**
* Screen showing a map with all the current users sharing their live location in room.
*/
@AndroidEntryPoint
class LocationLiveMapViewFragment : VectorBaseFragment<FragmentSimpleContainerBinding>() {
@Inject
lateinit var urlMapProvider: UrlMapProvider
private val args: LocationLiveMapViewArgs by args()
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSimpleContainerBinding {
return FragmentSimpleContainerBinding.inflate(layoutInflater, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupMap()
}
private fun setupMap() {
val mapFragment = getOrCreateSupportMapFragment()
mapFragment.getMapAsync { mapBoxMap ->
lifecycleScope.launchWhenCreated {
mapBoxMap.setStyle(urlMapProvider.getMapUrl())
}
}
}
private fun getOrCreateSupportMapFragment() =
childFragmentManager.findFragmentByTag(MAP_FRAGMENT_TAG) as? SupportMapFragment
?: run {
val options = MapboxMapOptions.createFromAttributes(requireContext(), null)
SupportMapFragment.newInstance(options)
.also { addChildFragment(R.id.fragmentContainer, it, tag = MAP_FRAGMENT_TAG) }
}
companion object {
private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map"
}
}

View File

@ -68,6 +68,8 @@ import im.vector.app.features.location.LocationData
import im.vector.app.features.location.LocationSharingActivity import im.vector.app.features.location.LocationSharingActivity
import im.vector.app.features.location.LocationSharingArgs import im.vector.app.features.location.LocationSharingArgs
import im.vector.app.features.location.LocationSharingMode import im.vector.app.features.location.LocationSharingMode
import im.vector.app.features.location.live.map.LocationLiveMapViewActivity
import im.vector.app.features.location.live.map.LocationLiveMapViewArgs
import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginActivity
import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.LoginConfig
import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.matrixto.MatrixToBottomSheet
@ -592,6 +594,14 @@ class DefaultNavigator @Inject constructor(
context.startActivity(intent) context.startActivity(intent)
} }
override fun openLocationLiveMap(context: Context, roomId: String) {
val intent = LocationLiveMapViewActivity.getIntent(
context = context,
locationLiveMapViewArgs = LocationLiveMapViewArgs(roomId = roomId)
)
context.startActivity(intent)
}
private fun startActivity(context: Context, intent: Intent, buildTask: Boolean) { private fun startActivity(context: Context, intent: Intent, buildTask: Boolean) {
if (buildTask) { if (buildTask) {
val stackBuilder = TaskStackBuilder.create(context) val stackBuilder = TaskStackBuilder.create(context)

View File

@ -172,6 +172,8 @@ interface Navigator {
initialLocationData: LocationData?, initialLocationData: LocationData?,
locationOwnerId: String?) locationOwnerId: String?)
fun openLocationLiveMap(context: Context, roomId: String)
fun openThread(context: Context, threadTimelineArgs: ThreadTimelineArgs, eventIdToNavigate: String? = null) fun openThread(context: Context, threadTimelineArgs: ThreadTimelineArgs, eventIdToNavigate: String? = null)
fun openThreadList(context: Context, threadTimelineArgs: ThreadTimelineArgs) fun openThreadList(context: Context, threadTimelineArgs: ThreadTimelineArgs)

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />