Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ec4e4e7 authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

update UI on fake location

parent 366e4ffa
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.PrivacyCentralApp">
        android:theme="@style/Theme.PrivacyCentralApp"
        android:windowSoftInputMode="adjustResize"
        >
        <activity android:name=".main.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
+117 −105
Original line number Diff line number Diff line
@@ -26,16 +26,19 @@ import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.RadioButton
import android.widget.Toast
import androidx.annotation.NonNull
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.google.android.material.textfield.TextInputLayout.END_ICON_CUSTOM
import com.google.android.material.textfield.TextInputLayout.END_ICON_NONE
import com.mapbox.android.core.location.LocationEngineCallback
import com.mapbox.android.core.location.LocationEngineRequest
import com.mapbox.android.core.location.LocationEngineResult
@@ -56,6 +59,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.databinding.FragmentFakeLocationBinding
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.extensions.viewModelProviderFactoryOf
import kotlinx.coroutines.Job
@@ -81,13 +85,9 @@ class FakeLocationFragment :
        viewModelProviderFactoryOf { dependencyContainer.fakeLocationViewModelFactory.create() }
    }

    private lateinit var mapView: FakeLocationMapView
    private lateinit var binding: FragmentFakeLocationBinding

    private lateinit var mapboxMap: MapboxMap
    private lateinit var useRealLocationRadioBtn: RadioButton
    private lateinit var useRandomLocationRadioBtn: RadioButton
    private lateinit var useSpecificLocationRadioBtn: RadioButton
    private lateinit var latEditText: EditText
    private lateinit var longEditText: EditText

    private var hoveringMarker: ImageView? = null

@@ -178,7 +178,7 @@ class FakeLocationFragment :
        Mapbox.getInstance(requireContext(), getString(R.string.mapbox_key))
    }

    override fun getTitle(): String = getString(R.string.dashboard_location_title)
    override fun getTitle(): String = getString(R.string.location_title)

    private fun displayToast(message: String) {
        Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT)
