From d448c62caddf7bcdb045e8e75a6c7516857379f5 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 30 Mar 2022 13:37:24 +0200 Subject: [PATCH 01/13] Adding changelog entry --- changelog.d/5667.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5667.feature 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 From f34225506a64ba354766cf9c032f20900495712f Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 30 Mar 2022 13:46:08 +0200 Subject: [PATCH 02/13] Adding strings resources --- vector/src/main/res/values/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 96c9541da7..be143e99bd 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2959,6 +2959,10 @@ Share live location Share this location Share this location + Share your live location for + 15 minutes + 1 hour + 8 hours Allow access 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. ${app_name} could not access your location From d0a255819a2b5bca3ffa1638a08cba00f50a6fae Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 30 Mar 2022 14:34:56 +0200 Subject: [PATCH 03/13] Creating BottomSheet to choose the live duration --- .../location/LocationSharingFragment.kt | 7 ++- .../duration/ChooseLiveDurationBottomSheet.kt | 48 +++++++++++++++++++ ...et_choose_live_location_share_duration.xml | 18 +++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/location/live/duration/ChooseLiveDurationBottomSheet.kt create mode 100644 vector/src/main/res/layout/bottom_sheet_choose_live_location_share_duration.xml 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..62104aa8eb 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 @@ -39,6 +39,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 @@ -236,8 +237,10 @@ class LocationSharingFragment @Inject constructor( private fun startLiveLocationSharing() { // TODO. Get duration from user - val duration = 30 * 1000L - viewModel.handle(LocationSharingAction.StartLiveLocationSharing(duration)) + ChooseLiveDurationBottomSheet.newInstance() + .show(requireActivity().supportFragmentManager, "DISPLAY_CHOOSE_DURATION_OPTIONS") + //val duration = 30 * 1000L + //viewModel.handle(LocationSharingAction.StartLiveLocationSharing(duration)) } private fun updateMap(state: LocationSharingViewState) { 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..2801d5f0a6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/duration/ChooseLiveDurationBottomSheet.kt @@ -0,0 +1,48 @@ +/* + * 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.view.LayoutInflater +import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetChooseLiveLocationShareDurationBinding +import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel + +/** + * Bottom sheet displaying list of options to choose the duration of the live sharing. + */ +@AndroidEntryPoint +class ChooseLiveDurationBottomSheet : + VectorBaseBottomSheetDialogFragment() { + + // TODO create interface callback to set the chosen duration + // TODO show same UI as in Figma + // TODO handle choice of user + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetChooseLiveLocationShareDurationBinding { + return BottomSheetChooseLiveLocationShareDurationBinding.inflate(inflater, container, false) + } + + // we are not using state for this one as it's static, so no need to override invalidate() + + companion object { + fun newInstance(): ChooseLiveDurationBottomSheet { + return ChooseLiveDurationBottomSheet() + } + } +} 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..675a63144f --- /dev/null +++ b/vector/src/main/res/layout/bottom_sheet_choose_live_location_share_duration.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file From 4da11bbdc0ae0beceede01a1010728e796628d28 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 30 Mar 2022 14:41:12 +0200 Subject: [PATCH 04/13] Renaming duration parameter to precise the time unit --- .../vector/app/features/location/LocationSharingAction.kt | 2 +- .../vector/app/features/location/LocationSharingFragment.kt | 2 +- .../app/features/location/LocationSharingViewEvents.kt | 2 +- .../app/features/location/LocationSharingViewModel.kt | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) 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 62104aa8eb..c4574d69db 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 @@ -182,7 +182,7 @@ 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) 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 )) } From 5abc1965364d4e3cc8240fbe4dce30b924a4c106 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 30 Mar 2022 14:53:32 +0200 Subject: [PATCH 05/13] Callback interface for the choice of the duration --- .../location/LocationSharingFragment.kt | 13 ++++++++----- .../duration/ChooseLiveDurationBottomSheet.kt | 18 +++++++++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) 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 c4574d69db..3fdae43312 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 @@ -53,7 +53,9 @@ class LocationSharingFragment @Inject constructor( private val avatarRenderer: AvatarRenderer, private val matrixItemColorProvider: MatrixItemColorProvider, private val vectorFeatures: VectorFeatures, -) : VectorBaseFragment(), LocationTargetChangeListener { +) : VectorBaseFragment(), + LocationTargetChangeListener, + ChooseLiveDurationBottomSheet.DurationChoiceListener { private val viewModel: LocationSharingViewModel by fragmentViewModel() @@ -236,11 +238,12 @@ class LocationSharingFragment @Inject constructor( } private fun startLiveLocationSharing() { - // TODO. Get duration from user - ChooseLiveDurationBottomSheet.newInstance() + ChooseLiveDurationBottomSheet.newInstance(this) .show(requireActivity().supportFragmentManager, "DISPLAY_CHOOSE_DURATION_OPTIONS") - //val duration = 30 * 1000L - //viewModel.handle(LocationSharingAction.StartLiveLocationSharing(duration)) + } + + override fun onDurationChoice(durationMillis: Long) { + viewModel.handle(LocationSharingAction.StartLiveLocationSharing(durationMillis)) } private fun updateMap(state: LocationSharingViewState) { 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 index 2801d5f0a6..59c9faddda 100644 --- 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 @@ -30,19 +30,31 @@ import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActi class ChooseLiveDurationBottomSheet : VectorBaseBottomSheetDialogFragment() { - // TODO create interface callback to set the chosen duration // TODO show same UI as in Figma // TODO handle choice of user + var durationChoiceListener: DurationChoiceListener? = null + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetChooseLiveLocationShareDurationBinding { return BottomSheetChooseLiveLocationShareDurationBinding.inflate(inflater, container, false) } + override fun onDestroyView() { + durationChoiceListener = null + super.onDestroyView() + } + // we are not using state for this one as it's static, so no need to override invalidate() companion object { - fun newInstance(): ChooseLiveDurationBottomSheet { - return ChooseLiveDurationBottomSheet() + fun newInstance(durationChoiceListener: DurationChoiceListener): ChooseLiveDurationBottomSheet { + val bottomSheet = ChooseLiveDurationBottomSheet() + bottomSheet.durationChoiceListener = durationChoiceListener + return bottomSheet } } + + interface DurationChoiceListener { + fun onDurationChoice(durationMillis: Long) + } } From c18a9230e552ce7f480e59ae02f31785672c8adb Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 30 Mar 2022 16:11:25 +0200 Subject: [PATCH 06/13] UI to select the duration --- .../duration/ChooseLiveDurationBottomSheet.kt | 44 ++++++++++++++- .../drawable/divider_horizontal_system.xml | 5 ++ ...et_choose_live_location_share_duration.xml | 56 +++++++++++++++++-- 3 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 vector/src/main/res/drawable/divider_horizontal_system.xml 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 index 59c9faddda..f0bee558cc 100644 --- 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 @@ -16,12 +16,29 @@ 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.databinding.BottomSheetChooseLiveLocationShareDurationBinding -import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel + +/** + * 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 live sharing. @@ -30,8 +47,7 @@ import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActi class ChooseLiveDurationBottomSheet : VectorBaseBottomSheetDialogFragment() { - // TODO show same UI as in Figma - // TODO handle choice of user + // TODO fix text color problem of button in dqrk mode var durationChoiceListener: DurationChoiceListener? = null @@ -39,6 +55,11 @@ class ChooseLiveDurationBottomSheet : return BottomSheetChooseLiveLocationShareDurationBinding.inflate(inflater, container, false) } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initConfirmButton() + } + override fun onDestroyView() { durationChoiceListener = null super.onDestroyView() @@ -46,6 +67,23 @@ class ChooseLiveDurationBottomSheet : // 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() + durationChoiceListener?.onDurationChoice(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(durationChoiceListener: DurationChoiceListener): ChooseLiveDurationBottomSheet { val bottomSheet = ChooseLiveDurationBottomSheet() diff --git a/vector/src/main/res/drawable/divider_horizontal_system.xml b/vector/src/main/res/drawable/divider_horizontal_system.xml new file mode 100644 index 0000000000..df847a4feb --- /dev/null +++ b/vector/src/main/res/drawable/divider_horizontal_system.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file 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 index 675a63144f..3336c0bac0 100644 --- 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 @@ -2,17 +2,61 @@ + android:paddingHorizontal="15dp" + android:paddingVertical="24dp" + android:text="@string/location_share_live_select_duration_title" + android:textColor="?vctr_content_primary" /> + + + + + + + + + + +