aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/foundation/e/privacycentralapp/features
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt87
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt52
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
}