@@ -187,11 +187,11 @@ class FakeLocationFragment :

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentFakeLocationBinding.bind(view)

        setupViews(view)
        mapView = view.findViewById<FakeLocationMapView>(R.id.mapView)
            .setup(savedInstanceState) { mapboxMap ->
        binding.mapView.setup(savedInstanceState) { mapboxMap ->
            this.mapboxMap = mapboxMap
            mapboxMap.getUiSettings().isRotateGesturesEnabled = false
            mapboxMap.setStyle(Style.MAPBOX_STREETS) { style ->
                enableLocationPlugin(style)
                hoveringMarker = ImageView(requireContext())
@@ -203,12 +203,12 @@ class FakeLocationFragment :
                        )
                        layoutParams = params
                    }
                    mapView.addView(hoveringMarker)
                binding.mapView.addView(hoveringMarker)
                hoveringMarker?.visibility = View.GONE // Keep hovering marker hidden by default

                mapboxMap.addOnCameraMoveStartedListener {
                    // Show marker when user starts to move across the map.
                        hoveringMarker?.visibility = if (mapView.isEnabled) {
                    hoveringMarker?.visibility = if (binding.mapView.isEnabled) {
                        View.VISIBLE
                    } else {
                        View.GONE
@@ -217,7 +217,7 @@ class FakeLocationFragment :
                }

                mapboxMap.addOnCameraMoveListener {
                        if (mapView.isEnabled) {
                    if (binding.mapView.isEnabled) {
                        viewModel.submitAction(
                            FakeLocationFeature.Action.UpdateLocationAction(
                                mapboxMap.cameraPosition.target
@@ -231,57 +231,68 @@ class FakeLocationFragment :
        }
    }

    private fun setupViews(view: View) {
        useRealLocationRadioBtn = view.findViewById(R.id.radio_use_real_location)
        useRandomLocationRadioBtn = view.findViewById(R.id.radio_use_random_location)
        useSpecificLocationRadioBtn = view.findViewById(R.id.radio_use_specific_location)
        latEditText = view.findViewById<TextInputLayout>(R.id.edittext_latitude).editText!!
        longEditText = view.findViewById<TextInputLayout>(R.id.edittext_longitude).editText!!
    }

    private fun bindClickListeners() {
        useRealLocationRadioBtn
            .setOnClickListener { radioButton ->
                toggleLocationType(radioButton)
            }
        useRandomLocationRadioBtn
            .setOnClickListener { radioButton ->
                toggleLocationType(radioButton)
            }
        useSpecificLocationRadioBtn
            .setOnClickListener { radioButton ->
                toggleLocationType(radioButton)
            }

        arrayOf(latEditText, longEditText).forEach { editText ->
            editText.addTextChangedListener(
                afterTextChanged = {
    private fun getCoordinatesAfterTextChanged(inputLayout: TextInputLayout, editText: TextInputEditText, isLat: Boolean) = { editable: Editable? ->
        inputJob?.cancel()
                    if (it?.length ?: 0 > 0 && editText.isEnabled) {
        if (editable != null && editable.length > 0 && editText.isEnabled) {
            inputJob = lifecycleScope.launch {
                delay(DEBOUNCE_PERIOD)
                ensureActive()
                try {
                                val lat = latEditText.text.toString().toDouble()
                                val long = longEditText.text.toString().toDouble()
                    val value = editable.toString().toDouble()
                    val maxValue = if (isLat) 90.0 else 180.0

                    if (value > maxValue || value < -maxValue) {
                        throw NumberFormatException("value $value is out of bounds")
                    }
                    inputLayout.error = null

                    inputLayout.setEndIconDrawable(R.drawable.ic_valid)
                    inputLayout.endIconMode = END_ICON_CUSTOM

                    // Here, value is valid, try to send the values
                    try {
                        val lat = binding.edittextLatitude.text.toString().toDouble()
                        val lon = binding.edittextLongitude.text.toString().toDouble()
                        if (lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) {
                            viewModel.submitAction(
                                    FakeLocationFeature.Action.SetCustomFakeLocationAction(
                                        lat,
                                        long
                                    )
                                FakeLocationFeature.Action.SetCustomFakeLocationAction(lat, lon)
                            )
                        }
                    } catch (e: NumberFormatException) {}
                } catch (e: NumberFormatException) {
                                Toast.makeText(
                                    requireContext(),
                                    getString(R.string.please_enter_valid_lat_long),
                                    Toast.LENGTH_SHORT
                                ).show()
                    inputLayout.endIconMode = END_ICON_NONE
                    inputLayout.error = getString(R.string.location_input_error)
                }
            }
        }
    }
            )

    private fun bindClickListeners() {
        binding.radioUseRealLocation.setOnClickListener { radioButton ->
            toggleLocationType(radioButton)
        }
        binding.radioUseRandomLocation.setOnClickListener { radioButton ->
            toggleLocationType(radioButton)
        }
        binding.radioUseSpecificLocation.setOnClickListener { radioButton ->
            toggleLocationType(radioButton)
        }

        binding.edittextLatitude.addTextChangedListener(
            afterTextChanged = getCoordinatesAfterTextChanged(
                binding.textlayoutLatitude,
                binding.edittextLatitude,
                true
            )
        )

        binding.edittextLongitude.addTextChangedListener(
            afterTextChanged = getCoordinatesAfterTextChanged(
                binding.textlayoutLongitude,
                binding.edittextLongitude,
                false
            )
        )
    }

    private fun toggleLocationType(radioButton: View?) {
@@ -313,17 +324,18 @@ class FakeLocationFragment :
    }

    override fun render(state: FakeLocationFeature.State) {
        latEditText.text =
            Editable.Factory.getInstance().newEditable(state.location.latitude.toString())
        longEditText.text =
            Editable.Factory.getInstance().newEditable(state.location.longitude.toString())
        useRandomLocationRadioBtn.isChecked = (state.location.mode == LocationMode.RANDOM_LOCATION)
        useSpecificLocationRadioBtn.isChecked =
        binding.radioUseRandomLocation.isChecked = (state.location.mode == LocationMode.RANDOM_LOCATION)
        binding.radioUseSpecificLocation.isChecked =
            (state.location.mode == LocationMode.CUSTOM_LOCATION)
        useRealLocationRadioBtn.isChecked = (state.location.mode == LocationMode.REAL_LOCATION)
        latEditText.isEnabled = (state.location.mode == LocationMode.CUSTOM_LOCATION)
        longEditText.isEnabled = (state.location.mode == LocationMode.CUSTOM_LOCATION)
        mapView.isEnabled = (state.location.mode == LocationMode.CUSTOM_LOCATION)
        binding.radioUseRealLocation.isChecked = (state.location.mode == LocationMode.REAL_LOCATION)

        binding.mapView.isEnabled = (state.location.mode == LocationMode.CUSTOM_LOCATION)

        binding.textlayoutLatitude.isVisible = (state.location.mode == LocationMode.CUSTOM_LOCATION)
        binding.textlayoutLongitude.isVisible = (state.location.mode == LocationMode.CUSTOM_LOCATION)

        binding.edittextLatitude.setText(state.location.latitude.toString())
        binding.edittextLongitude.setText(state.location.longitude.toString())
    }

    override fun actions(): Flow<FakeLocationFeature.Action> = viewModel.actions
@@ -359,32 +371,32 @@ class FakeLocationFragment :

    override fun onStart() {
        super.onStart()
        mapView.onStart()
        binding.mapView.onStart()
    }

    override fun onResume() {
        super.onResume()
        mapView.onResume()
        binding.mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mapView.onPause()
        binding.mapView.onPause()
    }

    override fun onStop() {
        super.onStop()
        mapView.onStop()
        binding.mapView.onStop()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
        binding.mapView.onLowMemory()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mapView.onDestroy()
        binding.mapView.onDestroy()
    }

    override fun onExplanationNeeded(permissionsToExplain: MutableList<String>?) {
+10 −0
Original line number Diff line number Diff line
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
  <path
      android:pathData="M9,16.2001L4.8,12.0001L3.4,13.4001L9,19.0001L21,7.0001L19.6,5.6001L9,16.2001Z"
      android:fillColor="#2CC766"
      android:fillType="evenOdd"/>
</vector>
+32 −46
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
@@ -18,7 +19,7 @@

        <LinearLayout
            android:layout_height="match_parent"
            android:layout_marginBottom="32dp"
            android:padding="16dp"
            android:layout_width="match_parent"
            android:orientation="vertical"
            tools:context=".main.MainActivity"
@@ -29,25 +30,8 @@
                android:layout_gravity="center_horizontal"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:paddingLeft="32dp"
                android:paddingRight="32dp"
                android:paddingTop="16dp"
                android:text="@string/fake_location_info"
                android:textColor="@color/black"
                android:textSize="14sp"
                />

            <TextView
                android:fontFamily="sans-serif-medium"
                android:gravity="center_vertical"
                android:id="@+id/learn_more_fake_location"
                android:layout_height="48dp"
                android:layout_width="wrap_content"
                android:paddingLeft="32dp"
                android:paddingRight="32dp"
                android:text="@string/learn_more"
                android:textColor="#007fff"
                android:textSize="14sp"
                android:text="@string/location_info"
                android:lineSpacingExtra="5sp"
                />

            <RadioGroup
@@ -55,56 +39,56 @@
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:paddingLeft="32dp"
                android:paddingRight="32dp"
                android:layout_marginTop="16dp"
                >

                <foundation.e.privacycentralapp.common.RightRadioButton
                    android:id="@+id/radio_use_real_location"
                    android:layout_height="wrap_content"
                    android:layout_height="52dp"
                    android:layout_width="match_parent"
                    android:text="@string/use_real_location"
                    android:textSize="16sp"
                    android:text="@string/location_use_real_location"
                    android:textSize="14sp"
                    />

                <foundation.e.privacycentralapp.common.RightRadioButton
                    android:id="@+id/radio_use_random_location"
                    android:layout_height="wrap_content"
                    android:layout_height="52dp"
                    android:layout_width="match_parent"
                    android:text="@string/use_random_location"
                    android:textSize="16sp"
                    android:text="@string/location_use_random_location"
                    android:textSize="14sp"
                    />

                <foundation.e.privacycentralapp.common.RightRadioButton
                    android:id="@+id/radio_use_specific_location"
                    android:layout_height="wrap_content"
                    android:layout_height="52dp"
                    android:layout_width="match_parent"
                    android:text="@string/use_specific_location"
                    android:textSize="16sp"
                    android:text="@string/location_use_specific_location"
                    android:textSize="14sp"
                    />
            </RadioGroup>


            <foundation.e.privacycentralapp.features.location.FakeLocationMapView
                android:id="@+id/mapView"
                android:layout_height="240dp"
                android:layout_marginBottom="16dp"
                android:layout_marginTop="32dp"
                android:layout_height="220dp"
                android:layout_marginTop="16dp"
                android:layout_width="match_parent"
                mapbox:mapbox_cameraZoom="8"
                />

            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:hint="@string/longitude"
                android:id="@+id/edittext_longitude"
                android:hint="@string/location_hint_longitude"
                android:id="@+id/textlayout_longitude"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:paddingLeft="32dp"
                android:paddingRight="32dp"
                android:layout_marginTop="16dp"
                app:endIconDrawable="@drawable/ic_valid"
                app:endIconMode="custom"
                app:endIconTint="@color/green_valid"
                >

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/edittext_longitude"
                    android:inputType="numberDecimal"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
@@ -113,16 +97,17 @@

            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:hint="@string/latitude"
                android:id="@+id/edittext_latitude"
                android:id="@+id/textlayout_latitude"
                android:hint="@string/location_hint_latitude"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_width="match_parent"
                android:paddingLeft="32dp"
                android:paddingRight="32dp"
                android:layout_marginTop="16dp"
                app:endIconDrawable="@drawable/ic_valid"
                app:endIconMode="custom"
                app:endIconTint="@color/green_valid"
                >

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/edittext_latitude"
                    android:inputType="numberDecimal"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
@@ -132,3 +117,4 @@
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

    <color name="orange_off">#FC7222</color>
    <color name="green_on">#169659</color>
    <color name="green_valid">#2CC766</color>



Loading