diff --git a/changelog.d/6350.feature b/changelog.d/6350.feature new file mode 100644 index 0000000000..e0bc4ac28b --- /dev/null +++ b/changelog.d/6350.feature @@ -0,0 +1 @@ +Promote live location labs flag 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 1b25f3fcec..f881e694b6 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 @@ -24,6 +24,7 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.core.view.isGone +import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -39,6 +40,7 @@ import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.databinding.FragmentLocationSharingBinding 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.LiveLocationLabsFlagPromotionBottomSheet import im.vector.app.features.location.live.duration.ChooseLiveDurationBottomSheet import im.vector.app.features.location.option.LocationSharingOption import im.vector.app.features.settings.VectorPreferences @@ -71,6 +73,15 @@ class LocationSharingFragment @Inject constructor( return FragmentLocationSharingBinding.inflate(inflater, container, false) } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setFragmentResultListener(LiveLocationLabsFlagPromotionBottomSheet.REQUEST_KEY) { _, bundle -> + val isApproved = bundle.getBoolean(LiveLocationLabsFlagPromotionBottomSheet.BUNDLE_KEY_LABS_APPROVAL) + handleLiveLocationLabsFlagPromotionResult(isApproved) + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -194,6 +205,22 @@ class LocationSharingFragment @Inject constructor( } } + private fun handleLiveLocationLabsFlagPromotionResult(isApproved: Boolean) { + if (isApproved) { + vectorPreferences.setLiveLocationLabsEnabled(isEnabled = true) + startLiveLocationSharing() + } + } + + private fun tryStartLiveLocationSharing() { + if (vectorPreferences.labsEnableLiveLocation()) { + startLiveLocationSharing() + } else { + LiveLocationLabsFlagPromotionBottomSheet.newInstance() + .show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION") + } + } + private val foregroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> if (allGranted) { startLiveLocationSharing() @@ -202,18 +229,14 @@ class LocationSharingFragment @Inject constructor( } } - private fun tryStartLiveLocationSharing() { + private fun startLiveLocationSharing() { // we need to re-check foreground location to be sure it has not changed after landing on this screen if (checkPermissions(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, requireActivity(), foregroundLocationResultLauncher)) { - startLiveLocationSharing() + ChooseLiveDurationBottomSheet.newInstance(this) + .show(requireActivity().supportFragmentManager, "DISPLAY_CHOOSE_DURATION_OPTIONS") } } - private fun startLiveLocationSharing() { - 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)) } @@ -223,13 +246,7 @@ class LocationSharingFragment @Inject constructor( private fun updateMap(state: LocationSharingViewState) { // first, update the options view val options: Set = when (state.areTargetAndUserLocationEqual) { - true -> { - if (vectorPreferences.labsEnableLiveLocation()) { - setOf(LocationSharingOption.USER_CURRENT, LocationSharingOption.USER_LIVE) - } else { - setOf(LocationSharingOption.USER_CURRENT) - } - } + true -> setOf(LocationSharingOption.USER_CURRENT, LocationSharingOption.USER_LIVE) false -> setOf(LocationSharingOption.PINNED) else -> emptySet() } diff --git a/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt b/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt new file mode 100644 index 0000000000..cf360ec277 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt @@ -0,0 +1,64 @@ +/* + * 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 + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.setFragmentResult +import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetLiveLocationLabsFlagPromotionBinding + +/** + * Bottom sheet to warn users that feature is still in active development. Users are able to enable labs flag by using the switch in this bottom sheet. + * This should not be shown if the user already enabled the labs flag. + */ +class LiveLocationLabsFlagPromotionBottomSheet : + VectorBaseBottomSheetDialogFragment() { + + override val showExpanded = true + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetLiveLocationLabsFlagPromotionBinding { + return BottomSheetLiveLocationLabsFlagPromotionBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initOkButton() + } + + private fun initOkButton() { + views.promoteLiveLocationFlagOkButton.debouncedClicks { + val enableLabsFlag = views.promoteLiveLocationFlagSwitch.isChecked + setFragmentResult(REQUEST_KEY, Bundle().apply { + putBoolean(BUNDLE_KEY_LABS_APPROVAL, enableLabsFlag) + }) + dismiss() + } + } + + companion object { + + const val REQUEST_KEY = "LiveLocationLabsFlagPromotionBottomSheetRequest" + const val BUNDLE_KEY_LABS_APPROVAL = "BUNDLE_KEY_LABS_APPROVAL" + + fun newInstance(): LiveLocationLabsFlagPromotionBottomSheet { + return LiveLocationLabsFlagPromotionBottomSheet() + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 2ac714f7a0..6d91dc3348 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -1051,6 +1051,12 @@ class VectorPreferences @Inject constructor( return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_LIVE_LOCATION, false) } + fun setLiveLocationLabsEnabled(isEnabled: Boolean) { + defaultPrefs.edit { + putBoolean(SETTINGS_LABS_ENABLE_LIVE_LOCATION, isEnabled) + } + } + /** * Indicates whether or not thread messages are enabled. */ diff --git a/vector/src/main/res/layout/bottom_sheet_live_location_labs_flag_promotion.xml b/vector/src/main/res/layout/bottom_sheet_live_location_labs_flag_promotion.xml new file mode 100644 index 0000000000..438e60a4d3 --- /dev/null +++ b/vector/src/main/res/layout/bottom_sheet_live_location_labs_flag_promotion.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + +