mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge pull request #5671 from vector-im/feature/mna/PSF-673-live-loc-share-duration
#5667: [Location Sharing] - Set duration of live sharing
This commit is contained in:
commit
bebe819c54
1
changelog.d/5667.feature
Normal file
1
changelog.d/5667.feature
Normal file
@ -0,0 +1 @@
|
||||
Location sharing: adding possibility to choose duration of live sharing
|
@ -67,4 +67,6 @@
|
||||
<dimen name="location_sharing_locate_button_margin_vertical">16dp</dimen>
|
||||
<dimen name="location_sharing_locate_button_margin_horizontal">12dp</dimen>
|
||||
<dimen name="location_sharing_compass_button_margin_horizontal">8dp</dimen>
|
||||
<dimen name="location_sharing_live_duration_choice_margin_horizontal">12dp</dimen>
|
||||
<dimen name="location_sharing_live_duration_choice_margin_vertical">22dp</dimen>
|
||||
</resources>
|
||||
|
@ -23,5 +23,5 @@ sealed class LocationSharingAction : VectorViewModelAction {
|
||||
data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
|
||||
data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
|
||||
object ZoomToUserLocation : LocationSharingAction()
|
||||
data class StartLiveLocationSharing(val duration: Long) : LocationSharingAction()
|
||||
data class StartLiveLocationSharing(val durationMillis: Long) : LocationSharingAction()
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import com.airbnb.mvrx.withState
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING
|
||||
import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING
|
||||
@ -39,6 +40,7 @@ import im.vector.app.databinding.FragmentLocationSharingBinding
|
||||
import im.vector.app.features.VectorFeatures
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
|
||||
import im.vector.app.features.location.live.duration.ChooseLiveDurationBottomSheet
|
||||
import im.vector.app.features.location.option.LocationSharingOption
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import java.lang.ref.WeakReference
|
||||
@ -52,7 +54,9 @@ class LocationSharingFragment @Inject constructor(
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val matrixItemColorProvider: MatrixItemColorProvider,
|
||||
private val vectorFeatures: VectorFeatures,
|
||||
) : VectorBaseFragment<FragmentLocationSharingBinding>(), LocationTargetChangeListener {
|
||||
) : VectorBaseFragment<FragmentLocationSharingBinding>(),
|
||||
LocationTargetChangeListener,
|
||||
VectorBaseBottomSheetDialogFragment.ResultListener {
|
||||
|
||||
private val viewModel: LocationSharingViewModel by fragmentViewModel()
|
||||
|
||||
@ -181,13 +185,15 @@ class LocationSharingFragment @Inject constructor(
|
||||
}
|
||||
|
||||
private fun handleStartLiveLocationService(event: LocationSharingViewEvents.StartLiveLocationService) {
|
||||
val args = LocationSharingService.RoomArgs(event.sessionId, event.roomId, event.duration)
|
||||
val args = LocationSharingService.RoomArgs(event.sessionId, event.roomId, event.durationMillis)
|
||||
|
||||
Intent(requireContext(), LocationSharingService::class.java)
|
||||
.putExtra(LocationSharingService.EXTRA_ROOM_ARGS, args)
|
||||
.also {
|
||||
ContextCompat.startForegroundService(requireContext(), it)
|
||||
}
|
||||
|
||||
vectorBaseActivity.finish()
|
||||
}
|
||||
|
||||
private fun initOptionsPicker() {
|
||||
@ -235,9 +241,14 @@ class LocationSharingFragment @Inject constructor(
|
||||
}
|
||||
|
||||
private fun startLiveLocationSharing() {
|
||||
// TODO. Get duration from user
|
||||
val duration = 30 * 1000L
|
||||
viewModel.handle(LocationSharingAction.StartLiveLocationSharing(duration))
|
||||
ChooseLiveDurationBottomSheet.newInstance(this)
|
||||
.show(requireActivity().supportFragmentManager, "DISPLAY_CHOOSE_DURATION_OPTIONS")
|
||||
}
|
||||
|
||||
override fun onBottomSheetResult(resultCode: Int, data: Any?) {
|
||||
if (resultCode == VectorBaseBottomSheetDialogFragment.ResultListener.RESULT_OK) {
|
||||
(data as? Long)?.let { viewModel.handle(LocationSharingAction.StartLiveLocationSharing(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMap(state: LocationSharingViewState) {
|
||||
|
@ -22,5 +22,5 @@ sealed class LocationSharingViewEvents : VectorViewEvents {
|
||||
object Close : LocationSharingViewEvents()
|
||||
object LocationNotAvailableError : LocationSharingViewEvents()
|
||||
data class ZoomToUserLocation(val userLocation: LocationData) : LocationSharingViewEvents()
|
||||
data class StartLiveLocationService(val sessionId: String, val roomId: String, val duration: Long) : LocationSharingViewEvents()
|
||||
data class StartLiveLocationService(val sessionId: String, val roomId: String, val durationMillis: Long) : LocationSharingViewEvents()
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ class LocationSharingViewModel @AssistedInject constructor(
|
||||
is LocationSharingAction.PinnedLocationSharing -> handlePinnedLocationSharingAction(action)
|
||||
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
|
||||
LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction()
|
||||
is LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction(action.duration)
|
||||
is LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction(action.durationMillis)
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,11 +158,11 @@ class LocationSharingViewModel @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleStartLiveLocationSharingAction(duration: Long) {
|
||||
private fun handleStartLiveLocationSharingAction(durationMillis: Long) {
|
||||
_viewEvents.post(LocationSharingViewEvents.StartLiveLocationService(
|
||||
sessionId = session.sessionId,
|
||||
roomId = room.roomId,
|
||||
duration = duration
|
||||
durationMillis = durationMillis
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2019 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.duration
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK
|
||||
import im.vector.app.databinding.BottomSheetChooseLiveLocationShareDurationBinding
|
||||
|
||||
/**
|
||||
* 15 minutes.
|
||||
*/
|
||||
private const val DURATION_IN_MS_OPTION_1 = 15 * 60_000L
|
||||
|
||||
/**
|
||||
* 1 hour.
|
||||
*/
|
||||
private const val DURATION_IN_MS_OPTION_2 = 60 * 60_000L
|
||||
|
||||
/**
|
||||
* 8 hours.
|
||||
*/
|
||||
private const val DURATION_IN_MS_OPTION_3 = 8 * 60 * 60_000L
|
||||
|
||||
/**
|
||||
* Bottom sheet displaying list of options to choose the duration of the location live sharing.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class ChooseLiveDurationBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetChooseLiveLocationShareDurationBinding>() {
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetChooseLiveLocationShareDurationBinding {
|
||||
return BottomSheetChooseLiveLocationShareDurationBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initConfirmButton()
|
||||
}
|
||||
|
||||
// we are not using state for this one as it's static, so no need to override invalidate()
|
||||
|
||||
private fun initConfirmButton() {
|
||||
views.liveLocShareChooseDurationConfirm.setOnClickListener {
|
||||
val currentChoice = getCurrentChoice()
|
||||
resultListener?.onBottomSheetResult(RESULT_OK, currentChoice)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCurrentChoice(): Long {
|
||||
return when (views.liveLocShareChooseDurationOptions.checkedRadioButtonId) {
|
||||
R.id.liveLocShareChooseDurationOption1 -> DURATION_IN_MS_OPTION_1
|
||||
R.id.liveLocShareChooseDurationOption2 -> DURATION_IN_MS_OPTION_2
|
||||
R.id.liveLocShareChooseDurationOption3 -> DURATION_IN_MS_OPTION_3
|
||||
else -> DURATION_IN_MS_OPTION_1
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(resultListener: ResultListener): ChooseLiveDurationBottomSheet {
|
||||
val bottomSheet = ChooseLiveDurationBottomSheet()
|
||||
bottomSheet.resultListener = resultListener
|
||||
return bottomSheet
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorSurface"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/liveLocShareChooseDurationTitle"
|
||||
style="@style/Widget.Vector.TextView.Subtitle.Medium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingHorizontal="15dp"
|
||||
android:paddingVertical="24dp"
|
||||
android:text="@string/location_share_live_select_duration_title"
|
||||
android:textColor="?vctr_content_primary" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/liveLocShareChooseDurationOptions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="@drawable/divider_horizontal"
|
||||
android:showDividers="beginning">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/liveLocShareChooseDurationOption1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/location_sharing_live_duration_choice_margin_horizontal"
|
||||
android:checked="true"
|
||||
android:paddingHorizontal="@dimen/location_sharing_live_duration_choice_margin_horizontal"
|
||||
android:paddingVertical="@dimen/location_sharing_live_duration_choice_margin_vertical"
|
||||
android:text="@string/location_share_live_select_duration_option_1" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/liveLocShareChooseDurationOption2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/location_sharing_live_duration_choice_margin_horizontal"
|
||||
android:paddingHorizontal="@dimen/location_sharing_live_duration_choice_margin_horizontal"
|
||||
android:paddingVertical="@dimen/location_sharing_live_duration_choice_margin_vertical"
|
||||
android:text="@string/location_share_live_select_duration_option_2" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/liveLocShareChooseDurationOption3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/location_sharing_live_duration_choice_margin_horizontal"
|
||||
android:paddingHorizontal="@dimen/location_sharing_live_duration_choice_margin_horizontal"
|
||||
android:paddingVertical="@dimen/location_sharing_live_duration_choice_margin_vertical"
|
||||
android:text="@string/location_share_live_select_duration_option_3" />
|
||||
</RadioGroup>
|
||||
|
||||
<Button
|
||||
android:id="@+id/liveLocShareChooseDurationConfirm"
|
||||
style="@style/Widget.Vector.Button.CallToAction"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="65dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="12dp"
|
||||
android:text="@string/action_share" />
|
||||
|
||||
</LinearLayout>
|
@ -2961,6 +2961,10 @@
|
||||
<string name="a11y_location_share_option_user_live_icon">Share live location</string>
|
||||
<string name="location_share_option_pinned">Share this location</string>
|
||||
<string name="a11y_location_share_option_pinned_icon">Share this location</string>
|
||||
<string name="location_share_live_select_duration_title">Share your live location for</string>
|
||||
<string name="location_share_live_select_duration_option_1">15 minutes</string>
|
||||
<string name="location_share_live_select_duration_option_2">1 hour</string>
|
||||
<string name="location_share_live_select_duration_option_3">8 hours</string>
|
||||
<string name="location_in_background_missing_permission_dialog_title">Allow access</string>
|
||||
<string name="location_in_background_missing_permission_dialog_content">If you’d like to share your Live location, ${app_name} needs location access all the time when the app is in the background.\nWe will only access your location for the duration that you choose.</string>
|
||||
<string name="location_not_available_dialog_title">${app_name} could not access your location</string>
|
||||
|
Loading…
Reference in New Issue
Block a user