summaryrefslogtreecommitdiff
path: root/app/src/main/java/foundation/e/privacycentralapp
diff options
context:
space:
mode:
authorjacquarg <guillaume.jacquart@hoodbrains.com>2021-11-01 21:24:09 +0100
committerjacquarg <guillaume.jacquart@hoodbrains.com>2021-11-01 21:24:09 +0100
commita484bf584f4163c8a0a1260e81d598fdec87ff3b (patch)
treed6895488aafed08ef1c178a3b7713024edc02635 /app/src/main/java/foundation/e/privacycentralapp
parentb0d9079811b08b95dd623d94c1d4338f28597d4c (diff)
Add trackers UI
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt6
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/AppsAdapter.kt67
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt16
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt12
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt16
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt77
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt118
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt28
9 files changed, 302 insertions, 40 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index ccb0a75..1ba235b 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -30,6 +30,7 @@ import foundation.e.privacycentralapp.features.dashboard.DashBoardViewModelFacto
import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyViewModelFactory
import foundation.e.privacycentralapp.features.location.FakeLocationViewModelFactory
import foundation.e.privacycentralapp.features.location.LocationApiDelegate
+import foundation.e.privacycentralapp.features.trackers.TrackersViewModelFactory
import foundation.e.privacymodules.ipscrambler.IpScramblerModule
import foundation.e.privacymodules.ipscramblermodule.IIpScramblerModule
import foundation.e.privacymodules.location.FakeLocation
@@ -83,6 +84,7 @@ class DependencyContainer constructor(val app: Application) {
TrackersStatisticsUseCase(trackTrackersPrivacyModule)
}
+ // ViewModelFactories
val dashBoardViewModelFactory by lazy {
DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase, trackersStatisticsUseCase)
}
@@ -96,4 +98,8 @@ class DependencyContainer constructor(val app: Application) {
val internetPrivacyViewModelFactory by lazy {
InternetPrivacyViewModelFactory(ipScramblerModule, getQuickPrivacyStateUseCase, ipScramblingStateUseCase, appListUseCase)
}
+
+ val trackersViewModelFactory by lazy {
+ TrackersViewModelFactory(getQuickPrivacyStateUseCase, trackersStatisticsUseCase, appListUseCase)
+ }
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/AppsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/common/AppsAdapter.kt
new file mode 100644
index 0000000..d66ce76
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/AppsAdapter.kt
@@ -0,0 +1,67 @@
+/*
+ * 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.common
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacymodules.permissions.data.ApplicationDescription
+
+class AppsAdapter(
+ private val itemsLayout: Int,
+ private val listener: (String) -> Unit
+) :
+ RecyclerView.Adapter<AppsAdapter.ViewHolder>() {
+
+ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val appName: TextView = view.findViewById(R.id.title)
+
+ fun bind(item: ApplicationDescription) {
+ appName.text = item.label
+
+ itemView.findViewById<ImageView>(R.id.icon).setImageDrawable(item.icon)
+ }
+ }
+
+ var dataSet: List<ApplicationDescription> = emptyList()
+ set(value) {
+ field = value
+ notifyDataSetChanged()
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(itemsLayout, parent, false)
+ val holder = ViewHolder(view)
+ holder.itemView.setOnClickListener { _ ->
+ listener(dataSet[holder.adapterPosition].packageName)
+ }
+ return holder
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val app = dataSet[position]
+ holder.bind(app)
+ }
+
+ override fun getItemCount(): Int = dataSet.size
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt
index 71b5e97..1817a0d 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt
@@ -22,7 +22,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.ImageView
-import android.widget.Switch
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import foundation.e.privacycentralapp.R
@@ -60,7 +59,6 @@ class ToggleAppsAdapter(
holder.togglePermission.setOnCheckedChangeListener { _, isChecked ->
listener(dataSet[holder.adapterPosition].first.packageName, isChecked)
}
- view.findViewById<Switch>(R.id.toggle)
return holder
}
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
index 93fbc08..33c3f64 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
@@ -26,4 +26,20 @@ class TrackersStatisticsUseCase(
fun getPast24HoursTrackersCalls(): List<Int> {
return trackTrackersPrivacyModule.getPast24HoursTrackersCalls()
}
+
+ fun getDayMonthYearStatistics(): Triple<List<Int>, List<Int>, List<Int>> {
+ return Triple(
+ trackTrackersPrivacyModule.getPast24HoursTrackersCalls(),
+ trackTrackersPrivacyModule.getPastMonthTrackersCalls(),
+ trackTrackersPrivacyModule.getPastYearTrackersCalls()
+ )
+ }
+
+ fun getDayMonthYearCounts(): Triple<Int, Int, Int> {
+ return Triple(
+ trackTrackersPrivacyModule.getPast24HoursTrackersCount(),
+ trackTrackersPrivacyModule.getPastMonthTrackersCount(),
+ trackTrackersPrivacyModule.getPastYearTrackersCount()
+ )
+ }
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt
index 76da6a2..55ca6ec 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt
@@ -30,6 +30,10 @@ class TrackTrackersPrivacyMock : ITrackTrackersPrivacyModule {
)
}
+ override fun getPast24HoursTrackersCount(): Int {
+ return 30
+ }
+
override fun getPastMonthTrackersCalls(): List<Int> {
return listOf(
20000, 23000, 24130, 12500, 31000, 22000,
@@ -40,6 +44,10 @@ class TrackTrackersPrivacyMock : ITrackTrackersPrivacyModule {
)
}
+ override fun getPastMonthTrackersCount(): Int {
+ return 43
+ }
+
override fun getPastYearTrackersCalls(): List<Int> {
return listOf(
620000, 823000, 424130, 712500, 831000, 922000,
@@ -47,6 +55,10 @@ class TrackTrackersPrivacyMock : ITrackTrackersPrivacyModule {
)
}
+ override fun getPastYearTrackersCount(): Int {
+ return 46
+ }
+
override fun getTrackersCount(): Int {
return 72
}
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 abdf764..1b4ad39 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
@@ -18,13 +18,8 @@
package foundation.e.privacycentralapp.features.dashboard
import android.content.Intent
-import android.graphics.Color
import android.os.Bundle
-import android.text.Spannable
-import android.text.SpannableString
-import android.text.style.ForegroundColorSpan
import android.view.View
-import android.widget.TextView
import androidx.core.content.ContextCompat.getColor
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.add
@@ -143,17 +138,6 @@ class DashboardFragment :
return getString(R.string.dashboard_title)
}
- private fun addClickToMore(textView: TextView) {
- val clickToMore = SpannableString(getString(R.string.click_to_learn_more))
- clickToMore.setSpan(
- ForegroundColorSpan(Color.parseColor("#007fff")),
- 0,
- clickToMore.length,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- )
- textView.append(clickToMore)
- }
-
override fun render(state: State) {
binding.stateLabel.text = getString(
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt
index 9400181..0394abb 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt
@@ -22,11 +22,17 @@ import foundation.e.flowmvi.Actor
import foundation.e.flowmvi.Reducer
import foundation.e.flowmvi.SingleEventProducer
import foundation.e.flowmvi.feature.BaseFeature
+import foundation.e.privacycentralapp.domain.usecases.AppListUseCase
+import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import foundation.e.privacycentralapp.dummy.Tracker
import foundation.e.privacycentralapp.dummy.TrackersDataSource
+import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
// Define a state machine for Tracker feature.
class TrackersFeature(
@@ -44,16 +50,28 @@ class TrackersFeature(
singleEventProducer
) {
data class State(
+ val dayStatistics: List<Int>? = null,
+ val dayTrackersCount: Int? = null,
+ val monthStatistics: List<Int>? = null,
+ val monthTrackersCount: Int? = null,
+ val yearStatistics: List<Int>? = null,
+ val yearTrackersCount: Int? = null,
+ val apps: List<ApplicationDescription>? = null,
+
val trackers: List<Tracker> = emptyList(),
val currentSelectedTracker: Tracker? = null
)
sealed class SingleEvent {
data class ErrorEvent(val error: String) : SingleEvent()
+ data class OpenAppDetailsEvent(val packageName: String) : SingleEvent()
object BlockerErrorEvent : SingleEvent()
}
sealed class Action {
+ object InitAction : Action()
+ data class ClickAppAction(val packageName: String) : Action()
+
object ObserveTrackers : Action()
data class SetSelectedTracker(val tracker: Tracker) : Action()
data class ToggleTrackerAction(
@@ -64,6 +82,19 @@ class TrackersFeature(
}
sealed class Effect {
+ data class TrackersStatisticsLoadedEffect(
+ val dayStatistics: List<Int>? = null,
+ val dayTrackersCount: Int? = null,
+ val monthStatistics: List<Int>? = null,
+ val monthTrackersCount: Int? = null,
+ val yearStatistics: List<Int>? = null,
+ val yearTrackersCount: Int? = null
+ ) : Effect()
+ data class AvailableAppsListEffect(
+ val apps: List<ApplicationDescription>
+ ) : Effect()
+ data class OpenAppDetailsEffect(val packageName: String) : Effect()
+ object QuickPrivacyDisabledWarningEffect : Effect()
data class TrackersLoadedEffect(val trackers: List<Tracker>) : Effect()
data class TrackerSelectedEffect(val tracker: Tracker) : Effect()
data class TrackerToggleEffect(val result: Boolean) : Effect()
@@ -74,12 +105,25 @@ class TrackersFeature(
companion object {
fun create(
initialState: State = State(),
- coroutineScope: CoroutineScope
+ coroutineScope: CoroutineScope,
+ getPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
+ trackersStatisticsUseCase: TrackersStatisticsUseCase,
+ appListUseCase: AppListUseCase
) = TrackersFeature(
initialState, coroutineScope,
reducer = { state, effect ->
when (effect) {
- is Effect.TrackersLoadedEffect -> State(effect.trackers)
+ is Effect.TrackersStatisticsLoadedEffect -> state.copy(
+ dayStatistics = effect.dayStatistics,
+ dayTrackersCount = effect.dayTrackersCount,
+ monthStatistics = effect.monthStatistics,
+ monthTrackersCount = effect.monthTrackersCount,
+ yearStatistics = effect.yearStatistics,
+ yearTrackersCount = effect.yearTrackersCount
+ )
+ is Effect.AvailableAppsListEffect -> state.copy(apps = effect.apps)
+
+ is Effect.TrackersLoadedEffect -> State()
is Effect.TrackerSelectedEffect -> state.copy(currentSelectedTracker = effect.tracker)
is Effect.ErrorEffect -> state
is Effect.TrackerToggleEffect -> {
@@ -88,10 +132,37 @@ class TrackersFeature(
is Effect.TrackerLoadedEffect -> {
state.copy(currentSelectedTracker = effect.tracker)
}
+ else -> state
}
},
actor = { state, action ->
when (action) {
+ Action.InitAction -> merge(
+ flow {
+ val statistics = trackersStatisticsUseCase.getDayMonthYearStatistics()
+ val counts = trackersStatisticsUseCase.getDayMonthYearCounts()
+ emit(
+ Effect.TrackersStatisticsLoadedEffect(
+ dayStatistics = statistics.first,
+ dayTrackersCount = counts.first,
+ monthStatistics = statistics.second,
+ monthTrackersCount = counts.second,
+ yearStatistics = statistics.third,
+ yearTrackersCount = counts.third
+ )
+ )
+ },
+ flow {
+ val apps = appListUseCase.getAppsUsingInternet()
+ emit(Effect.AvailableAppsListEffect(apps))
+ }
+ )
+
+ is Action.ClickAppAction -> flowOf(
+ if (getPrivacyStateUseCase.isQuickPrivacyEnabled)
+ Effect.OpenAppDetailsEffect(action.packageName)
+ else Effect.QuickPrivacyDisabledWarningEffect
+ )
Action.ObserveTrackers -> TrackersDataSource.trackers.map {
Effect.TrackersLoadedEffect(
it
@@ -131,9 +202,11 @@ class TrackersFeature(
singleEventProducer = { _, _, effect ->
when (effect) {
is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message)
+ is Effect.OpenAppDetailsEffect -> SingleEvent.OpenAppDetailsEvent(effect.packageName)
is Effect.TrackerToggleEffect -> {
if (!effect.result) SingleEvent.BlockerErrorEvent else null
}
+ Effect.QuickPrivacyDisabledWarningEffect -> SingleEvent.ErrorEvent("Enabled Quick Privacy to use functionalities")
else -> null
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
index e3dc941..441f39a 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
@@ -19,24 +19,39 @@ package foundation.e.privacycentralapp.features.trackers
import android.os.Bundle
import android.view.View
-import androidx.core.os.bundleOf
-import androidx.fragment.app.add
-import androidx.fragment.app.commit
+import android.widget.Toast
+import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
+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
import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.common.AppsAdapter
import foundation.e.privacycentralapp.common.NavToolbarFragment
+import foundation.e.privacycentralapp.databinding.FragmentTrackersBinding
+import foundation.e.privacycentralapp.databinding.TrackersItemGraphBinding
+import foundation.e.privacycentralapp.extensions.viewModelProviderFactoryOf
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collect
class TrackersFragment :
NavToolbarFragment(R.layout.fragment_trackers),
MVIView<TrackersFeature.State, TrackersFeature.Action> {
- private val viewModel: TrackersViewModel by viewModels()
- private lateinit var trackersAdapter: TrackersAdapter
+ private val dependencyContainer: DependencyContainer by lazy {
+ (this.requireActivity().application as PrivacyCentralApplication).dependencyContainer
+ }
+
+ private val viewModel: TrackersViewModel by viewModels {
+ viewModelProviderFactoryOf { dependencyContainer.trackersViewModelFactory.create() }
+ }
+
+ private lateinit var binding: FragmentTrackersBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -44,32 +59,99 @@ class TrackersFragment :
viewModel.trackersFeature.takeView(this, this@TrackersFragment)
}
lifecycleScope.launchWhenStarted {
- viewModel.submitAction(TrackersFeature.Action.ObserveTrackers)
+ viewModel.trackersFeature.singleEvents.collect { event ->
+ when (event) {
+ is TrackersFeature.SingleEvent.ErrorEvent -> {
+ displayToast(event.error)
+ }
+ is TrackersFeature.SingleEvent.OpenAppDetailsEvent -> {
+ displayToast(event.packageName)
+ }
+ }
+ }
+ }
+
+ lifecycleScope.launchWhenStarted {
+ viewModel.submitAction(TrackersFeature.Action.InitAction)
}
}
+ private fun displayToast(message: String) {
+ Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT)
+ .show()
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- trackersAdapter = TrackersAdapter {
- requireActivity().supportFragmentManager.commit {
- val bundle = bundleOf("TRACKER" to it.name)
- add<TrackerAppsFragment>(R.id.container, args = bundle)
- setReorderingAllowed(true)
- addToBackStack("trackers")
+
+ binding = FragmentTrackersBinding.bind(view)
+
+ listOf(binding.graphDay, binding.graphMonth, binding.graphYear).forEach {
+ it.graph.apply {
+ description = null
+ setTouchEnabled(false)
+ setDrawGridBackground(false)
+ setDrawBorders(false)
+ axisLeft.isEnabled = false
+ axisRight.isEnabled = false
+ xAxis.isEnabled = false
+ legend.isEnabled = false
}
- // viewModel.submitAction(TrackersFeature.Action.SetSelectedTracker(it))
}
- view.findViewById<RecyclerView>(R.id.recylcer_view_trackers)?.apply {
+
+ binding.apps.apply {
layoutManager = LinearLayoutManager(requireContext())
setHasFixedSize(true)
- adapter = trackersAdapter
+ adapter = AppsAdapter(R.layout.trackers_item_app) { packageName ->
+ viewModel.submitAction(
+ TrackersFeature.Action.ClickAppAction(packageName)
+ )
+ }
}
+
+ //
+ // requireActivity().supportFragmentManager.commit {
+ // val bundle = bundleOf("TRACKER" to it.name)
+ // add<TrackerAppsFragment>(R.id.container, args = bundle)
+ // setReorderingAllowed(true)
+ // addToBackStack("trackers")
+ // }
}
- override fun getTitle() = getString(R.string.trackers)
+ override fun getTitle() = getString(R.string.trackers_title)
override fun render(state: TrackersFeature.State) {
- trackersAdapter.setData(state.trackers)
+ if (state.dayStatistics != null && state.dayTrackersCount != null) {
+ renderGraph(state.dayTrackersCount, state.dayStatistics, binding.graphDay)
+ }
+
+ if (state.monthStatistics != null && state.monthTrackersCount != null) {
+ renderGraph(state.monthTrackersCount, state.monthStatistics, binding.graphMonth)
+ }
+
+ if (state.yearStatistics != null && state.yearTrackersCount != null) {
+ renderGraph(state.yearTrackersCount, state.yearStatistics, binding.graphYear)
+ }
+
+ state.apps?.let {
+ binding.apps.post {
+ (binding.apps.adapter as AppsAdapter?)?.dataSet = it
+ }
+ }
+ }
+
+ private fun renderGraph(trackersCount: Int, data: List<Int>, graphBinding: TrackersItemGraphBinding) {
+ val trackersDataSet = BarDataSet(
+ data.mapIndexed { index, value -> BarEntry(index.toFloat(), value.toFloat()) },
+ getString(R.string.trackers_count_label)
+ ).apply {
+ color = ContextCompat.getColor(requireContext(), R.color.purple_chart)
+ setDrawValues(false)
+ }
+
+ graphBinding.graph.data = BarData(trackersDataSet)
+ graphBinding.graph.invalidate()
+ graphBinding.trackersCountLabel.text = getString(R.string.trackers_count_label, trackersCount)
}
override fun actions(): Flow<TrackersFeature.Action> = viewModel.actions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
index ee89887..12b66d4 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
@@ -20,17 +20,30 @@ package foundation.e.privacycentralapp.features.trackers
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import foundation.e.privacycentralapp.common.Factory
+import foundation.e.privacycentralapp.domain.usecases.AppListUseCase
+import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
-class TrackersViewModel : ViewModel() {
+class TrackersViewModel(
+ private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
+ private val trackersStatisticsUseCase: TrackersStatisticsUseCase,
+ private val appListUseCase: AppListUseCase
+) : ViewModel() {
private val _actions = MutableSharedFlow<TrackersFeature.Action>()
val actions = _actions.asSharedFlow()
val trackersFeature: TrackersFeature by lazy {
- TrackersFeature.create(coroutineScope = viewModelScope)
+ TrackersFeature.create(
+ coroutineScope = viewModelScope,
+ getPrivacyStateUseCase = getQuickPrivacyStateUseCase,
+ trackersStatisticsUseCase = trackersStatisticsUseCase,
+ appListUseCase = appListUseCase
+ )
}
fun submitAction(action: TrackersFeature.Action) {
@@ -40,3 +53,14 @@ class TrackersViewModel : ViewModel() {
}
}
}
+
+class TrackersViewModelFactory(
+ private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
+ private val trackersStatisticsUseCase: TrackersStatisticsUseCase,
+ private val appListUseCase: AppListUseCase
+) :
+ Factory<TrackersViewModel> {
+ override fun create(): TrackersViewModel {
+ return TrackersViewModel(getQuickPrivacyStateUseCase, trackersStatisticsUseCase, appListUseCase)
+ }
+}