diff options
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
2 files changed, 69 insertions, 70 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt index a7869ce..faac5a4 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt @@ -27,7 +27,6 @@ import foundation.e.privacycentralapp.domain.entities.LocationMode import foundation.e.privacycentralapp.domain.usecases.FakeLocationStateUseCase import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge @@ -48,16 +47,17 @@ class FakeLocationFeature( singleEventProducer ) { data class State( - val isEnabled: Boolean, - val mode: LocationMode, - val currentLocation: Location?, + val isEnabled: Boolean = true, + val mode: LocationMode = LocationMode.REAL_LOCATION, + val currentLocation: Location? = null, val specificLatitude: Float? = null, val specificLongitude: Float? = null, - val forceRefresh: Boolean = false + val forceRefresh: Boolean = false, + val showQuickPrivacyDisabledMessage: Boolean = false ) sealed class SingleEvent { - data class LocationUpdatedEvent(val location: Location?) : SingleEvent() + data class LocationUpdatedEvent(val mode: LocationMode, val location: Location?) : SingleEvent() data class ErrorEvent(val error: String) : SingleEvent() } @@ -70,6 +70,7 @@ class FakeLocationFeature( val latitude: Float, val longitude: Float ) : Action() + object CloseQuickPrivacyDisabledMessage : Action() } sealed class Effect { @@ -81,17 +82,13 @@ class FakeLocationFeature( ) : Effect() data class LocationUpdatedEffect(val location: Location?) : Effect() data class ErrorEffect(val message: String) : Effect() - object QuickPrivacyDisabledWarningEffect : Effect() object NoEffect : Effect() + data class ShowQuickPrivacyDisabledMessageEffect(val show: Boolean) : Effect() } companion object { fun create( - initialState: State = State( - isEnabled = false, - mode = LocationMode.REAL_LOCATION, - currentLocation = null - ), + initialState: State = State(), getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, fakeLocationStateUseCase: FakeLocationStateUseCase, coroutineScope: CoroutineScope @@ -99,66 +96,58 @@ class FakeLocationFeature( initialState, coroutineScope, reducer = { state, effect -> when (effect) { - is Effect.QuickPrivacyUpdatedEffect -> state.copy(isEnabled = effect.isEnabled) is Effect.LocationModeUpdatedEffect -> state.copy( mode = effect.mode, specificLatitude = effect.latitude, specificLongitude = effect.longitude ) - Effect.QuickPrivacyDisabledWarningEffect -> state.copy(forceRefresh = !state.forceRefresh) + is Effect.ShowQuickPrivacyDisabledMessageEffect -> state.copy(showQuickPrivacyDisabledMessage = effect.show) else -> state } }, - actor = { state, action -> + actor = { _, action -> when (action) { - is Action.Init -> merge( - getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.map { Effect.QuickPrivacyUpdatedEffect(it) }, - flow { - fakeLocationStateUseCase.startListeningLocation() - val (mode, lat, lon) = fakeLocationStateUseCase.getLocationMode() - emit(Effect.LocationModeUpdatedEffect(mode = mode, latitude = lat, longitude = lon)) - }, - fakeLocationStateUseCase.currentLocation.map { Effect.LocationUpdatedEffect(it) } - ) + is Action.Init -> { + fakeLocationStateUseCase.startListeningLocation() + + merge( + getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.map { Effect.QuickPrivacyUpdatedEffect(it) }, + fakeLocationStateUseCase.configuredLocationMode.map { (mode, lat, lon) -> + Effect.LocationModeUpdatedEffect(mode = mode, latitude = lat, longitude = lon) + }, + fakeLocationStateUseCase.currentLocation.map { Effect.LocationUpdatedEffect(it) }, + getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { Effect.ShowQuickPrivacyDisabledMessageEffect(it) }, + ) + } is Action.LeaveScreen -> { fakeLocationStateUseCase.stopListeningLocation() flowOf(Effect.NoEffect) } is Action.SetSpecificLocationAction -> { - if (state.isEnabled) { - fakeLocationStateUseCase.setSpecificLocation( - action.latitude, - action.longitude - ) - flowOf( - Effect.LocationModeUpdatedEffect( - mode = LocationMode.SPECIFIC_LOCATION, - latitude = action.latitude, - longitude = action.longitude - ) - ) - } else flowOf(Effect.QuickPrivacyDisabledWarningEffect) + fakeLocationStateUseCase.setSpecificLocation( + action.latitude, + action.longitude + ) + flowOf(Effect.NoEffect) } is Action.UseRandomLocationAction -> { - if (state.isEnabled) { - fakeLocationStateUseCase.setRandomLocation() - flowOf(Effect.LocationModeUpdatedEffect(LocationMode.RANDOM_LOCATION)) - } else flowOf(Effect.QuickPrivacyDisabledWarningEffect) + fakeLocationStateUseCase.setRandomLocation() + flowOf(Effect.NoEffect) } is Action.UseRealLocationAction -> { - if (state.isEnabled) { - fakeLocationStateUseCase.stopFakeLocation() - flowOf(Effect.LocationModeUpdatedEffect(LocationMode.REAL_LOCATION)) - } else flowOf(Effect.QuickPrivacyDisabledWarningEffect) + fakeLocationStateUseCase.stopFakeLocation() + flowOf(Effect.NoEffect) + } + is Action.CloseQuickPrivacyDisabledMessage -> { + getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage() + flowOf(Effect.NoEffect) } } }, - singleEventProducer = { _, _, effect -> + singleEventProducer = { state, _, effect -> when (effect) { is Effect.LocationUpdatedEffect -> - SingleEvent.LocationUpdatedEvent(effect.location) - Effect.QuickPrivacyDisabledWarningEffect -> - SingleEvent.ErrorEvent("Enabled Quick Privacy to use functionalities") + SingleEvent.LocationUpdatedEvent(state.mode, effect.location) is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message) else -> null } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt index bc35521..2999eb6 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt @@ -22,6 +22,7 @@ import android.content.Context import android.location.Location import android.os.Bundle import android.text.Editable +import android.util.Log import android.view.View import android.widget.Toast import androidx.annotation.NonNull @@ -29,6 +30,7 @@ import androidx.core.view.isVisible import androidx.core.widget.addTextChangedListener import androidx.fragment.app.viewModels import androidx.lifecycle.lifecycleScope +import com.google.android.material.snackbar.Snackbar import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout.END_ICON_CUSTOM @@ -48,6 +50,7 @@ import foundation.e.privacycentralapp.DependencyContainer import foundation.e.privacycentralapp.PrivacyCentralApplication import foundation.e.privacycentralapp.R import foundation.e.privacycentralapp.common.NavToolbarFragment +import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar import foundation.e.privacycentralapp.databinding.FragmentFakeLocationBinding import foundation.e.privacycentralapp.domain.entities.LocationMode import foundation.e.privacycentralapp.extensions.viewModelProviderFactoryOf @@ -78,6 +81,8 @@ class FakeLocationFragment : private var mapboxMap: MapboxMap? = null private var locationComponent: LocationComponent? = null + private var qpDisabledSnackbar: Snackbar? = null + private var inputJob: Job? = null companion object { @@ -97,18 +102,7 @@ class FakeLocationFragment : displayToast(event.error) } is FakeLocationFeature.SingleEvent.LocationUpdatedEvent -> { - if (isFirstLaunch && mapboxMap != null) { - mapboxMap?.moveCamera( - CameraUpdateFactory.newLatLng( - LatLng( - event.location?.latitude ?: 0.0, - event.location?.longitude ?: 0.0 - ) - ) - ) - isFirstLaunch = false - } - updateLocation(event.location) + updateLocation(event.location, event.mode) } } } @@ -151,8 +145,14 @@ class FakeLocationFragment : } // Bind click listeners once map is ready. bindClickListeners() + + render(viewModel.fakeLocationFeature.state.value) } } + + qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) { + viewModel.submitAction(Action.CloseQuickPrivacyDisabledMessage) + } } private fun getCoordinatesAfterTextChanged( @@ -232,6 +232,9 @@ class FakeLocationFragment : @SuppressLint("MissingPermission") override fun render(state: FakeLocationFeature.State) { + if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show() + else qpDisabledSnackbar?.dismiss() + binding.radioUseRandomLocation.apply { isChecked = state.mode == LocationMode.RANDOM_LOCATION isEnabled = state.isEnabled @@ -249,13 +252,14 @@ class FakeLocationFragment : binding.mapView.isEnabled = (state.mode == LocationMode.SPECIFIC_LOCATION) - if (state.mode != LocationMode.SPECIFIC_LOCATION) { + if (state.mode == LocationMode.REAL_LOCATION) { binding.centeredMarker.isVisible = false } else { binding.mapLoader.isVisible = false - binding.mapOverlay.isVisible = false + binding.mapOverlay.isVisible = state.mode != LocationMode.SPECIFIC_LOCATION binding.centeredMarker.isVisible = true + Log.d("LocationTest", "is mapboxMap null: ${mapboxMap == null}") mapboxMap?.moveCamera( CameraUpdateFactory.newLatLng( LatLng( @@ -276,7 +280,7 @@ class FakeLocationFragment : override fun actions(): Flow<Action> = viewModel.actions @SuppressLint("MissingPermission") - private fun updateLocation(lastLocation: Location?) { + private fun updateLocation(lastLocation: Location?, mode: LocationMode) { lastLocation?.let { location -> locationComponent?.isLocationComponentEnabled = true val locationUpdate = LocationUpdate.Builder() @@ -285,18 +289,24 @@ class FakeLocationFragment : .build() locationComponent?.forceLocationUpdate(locationUpdate) - if (!binding.mapView.isEnabled) { + if (mode == LocationMode.REAL_LOCATION) { binding.mapLoader.isVisible = false binding.mapOverlay.isVisible = false - mapboxMap?.animateCamera( - CameraUpdateFactory.newLatLng( - LatLng(location.latitude, location.longitude) - ) + + val update = CameraUpdateFactory.newLatLng( + LatLng(location.latitude, location.longitude) ) + + if (isFirstLaunch) { + mapboxMap?.moveCamera(update) + isFirstLaunch = false + } else { + mapboxMap?.animateCamera(update) + } } } ?: run { locationComponent?.isLocationComponentEnabled = false - if (!binding.mapView.isEnabled) { + if (mode == LocationMode.REAL_LOCATION) { binding.mapLoader.isVisible = true binding.mapOverlay.isVisible = true } |
