summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
authorjacquarg <guillaume.jacquart@hoodbrains.com>2021-10-31 19:11:27 +0100
committerjacquarg <guillaume.jacquart@hoodbrains.com>2021-10-31 19:11:27 +0100
commitb0d9079811b08b95dd623d94c1d4338f28597d4c (patch)
tree52f409643ee6733c232e1218eb2ecbd1e4999240 /app/src
parent880a48c87686dfc976a11ade9429bc9c50d4c7f2 (diff)
Add graph view on home dashboard.
Diffstat (limited to 'app/src')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt9
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt29
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt60
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt74
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt73
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt12
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt40
-rw-r--r--app/src/main/res/drawable/bg_outlined.xml (renamed from app/src/main/res/drawable/outlined_background.xml)0
-rw-r--r--app/src/main/res/drawable/ic_disk.xml21
-rw-r--r--app/src/main/res/layout/fragment_dashboard.xml53
-rw-r--r--app/src/main/res/layout/fragment_internet_activity_policy.xml2
-rw-r--r--app/src/main/res/values/colors.xml3
-rw-r--r--app/src/main/res/values/strings.xml2
13 files changed, 236 insertions, 142 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index 1f7cd3d..ccb0a75 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -24,6 +24,8 @@ import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.usecases.AppListUseCase
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
+import foundation.e.privacycentralapp.dummy.TrackTrackersPrivacyMock
import foundation.e.privacycentralapp.features.dashboard.DashBoardViewModelFactory
import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyViewModelFactory
import foundation.e.privacycentralapp.features.location.FakeLocationViewModelFactory
@@ -66,7 +68,7 @@ class DependencyContainer constructor(val app: Application) {
// Repositories
private val localStateRepository by lazy { LocalStateRepository(context) }
-
+ private val trackTrackersPrivacyModule by lazy { TrackTrackersPrivacyMock() }
// Usecases
private val getQuickPrivacyStateUseCase by lazy {
GetQuickPrivacyStateUseCase(localStateRepository)
@@ -77,9 +79,12 @@ class DependencyContainer constructor(val app: Application) {
private val appListUseCase by lazy {
AppListUseCase(permissionsModule)
}
+ private val trackersStatisticsUseCase by lazy {
+ TrackersStatisticsUseCase(trackTrackersPrivacyModule)
+ }
val dashBoardViewModelFactory by lazy {
- DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase)
+ DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase, trackersStatisticsUseCase)
}
val fakeLocationViewModelFactory by lazy {
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
new file mode 100644
index 0000000..93fbc08
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.domain.usecases
+
+import foundation.e.privacycentralapp.dummy.TrackTrackersPrivacyMock
+
+class TrackersStatisticsUseCase(
+ private val trackTrackersPrivacyModule: TrackTrackersPrivacyMock
+) {
+
+ fun getPast24HoursTrackersCalls(): List<Int> {
+ return trackTrackersPrivacyModule.getPast24HoursTrackersCalls()
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt
new file mode 100644
index 0000000..76da6a2
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.dummy
+
+import foundation.e.privacymodules.trackers.ITrackTrackersPrivacyModule
+import foundation.e.privacymodules.trackers.Tracker
+
+class TrackTrackersPrivacyMock : ITrackTrackersPrivacyModule {
+ override fun getPast24HoursTrackersCalls(): List<Int> {
+ return listOf(
+ 2000, 2300, 130, 2500, 1000, 2000,
+ 2000, 2300, 130, 2500, 1000, 2000,
+ 2000, 2300, 130, 2500, 1000, 2000,
+ 2000, 2300, 130, 2500, 1000, 2000
+ )
+ }
+
+ override fun getPastMonthTrackersCalls(): List<Int> {
+ return listOf(
+ 20000, 23000, 24130, 12500, 31000, 22000,
+ 20000, 23000, 24130, 12500, 31000, 22000,
+ 20000, 23000, 24130, 12500, 31000, 22000,
+ 20000, 23000, 24130, 12500, 31000, 22000,
+ 20000, 23000, 24130, 12500, 31000, 22000
+ )
+ }
+
+ override fun getPastYearTrackersCalls(): List<Int> {
+ return listOf(
+ 620000, 823000, 424130, 712500, 831000, 922000,
+ 620000, 823000, 424130, 712500, 831000, 922000
+ )
+ }
+
+ override fun getTrackersCount(): Int {
+ return 72
+ }
+
+ override fun getTrackersForApp(appUid: Int): List<Tracker> {
+ return listOf(
+ Tracker("Crashlytics", null),
+ Tracker(label = "Facebook", null)
+ )
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt
index 9d439ec..d38d4f6 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt
@@ -26,7 +26,9 @@ import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
@@ -45,24 +47,17 @@ class DashboardFeature(
initialState, actor, reducer, coroutineScope, { message -> Log.d("DashboardFeature", message) },
singleEventProducer
) {
- sealed class State() {
- object LoadingState : State()
- data class DisabledState(
- val totalGraph: Int = 230,
- // val graphData
- val trackersCount: Int = 77,
- val activeTrackersCount: Int = 22
- ) : State()
- data class EnabledState(
- val isAllTrackersBlocked: Boolean = false,
- val locationMode: LocationMode = LocationMode.CUSTOM_LOCATION,
- val internetPrivacyMode: InternetPrivacyMode,
- val totalGraph: Int = 150,
- // val graphData
- val trackersCount: Int = 80,
- val activeTrackersCount: Int = 10
- ) : State()
- }
+ data class State(
+ val isQuickPrivacyEnabled: Boolean = false,
+ val isAllTrackersBlocked: Boolean = false,
+ val locationMode: LocationMode = LocationMode.REAL_LOCATION,
+ val internetPrivacyMode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP,
+ val totalGraph: Int? = null,
+ // val graphData
+ val trackersCount: Int? = null,
+ val activeTrackersCount: Int? = null,
+ val dayStatistics: List<Int>? = null
+ )
sealed class SingleEvent {
object NavigateToQuickProtectionSingleEvent : SingleEvent()
@@ -89,6 +84,7 @@ class DashboardFeature(
object NoEffect : Effect()
data class UpdateStateEffect(val isEnabled: Boolean) : Effect()
data class IpScramblingModeUpdatedEffect(val mode: InternetPrivacyMode) : Effect()
+ data class TrackersStatisticsUpdatedEffect(val dayStatistics: List<Int>) : Effect()
object OpenQuickPrivacyProtectionEffect : Effect()
data class OpenDashboardEffect(
@@ -118,36 +114,17 @@ class DashboardFeature(
fun create(
coroutineScope: CoroutineScope,
getPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
- ipScramblingStateUseCase: IpScramblingStateUseCase
+ ipScramblingStateUseCase: IpScramblingStateUseCase,
+ trackersStatisticsUseCase: TrackersStatisticsUseCase
): DashboardFeature =
DashboardFeature(
- initialState = State.DisabledState(),
+ initialState = State(),
coroutineScope,
reducer = { state, effect ->
- if (state is State.LoadingState) state
- else when (effect) {
- is Effect.UpdateStateEffect -> when {
- effect.isEnabled && state is State.EnabledState
- || !effect.isEnabled && state is State.DisabledState -> state
- effect.isEnabled && state is State.DisabledState -> State.EnabledState(
- isAllTrackersBlocked = false,
- locationMode = LocationMode.REAL_LOCATION,
- internetPrivacyMode = InternetPrivacyMode.REAL_IP,
- totalGraph = state.totalGraph,
- // val graphData
- trackersCount = state.trackersCount,
- activeTrackersCount = state.activeTrackersCount
- )
- !effect.isEnabled && state is State.EnabledState -> State.DisabledState(
- totalGraph = state.totalGraph,
- // val graphData
- trackersCount = state.trackersCount,
- activeTrackersCount = state.activeTrackersCount
- )
- else -> state
- }
- is Effect.IpScramblingModeUpdatedEffect -> if (state is State.EnabledState) state.copy(internetPrivacyMode = effect.mode)
- else state
+ when (effect) {
+ is Effect.UpdateStateEffect -> state.copy(isQuickPrivacyEnabled = effect.isEnabled)
+ is Effect.IpScramblingModeUpdatedEffect -> state.copy(internetPrivacyMode = effect.mode)
+ is Effect.TrackersStatisticsUpdatedEffect -> state.copy(dayStatistics = effect.dayStatistics)
/*is Effect.OpenDashboardEffect -> State.DashboardState(
effect.trackersCount,
@@ -196,13 +173,11 @@ class DashboardFeature(
else -> state
}
},
- actor = { state: State, action: Action ->
+ actor = { _: State, action: Action ->
Log.d("Feature", "action: $action")
when (action) {
Action.TogglePrivacyAction -> {
- if (state != State.LoadingState) {
- getPrivacyStateUseCase.toggle()
- }
+ getPrivacyStateUseCase.toggle()
flowOf(Effect.NoEffect)
}
@@ -213,6 +188,9 @@ class DashboardFeature(
},
ipScramblingStateUseCase.internetPrivacyMode.map {
Effect.IpScramblingModeUpdatedEffect(it)
+ },
+ flow {
+ emit(Effect.TrackersStatisticsUpdatedEffect(trackersStatisticsUseCase.getPast24HoursTrackersCalls()))
}
)
/*
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
index fade14b..abdf764 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
@@ -30,6 +30,9 @@ import androidx.fragment.app.activityViewModels
import androidx.fragment.app.add
import androidx.fragment.app.commit
import androidx.lifecycle.lifecycleScope
+import com.github.mikephil.charting.data.BarData
+import com.github.mikephil.charting.data.BarDataSet
+import com.github.mikephil.charting.data.BarEntry
import foundation.e.flowmvi.MVIView
import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
@@ -39,9 +42,7 @@ import foundation.e.privacycentralapp.databinding.FragmentDashboardBinding
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.extensions.viewModelProviderFactoryOf
-import foundation.e.privacycentralapp.features.dashboard.DashboardFeature.State.DisabledState
-import foundation.e.privacycentralapp.features.dashboard.DashboardFeature.State.EnabledState
-import foundation.e.privacycentralapp.features.dashboard.DashboardFeature.State.LoadingState
+import foundation.e.privacycentralapp.features.dashboard.DashboardFeature.State
import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyFragment
import foundation.e.privacycentralapp.features.location.FakeLocationFragment
import foundation.e.privacycentralapp.features.trackers.TrackersFragment
@@ -77,13 +78,6 @@ class DashboardFragment :
addToBackStack("dashboard")
}
}
- is DashboardFeature.SingleEvent.NavigateToQuickProtectionSingleEvent -> {
- requireActivity().supportFragmentManager.commit {
- add<QuickProtectionFragment>(R.id.container)
- setReorderingAllowed(true)
- addToBackStack("dashboard")
- }
- }
is DashboardFeature.SingleEvent.NavigateToInternetActivityPrivacySingleEvent -> {
requireActivity().supportFragmentManager.commit {
add<InternetPrivacyFragment>(R.id.container)
@@ -116,6 +110,17 @@ class DashboardFragment :
super.onViewCreated(view, savedInstanceState)
binding = FragmentDashboardBinding.bind(view)
+ binding.graph.apply {
+ description = null
+ setTouchEnabled(false)
+ setDrawGridBackground(false)
+ setDrawBorders(false)
+ axisLeft.isEnabled = false
+ axisRight.isEnabled = false
+ xAxis.isEnabled = false
+ legend.isEnabled = false
+ }
+
binding.togglePrivacyCentral.setOnClickListener {
viewModel.submitAction(DashboardFeature.Action.TogglePrivacyAction)
}
@@ -149,27 +154,26 @@ class DashboardFragment :
textView.append(clickToMore)
}
- override fun render(state: DashboardFeature.State) {
- val enabled = state is EnabledState
+ override fun render(state: State) {
+
binding.stateLabel.text = getString(
- if (enabled) R.string.dashboard_state_label_on
+ if (state.isQuickPrivacyEnabled) R.string.dashboard_state_label_on
else R.string.dashboard_state_label_off
)
binding.togglePrivacyCentral.setImageResource(
- if (enabled) R.drawable.ic_quick_privacy_on
+ if (state.isQuickPrivacyEnabled) R.drawable.ic_quick_privacy_on
else R.drawable.ic_quick_privacy_off
)
binding.stateLabel.setTextColor(
getColor(
requireContext(),
- if (enabled) R.color.green_on
+ if (state.isQuickPrivacyEnabled) R.color.green_on
else R.color.orange_off
)
)
- val trackersEnabled = state is EnabledState &&
- state.isAllTrackersBlocked
+ val trackersEnabled = state.isQuickPrivacyEnabled && state.isAllTrackersBlocked
binding.stateTrackers.text = getString(
if (trackersEnabled) R.string.dashboard_state_trackers_on
else R.string.dashboard_state_trackers_off
@@ -182,7 +186,7 @@ class DashboardFragment :
)
)
- val geolocEnabled = state is EnabledState && state.locationMode != LocationMode.REAL_LOCATION
+ val geolocEnabled = state.isQuickPrivacyEnabled && state.locationMode != LocationMode.REAL_LOCATION
binding.stateGeolocation.text = getString(
if (geolocEnabled) R.string.dashboard_state_geolocation_on
else R.string.dashboard_state_geolocation_off
@@ -195,8 +199,8 @@ class DashboardFragment :
)
)
- val ipAddressEnabled = state is EnabledState && state.internetPrivacyMode != InternetPrivacyMode.REAL_IP
- val isLoading = state is EnabledState && state.internetPrivacyMode in listOf(
+ val ipAddressEnabled = state.isQuickPrivacyEnabled && state.internetPrivacyMode != InternetPrivacyMode.REAL_IP
+ val isLoading = state.isQuickPrivacyEnabled && state.internetPrivacyMode in listOf(
InternetPrivacyMode.HIDE_IP_LOADING,
InternetPrivacyMode.REAL_IP_LOADING
)
@@ -216,6 +220,23 @@ class DashboardFragment :
)
)
+ state.dayStatistics?.let {
+ val trackersDataSet = BarDataSet(
+ it.mapIndexed { index, value -> BarEntry(index.toFloat(), value.toFloat()) },
+ getString(R.string.dashboard_graph_trackers_legend)
+ ).apply {
+ color = getColor(requireContext(), R.color.purple_chart)
+ setDrawValues(false)
+ }
+
+ binding.graph.data = BarData(trackersDataSet)
+ binding.graph.invalidate()
+ }
+
+ state.trackersCount?.let {
+ binding.graphLegend.text = getString(R.string.dashboard_graph_trackers_legend, it)
+ }
+
// binding.graphTotal.text = if (state == DashboardFeature.State.LoadingState) {
// ""
// } else {
@@ -225,16 +246,12 @@ class DashboardFragment :
// getString(R.string.dashboard_graph_total, value)
// }
- binding.amITracked.subtitle.text = if (state == LoadingState) ""
- else {
- val value = if (state is EnabledState) state.activeTrackersCount
- else if (state is DisabledState) state.activeTrackersCount
- else 0 // dummy
- getString(R.string.dashboard_am_i_tracked_subtitle, 77, value)
+ state.activeTrackersCount?.let {
+ binding.amITracked.subtitle.text = getString(R.string.dashboard_am_i_tracked_subtitle, 77, it)
}
binding.myLocation.subtitle.text = getString(
- if (state is EnabledState &&
+ if (state.isQuickPrivacyEnabled &&
state.locationMode != LocationMode.REAL_LOCATION
)
R.string.dashboard_location_subtitle_on
@@ -242,7 +259,7 @@ class DashboardFragment :
)
binding.internetActivityPrivacy.subtitle.text = getString(
- if (state is EnabledState &&
+ if (state.isQuickPrivacyEnabled &&
state.internetPrivacyMode != InternetPrivacyMode.REAL_IP
)
R.string.dashboard_internet_activity_privacy_subtitle_on
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
index 67801eb..fa24b1d 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
@@ -22,13 +22,15 @@ import androidx.lifecycle.viewModelScope
import foundation.e.privacycentralapp.common.Factory
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
class DashboardViewModel(
private val getPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
- private val ipScramblingStateUseCase: IpScramblingStateUseCase
+ private val ipScramblingStateUseCase: IpScramblingStateUseCase,
+ private val trackersStatisticsUseCase: TrackersStatisticsUseCase
) : ViewModel() {
private val _actions = MutableSharedFlow<DashboardFeature.Action>()
@@ -38,7 +40,8 @@ class DashboardViewModel(
DashboardFeature.create(
coroutineScope = viewModelScope,
getPrivacyStateUseCase = getPrivacyStateUseCase,
- ipScramblingStateUseCase = ipScramblingStateUseCase
+ ipScramblingStateUseCase = ipScramblingStateUseCase,
+ trackersStatisticsUseCase = trackersStatisticsUseCase
)
}
@@ -51,9 +54,10 @@ class DashboardViewModel(
class DashBoardViewModelFactory(
private val getPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
- private val ipScramblingStateUseCase: IpScramblingStateUseCase
+ private val ipScramblingStateUseCase: IpScramblingStateUseCase,
+ private val trackersStatisticsUseCase: TrackersStatisticsUseCase
) : Factory<DashboardViewModel> {
override fun create(): DashboardViewModel {
- return DashboardViewModel(getPrivacyStateUseCase, ipScramblingStateUseCase)
+ return DashboardViewModel(getPrivacyStateUseCase, ipScramblingStateUseCase, trackersStatisticsUseCase)
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt
deleted file mode 100644
index 981c8da..0000000
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2021 E FOUNDATION
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package foundation.e.privacycentralapp.features.dashboard
-
-import android.content.Context
-import androidx.activity.addCallback
-import androidx.fragment.app.activityViewModels
-import foundation.e.privacycentralapp.R
-import foundation.e.privacycentralapp.common.NavToolbarFragment
-
-class QuickProtectionFragment : NavToolbarFragment(R.layout.fragment_quick_protection) {
-
- private val viewModel: DashboardViewModel by activityViewModels()
-
- override fun getTitle(): String = getString(R.string.quick_protection)
-
- override fun onAttach(context: Context) {
- super.onAttach(context)
- requireActivity().onBackPressedDispatcher.addCallback(this, true) {
- // viewModel.submitAction(DashboardFeature.Action.ShowDashboardAction)
- this.isEnabled = false
- requireActivity().onBackPressed()
- }
- }
-}
diff --git a/app/src/main/res/drawable/outlined_background.xml b/app/src/main/res/drawable/bg_outlined.xml
index 2040f18..2040f18 100644
--- a/app/src/main/res/drawable/outlined_background.xml
+++ b/app/src/main/res/drawable/bg_outlined.xml
diff --git a/app/src/main/res/drawable/ic_disk.xml b/app/src/main/res/drawable/ic_disk.xml
new file mode 100644
index 0000000..92200b1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_disk.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2021 E FOUNDATION
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU General Public License as published by
+ ~ the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="@color/purple_chart" />
+</shape> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml
index c97d1a5..6976948 100644
--- a/app/src/main/res/layout/fragment_dashboard.xml
+++ b/app/src/main/res/layout/fragment_dashboard.xml
@@ -142,11 +142,14 @@ android:text="@string/dashboard_state_ipaddress_off"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="16dp">
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp"
+ >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dashboard_graph_label"
+ android:layout_marginLeft="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
@@ -160,6 +163,7 @@ android:text="@string/dashboard_state_ipaddress_off"
android:textColor="@color/grey_text_2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
+ android:layout_marginRight="16dp"
/>
<!-- <TextView-->
@@ -170,12 +174,35 @@ android:text="@string/dashboard_state_ipaddress_off"
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/graph_period"-->
<!-- />-->
- <ImageView
+
+ <com.github.mikephil.charting.charts.BarChart
android:id="@+id/graph"
- android:layout_height="160dp"
+ android:layout_height="100dp"
android:layout_width="match_parent"
- android:src="@drawable/dummy_leakage_analytics"
app:layout_constraintTop_toBottomOf="@+id/graph_period"
+ android:layout_marginTop="16dp"
+ />
+
+ <View
+ android:id="@+id/graph_legend_form"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/graph"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="16dp"
+ android:background="@drawable/ic_disk"
+ />
+ <TextView
+ android:id="@+id/graph_legend"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_form"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_form"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -183,7 +210,7 @@ android:text="@string/dashboard_state_ipaddress_off"
layout="@layout/dashboard_item_submenu_button"
android:id="@+id/am_i_tracked"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="88dp"
app:icon="@{@drawable/ic_tracked}"
app:title="@{@string/dashboard_am_i_tracked_title}"
app:subTitle='@{""}'
@@ -199,7 +226,7 @@ android:text="@string/dashboard_state_ipaddress_off"
layout="@layout/dashboard_item_submenu_button"
android:id="@+id/apps_permissions"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="88dp"
app:icon="@{@drawable/ic_apps_permissions}"
app:title="@{@string/dashboard_apps_permissions_title}"
app:subTitle='@{@string/dashboard_apps_permissions_subtitle}'
@@ -207,7 +234,7 @@ android:text="@string/dashboard_state_ipaddress_off"
<View
android:layout_width="match_parent"
android:layout_height="1dp"
- android:layout_marginStart="72dp"
+ android:layout_marginStart="48dp"
android:background="@color/grey_divider"
/>
@@ -215,7 +242,7 @@ android:text="@string/dashboard_state_ipaddress_off"
layout="@layout/dashboard_item_submenu_button"
android:id="@+id/my_location"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="88dp"
app:icon="@{@drawable/ic_my_location}"
app:title="@{@string/dashboard_location_title}"
app:subTitle='@{@string/dashboard_location_subtitle_off}'
@@ -223,7 +250,7 @@ android:text="@string/dashboard_state_ipaddress_off"
<View
android:layout_width="match_parent"
android:layout_height="1dp"
- android:layout_marginStart="72dp"
+ android:layout_marginStart="48dp"
android:background="@color/grey_divider"
/>
@@ -231,17 +258,11 @@ android:text="@string/dashboard_state_ipaddress_off"
layout="@layout/dashboard_item_submenu_button"
android:id="@+id/internet_activity_privacy"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="88dp"
app:icon="@{@drawable/ic_internet_activity}"
app:title="@{@string/dashboard_internet_activity_privacy_title}"
app:subTitle='@{@string/dashboard_internet_activity_privacy_subtitle_off}'
/>
- <View
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_marginStart="72dp"
- android:background="@color/grey_divider"
- />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/fragment_internet_activity_policy.xml b/app/src/main/res/layout/fragment_internet_activity_policy.xml
index 4f29776..a59d807 100644
--- a/app/src/main/res/layout/fragment_internet_activity_policy.xml
+++ b/app/src/main/res/layout/fragment_internet_activity_policy.xml
@@ -91,7 +91,7 @@
android:id="@+id/select_location_container"
android:layout_width="match_parent"
android:layout_height="54dp"
- android:background="@drawable/outlined_background"
+ android:background="@drawable/bg_outlined"
android:layout_marginTop="16dp"
android:padding="1dp"
>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index a3ebbeb..935d0a7 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -21,6 +21,5 @@
<color name="green_on">#169659</color>
<color name="green_valid">#2CC766</color>
-
-
+ <color name="purple_chart">#855CF8</color>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d675a79..7433080 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -17,7 +17,7 @@
<string name="dashboard_state_ipaddress_on">Hidden</string>
<string name="dashboard_graph_label">Personal data leakage</string>
<string name="dashboard_graph_period">Last 24 hours</string>
- <string name="dashboard_graph_total">%d hits</string>
+ <string name="dashboard_graph_trackers_legend">%d Trackers</string>
<string name="dashboard_am_i_tracked_title">Am I tracked?</string>
<string name="dashboard_am_i_tracked_subtitle">%1$d app trackers, %2$d active trackers</string>