diff --git a/changelog.d/5667.feature b/changelog.d/5667.feature new file mode 100644 index 0000000000..38e750112e --- /dev/null +++ b/changelog.d/5667.feature @@ -0,0 +1 @@ +Location sharing: adding possibility to choose duration of live sharing \ No newline at end of file diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index 600c73c878..8dd7188327 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -67,4 +67,6 @@ 16dp 12dp 8dp + 12dp + 22dp diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt index 4025fbefa8..d86d97e6b0 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt @@ -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() } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index ab3bf9b933..38b96142b5 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -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(), LocationTargetChangeListener { +) : VectorBaseFragment(), + 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) { diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt index b25a4988b0..1116003e41 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt @@ -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() } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt index 5f538dad67..e67d5d0abb 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt @@ -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 )) } diff --git a/vector/src/main/java/im/vector/app/features/location/live/duration/ChooseLiveDurationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/location/live/duration/ChooseLiveDurationBottomSheet.kt new file mode 100644 index 0000000000..36165d4524 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/duration/ChooseLiveDurationBottomSheet.kt @@ -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() { + + 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 + } + } +} diff --git a/vector/src/main/res/layout/bottom_sheet_choose_live_location_share_duration.xml b/vector/src/main/res/layout/bottom_sheet_choose_live_location_share_duration.xml new file mode 100644 index 0000000000..b044fe7de9 --- /dev/null +++ b/vector/src/main/res/layout/bottom_sheet_choose_live_location_share_duration.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + +