mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-25 10:55:55 +03: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
9 changed files with 178 additions and 10 deletions
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_vertical">16dp</dimen>
|
||||||
<dimen name="location_sharing_locate_button_margin_horizontal">12dp</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_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>
|
</resources>
|
||||||
|
|
|
@ -23,5 +23,5 @@ sealed class LocationSharingAction : VectorViewModelAction {
|
||||||
data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
|
data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
|
||||||
data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
|
data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
|
||||||
object ZoomToUserLocation : 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.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.mapbox.mapboxsdk.maps.MapView
|
import com.mapbox.mapboxsdk.maps.MapView
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
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_BACKGROUND_LOCATION_SHARING
|
||||||
import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_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.VectorFeatures
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
|
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 im.vector.app.features.location.option.LocationSharingOption
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -52,7 +54,9 @@ class LocationSharingFragment @Inject constructor(
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val matrixItemColorProvider: MatrixItemColorProvider,
|
private val matrixItemColorProvider: MatrixItemColorProvider,
|
||||||
private val vectorFeatures: VectorFeatures,
|
private val vectorFeatures: VectorFeatures,
|
||||||
) : VectorBaseFragment<FragmentLocationSharingBinding>(), LocationTargetChangeListener {
|
) : VectorBaseFragment<FragmentLocationSharingBinding>(),
|
||||||
|
LocationTargetChangeListener,
|
||||||
|
VectorBaseBottomSheetDialogFragment.ResultListener {
|
||||||
|
|
||||||
private val viewModel: LocationSharingViewModel by fragmentViewModel()
|
private val viewModel: LocationSharingViewModel by fragmentViewModel()
|
||||||
|
|
||||||
|
@ -181,13 +185,15 @@ class LocationSharingFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleStartLiveLocationService(event: LocationSharingViewEvents.StartLiveLocationService) {
|
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)
|
Intent(requireContext(), LocationSharingService::class.java)
|
||||||
.putExtra(LocationSharingService.EXTRA_ROOM_ARGS, args)
|
.putExtra(LocationSharingService.EXTRA_ROOM_ARGS, args)
|
||||||
.also {
|
.also {
|
||||||
ContextCompat.startForegroundService(requireContext(), it)
|
ContextCompat.startForegroundService(requireContext(), it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vectorBaseActivity.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initOptionsPicker() {
|
private fun initOptionsPicker() {
|
||||||
|
@ -235,9 +241,14 @@ class LocationSharingFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startLiveLocationSharing() {
|
private fun startLiveLocationSharing() {
|
||||||
// TODO. Get duration from user
|
ChooseLiveDurationBottomSheet.newInstance(this)
|
||||||
val duration = 30 * 1000L
|
.show(requireActivity().supportFragmentManager, "DISPLAY_CHOOSE_DURATION_OPTIONS")
|
||||||
viewModel.handle(LocationSharingAction.StartLiveLocationSharing(duration))
|
}
|
||||||
|
|
||||||
|
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) {
|
private fun updateMap(state: LocationSharingViewState) {
|
||||||
|
|
|
@ -22,5 +22,5 @@ sealed class LocationSharingViewEvents : VectorViewEvents {
|
||||||
object Close : LocationSharingViewEvents()
|
object Close : LocationSharingViewEvents()
|
||||||
object LocationNotAvailableError : LocationSharingViewEvents()
|
object LocationNotAvailableError : LocationSharingViewEvents()
|
||||||
data class ZoomToUserLocation(val userLocation: LocationData) : 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.PinnedLocationSharing -> handlePinnedLocationSharingAction(action)
|
||||||
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
|
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
|
||||||
LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction()
|
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(
|
_viewEvents.post(LocationSharingViewEvents.StartLiveLocationService(
|
||||||
sessionId = session.sessionId,
|
sessionId = session.sessionId,
|
||||||
roomId = room.roomId,
|
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="a11y_location_share_option_user_live_icon">Share live location</string>
|
||||||
<string name="location_share_option_pinned">Share this 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="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_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_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>
|
<string name="location_not_available_dialog_title">${app_name} could not access your location</string>
|
||||||
|
|
Loading…
Reference in a new issue