diff --git a/app/src/main/java/com/mobilecoronatracker/data/persistence/CountriesFollowRepo.kt b/app/src/main/java/com/mobilecoronatracker/data/persistence/CountriesFollowRepo.kt new file mode 100644 index 0000000..ed10ffc --- /dev/null +++ b/app/src/main/java/com/mobilecoronatracker/data/persistence/CountriesFollowRepo.kt @@ -0,0 +1,7 @@ +package com.mobilecoronatracker.data.persistence + +interface CountriesFollowRepo { + fun addFollowedCountry(country: String) + fun removeFollowedCountry(country: String) + fun getFollowedCountries(): List +} diff --git a/app/src/main/java/com/mobilecoronatracker/data/persistence/impl/SharedPreferencesCountriesFollowRepo.kt b/app/src/main/java/com/mobilecoronatracker/data/persistence/impl/SharedPreferencesCountriesFollowRepo.kt new file mode 100644 index 0000000..8a0250c --- /dev/null +++ b/app/src/main/java/com/mobilecoronatracker/data/persistence/impl/SharedPreferencesCountriesFollowRepo.kt @@ -0,0 +1,43 @@ +package com.mobilecoronatracker.data.persistence.impl + +import android.content.Context +import android.content.SharedPreferences +import com.mobilecoronatracker.data.persistence.CountriesFollowRepo + +class SharedPreferencesCountriesFollowRepo(context: Context) : CountriesFollowRepo { + private val sharedPrefs: SharedPreferences + + init { + sharedPrefs = context.getSharedPreferences(SHARED_PREFS_FILE_NAME, SHARED_PREFS_MODE) + } + + override fun addFollowedCountry(country: String) { + val followed = sharedPrefs.getStringSet(FOLLOWED_COUNTRIES, emptySet()) ?: emptySet() + if (followed.contains(country)) { + return + } + val newSet = HashSet(followed) + newSet.add(country) + sharedPrefs.edit().putStringSet(FOLLOWED_COUNTRIES, newSet).apply() + } + + override fun removeFollowedCountry(country: String) { + val followed = sharedPrefs.getStringSet(FOLLOWED_COUNTRIES, emptySet()) ?: emptySet() + if (followed.contains(country)) { + val newSet = HashSet(followed) + newSet.remove(country) + sharedPrefs.edit().putStringSet(FOLLOWED_COUNTRIES, newSet).apply() + } + } + + override fun getFollowedCountries(): List { + val followed = sharedPrefs.getStringSet(FOLLOWED_COUNTRIES, emptySet()) ?: emptySet() + return followed.toList() + } + + companion object { + const val FOLLOWED_COUNTRIES = "corona.tracker.prefs.followed" + const val SHARED_PREFS_FILE_NAME = "corona.tracker.prefs" + const val SHARED_PREFS_MODE = Context.MODE_PRIVATE + } +} diff --git a/app/src/main/java/com/mobilecoronatracker/model/CountryReportModel.kt b/app/src/main/java/com/mobilecoronatracker/model/CountryReportModel.kt index bea8c5b..0aae622 100644 --- a/app/src/main/java/com/mobilecoronatracker/model/CountryReportModel.kt +++ b/app/src/main/java/com/mobilecoronatracker/model/CountryReportModel.kt @@ -2,17 +2,27 @@ package com.mobilecoronatracker.model import com.mobilecoronatracker.model.pojo.CovidCountryEntry -class CountryReportModel( - override var country: String, - override var cases: Int, - override var todayCases: Int, - override var deaths: Int, - override var todayDeaths: Int, - override var recovered: Int, - override var critical: Int, - override var active: Int +data class CountryReportModel( + override val country: String, + override val cases: Int, + override val todayCases: Int, + override val deaths: Int, + override val todayDeaths: Int, + override val recovered: Int, + override val critical: Int, + override val active: Int, + override var followed: Boolean ) : CountryReportModelable { constructor(data: CovidCountryEntry) : - this(data.country, data.cases, data.todayCases, data.deaths, data.todayDeaths, - data.recovered, data.critical, data.active) -} \ No newline at end of file + this( + data.country, + data.cases, + data.todayCases, + data.deaths, + data.todayDeaths, + data.recovered, + data.critical, + data.active, + followed = false + ) +} diff --git a/app/src/main/java/com/mobilecoronatracker/model/CountryReportModelable.kt b/app/src/main/java/com/mobilecoronatracker/model/CountryReportModelable.kt index aefbef8..c6d94e4 100644 --- a/app/src/main/java/com/mobilecoronatracker/model/CountryReportModelable.kt +++ b/app/src/main/java/com/mobilecoronatracker/model/CountryReportModelable.kt @@ -1,12 +1,13 @@ package com.mobilecoronatracker.model interface CountryReportModelable { - var country: String - var cases: Int - var todayCases: Int - var deaths: Int - var todayDeaths: Int - var recovered: Int - var critical: Int - var active: Int -} \ No newline at end of file + val country: String + val cases: Int + val todayCases: Int + val deaths: Int + val todayDeaths: Int + val recovered: Int + val critical: Int + val active: Int + var followed: Boolean +} diff --git a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListAdapter.kt b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListAdapter.kt index f1facee..f6d85e9 100644 --- a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListAdapter.kt +++ b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListAdapter.kt @@ -6,13 +6,17 @@ import androidx.recyclerview.widget.RecyclerView import com.mobilecoronatracker.databinding.ItemCountryReportBinding import com.mobilecoronatracker.model.CountryReportModelable -class CountriesListAdapter : RecyclerView.Adapter() { + +class CountriesListAdapter : + RecyclerView.Adapter() { var reports = emptyList() + var listener: CountryFollowListener? = null inner class ViewHolder(private val binding: ItemCountryReportBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(item: CountryReportModelable) { binding.item = item + binding.listener = listener binding.executePendingBindings() } } @@ -25,5 +29,6 @@ class CountriesListAdapter : RecyclerView.Adapter = emptyList() private var currentFilterText: String = "" override val countryReports = MutableLiveData>() @@ -42,15 +43,46 @@ class CountriesListViewModel : ViewModel(), CountriesListViewModelable, CovidCou dataSource.requestData() } + override fun onCountryFollowed(countryName: String) { + countriesFollowRepo.addFollowedCountry(countryName) + postFilteredList() + } + + override fun onCountryUnfollowed(countryName: String) { + countriesFollowRepo.removeFollowedCountry(countryName) + postFilteredList() + } + private fun postFilteredList() { - countryReports.postValue( - currentList.filter { - it.country - .toLowerCase(Locale.getDefault()) - .contains( - currentFilterText.toLowerCase(Locale.getDefault()) - ) - }) + val filtered = getFilteredList() + countryReports.postValue(getFollowStatusList(filtered)) isRefreshing.postValue(false) } -} \ No newline at end of file + + private fun getFilteredList(): List { + return currentList.filter { + it.country + .toLowerCase(Locale.getDefault()) + .contains( + currentFilterText.toLowerCase(Locale.getDefault()) + ) + } + } + + private fun getFollowStatusList(filtered: List): List { + val followedCountries = countriesFollowRepo.getFollowedCountries() + val followed = filtered.filter { + followedCountries.contains(it.country) + }.map { + it.followed = true + it + } + val notFollowed = filtered.filterNot { + followedCountries.contains(it.country) + }.map { + it.followed = false; + it + } + return followed + notFollowed + } +} diff --git a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListViewModelable.kt b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListViewModelable.kt index afe7c8b..cc6545f 100644 --- a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListViewModelable.kt +++ b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountriesListViewModelable.kt @@ -9,4 +9,4 @@ interface CountriesListViewModelable { val countryReports: LiveData> val isRefreshing: LiveData -} \ No newline at end of file +} diff --git a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountryFollowListener.kt b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountryFollowListener.kt new file mode 100644 index 0000000..9649671 --- /dev/null +++ b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/CountryFollowListener.kt @@ -0,0 +1,6 @@ +package com.mobilecoronatracker.ui.countriesreports + +interface CountryFollowListener { + fun onCountryFollowed(countryName: String) + fun onCountryUnfollowed(countryName: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/FragmentCountriesReports.kt b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/FragmentCountriesReports.kt index 8f5b748..0c1c820 100644 --- a/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/FragmentCountriesReports.kt +++ b/app/src/main/java/com/mobilecoronatracker/ui/countriesreports/FragmentCountriesReports.kt @@ -12,13 +12,18 @@ import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import com.mobilecoronatracker.R +import com.mobilecoronatracker.data.persistence.impl.SharedPreferencesCountriesFollowRepo import com.mobilecoronatracker.databinding.FragmentCountriesReportsBinding import com.mobilecoronatracker.ui.utils.hideKeyboard import kotlinx.android.synthetic.main.fragment_countries_reports.* class FragmentCountriesReports : Fragment() { - private val viewModel = CountriesListViewModel() - private val adapter = CountriesListAdapter() + private val viewModel by lazy { + CountriesListViewModel(SharedPreferencesCountriesFollowRepo(requireContext())) + } + private val adapter by lazy { + CountriesListAdapter() + } override fun onCreateView( inflater: LayoutInflater, @@ -29,6 +34,7 @@ class FragmentCountriesReports : Fragment() { val binding = DataBindingUtil.inflate( inflater, R.layout.fragment_countries_reports, container, false ) + adapter.listener = viewModel binding.adapter = adapter binding.viewModel = viewModel binding.lifecycleOwner = viewLifecycleOwner @@ -41,6 +47,11 @@ class FragmentCountriesReports : Fragment() { bindObservers() } + override fun onDestroyView() { + super.onDestroyView() + adapter.listener = null + } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.countries_reports_menu, menu) super.onCreateOptionsMenu(menu, inflater) diff --git a/app/src/main/res/drawable/ic_flag.xml b/app/src/main/res/drawable/ic_flag.xml new file mode 100644 index 0000000..4dd89b2 --- /dev/null +++ b/app/src/main/res/drawable/ic_flag.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/rounded_bottom_rect_bg.xml b/app/src/main/res/drawable/rounded_bottom_rect_bg.xml new file mode 100644 index 0000000..c0596f7 --- /dev/null +++ b/app/src/main/res/drawable/rounded_bottom_rect_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_countries_reports.xml b/app/src/main/res/layout/fragment_countries_reports.xml index 00f1a74..7f0762d 100644 --- a/app/src/main/res/layout/fragment_countries_reports.xml +++ b/app/src/main/res/layout/fragment_countries_reports.xml @@ -14,11 +14,11 @@ android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" - app:refreshing="@{viewModel.isRefreshing}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/countries_reports_search_view"> + app:layout_constraintTop_toBottomOf="@+id/countries_reports_search_view" + app:refreshing="@{viewModel.isRefreshing}"> + android:paddingBottom="@dimen/country_report_padding"> + app:layout_constraintGuide_percent="0.6" /> + + + + + + @@ -53,14 +79,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/today_cases_label_text" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="@+id/start_guideline" app:layout_constraintTop_toBottomOf="@id/cases_label" /> @@ -70,14 +97,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/deaths_label_text" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="@+id/start_guideline" app:layout_constraintTop_toBottomOf="@id/today_cases_label" /> @@ -87,14 +115,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/today_deaths_label_text" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="@+id/start_guideline" app:layout_constraintTop_toBottomOf="@id/deaths_label" /> @@ -104,14 +133,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/recovered_label_text" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="@+id/start_guideline" app:layout_constraintTop_toBottomOf="@id/today_deaths_label" /> @@ -121,14 +151,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/critical_label_text" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="@+id/start_guideline" app:layout_constraintTop_toBottomOf="@id/recovered_label" /> @@ -138,14 +169,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/active_label_text" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toStartOf="@+id/start_guideline" app:layout_constraintTop_toBottomOf="@id/critical_label" /> @@ -154,8 +186,14 @@ + + + + - \ No newline at end of file + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b7899b8..d0c5a34 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -18,4 +18,6 @@ W stanie krytycznym: Ta aplikacja jest darmowa i została stworzona aby ułatwić śledzenie postępu pandemii COVID-19 - choroby powodowanej przez koronawirusa SARS-CoV-2, który został odkryty w 2019 roku w Wuhan (Chiny). Aktywne: + Więcej danych + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 5d495f6..f659a7c 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -3,5 +3,6 @@ 16dp 16dp 10dp + 0dp 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b0be20..c0cf320 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -27,4 +27,5 @@ made by Freepik from www.flaticon.com World vector created by freepik - www.freepik.com provided by https://github.com/NovelCOVID/API + More data