From 547f27ed5b03096d5b422dc74f43b2cc2bda6f7e Mon Sep 17 00:00:00 2001 From: Alexandr Alexeenko Date: Mon, 8 Nov 2021 12:11:58 +0300 Subject: [PATCH] Adapt fragments to fg sync Closes #155 --- .../gitstat/data/ReposRepository.kt | 5 + .../data/local/dao/ContributionsDao.kt | 4 + .../gitstat/data/local/dao/RepositoriesDao.kt | 4 + .../contributions/ContributionsFragment.kt | 100 ++++++++++-------- .../YearContributionsFragment.kt | 75 +++++++------ .../YearContributionRatesFragment.kt | 63 +++++------ .../gitstat/view/profile/ProfileFragment.kt | 55 +++++----- .../repositories/ReposOverviewFragment.kt | 45 ++++---- .../repositories/RepositoriesViewModel.kt | 4 + 9 files changed, 202 insertions(+), 153 deletions(-) diff --git a/app/src/main/java/by/alexandr7035/gitstat/data/ReposRepository.kt b/app/src/main/java/by/alexandr7035/gitstat/data/ReposRepository.kt index ebf8aa1d..d0f5bb0a 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/data/ReposRepository.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/data/ReposRepository.kt @@ -1,5 +1,6 @@ package by.alexandr7035.gitstat.data +import androidx.lifecycle.LiveData import by.alexandr7035.gitstat.core.AppPreferences import by.alexandr7035.gitstat.core.Language import by.alexandr7035.gitstat.data.local.dao.RepositoriesDao @@ -13,6 +14,10 @@ class ReposRepository @Inject constructor( private val appPreferences: AppPreferences, private val gson: Gson) { + fun getRepositoriesLiveData(): LiveData>{ + return dao.getRepositoriesLiveData() + } + suspend fun fetchAllRepositoriesFromDb(): List { return dao.getRepositories() } diff --git a/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/ContributionsDao.kt b/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/ContributionsDao.kt index 30d94e78..970ef0c4 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/ContributionsDao.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/ContributionsDao.kt @@ -33,9 +33,13 @@ interface ContributionsDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertContributionYearsCache(years: List) + @Query("SELECT * FROM contribution_years") fun getContributionYearsWithDaysLiveData(): LiveData> + @Query("SELECT * FROM contribution_years where id = (:yearId)") + suspend fun getContributionYearWithDays(yearId: Int): ContributionsYearWithDays + @Query("DELETE FROM contribution_years") fun clearContributionYears() diff --git a/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/RepositoriesDao.kt b/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/RepositoriesDao.kt index 741f8a6b..ef462826 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/RepositoriesDao.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/data/local/dao/RepositoriesDao.kt @@ -1,5 +1,6 @@ package by.alexandr7035.gitstat.data.local.dao +import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy @@ -11,6 +12,9 @@ interface RepositoriesDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertRepositories(repos: List) + @Query("select * from repositories") + fun getRepositoriesLiveData(): LiveData> + @Query("select * from repositories") suspend fun getRepositories(): List diff --git a/app/src/main/java/by/alexandr7035/gitstat/view/contributions/ContributionsFragment.kt b/app/src/main/java/by/alexandr7035/gitstat/view/contributions/ContributionsFragment.kt index 7e43ad43..75ac0a47 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/view/contributions/ContributionsFragment.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/view/contributions/ContributionsFragment.kt @@ -47,70 +47,82 @@ class ContributionsFragment : Fragment() { // Update data viewModel.getContributionYearsLiveData().observe(viewLifecycleOwner, { years -> - if (years.isNotEmpty()) { - yearContributionsAdapter = YearContributionsAdapter(this) - yearContributionsAdapter.setItems(years) - binding?.yearsViewPager?.adapter = yearContributionsAdapter - - // Set to last position - binding?.yearsViewPager?.setCurrentItem(years.size - 1, false) - binding?.currentYearView?.text = years[years.size-1].year.id.toString() - - // Change year in card title when viewpager item changes - binding?.yearsViewPager?.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() { - override fun onPageSelected(position: Int) { - super.onPageSelected(position) - Timber.d("Page changed callback") - binding?.currentYearView?.text = years[position].year.id.toString() - } - }) - - // Attach tablayout - TabLayoutMediator(binding!!.yearsTabLayout, binding!!.yearsViewPager) { - tab, position -> - }.attach() - + if (years != null) { + + if (years.isNotEmpty()) { + yearContributionsAdapter = YearContributionsAdapter(this) + yearContributionsAdapter.setItems(years) + binding?.yearsViewPager?.adapter = yearContributionsAdapter + + // Set to last position + binding?.yearsViewPager?.setCurrentItem(years.size - 1, false) + binding?.currentYearView?.text = years[years.size - 1].year.id.toString() + + // Change year in card title when viewpager item changes + binding?.yearsViewPager?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + Timber.d("Page changed callback") + binding?.currentYearView?.text = years[position].year.id.toString() + } + }) + + // Attach tablayout + TabLayoutMediator(binding!!.yearsTabLayout, binding!!.yearsViewPager) { tab, position -> + }.attach() + + } } }) viewModel.getContributionDaysLiveData().observe(viewLifecycleOwner, { contributions -> - val totalContributions = contributions.sumOf { it.count } - binding?.totalContributions?.text = totalContributions.toString() + if (contributions != null) { + val totalContributions = contributions.sumOf { it.count } + binding?.totalContributions?.text = totalContributions.toString() + } }) viewModel.getContributionYearsWithRatesLiveData().observe(viewLifecycleOwner, { rateYears -> - if (rateYears.isNotEmpty()) { - yearContributionsRateAdapter = YearContributionRatesAdapter(this) - yearContributionsRateAdapter.setItems(rateYears) - binding?.rateViewPager?.adapter = yearContributionsRateAdapter + if (rateYears != null) { + + if (rateYears.isNotEmpty()) { + yearContributionsRateAdapter = YearContributionRatesAdapter(this) + yearContributionsRateAdapter.setItems(rateYears) + binding?.rateViewPager?.adapter = yearContributionsRateAdapter - TabLayoutMediator(binding!!.rateTabLayout, binding!!.rateViewPager) { tab, position -> - }.attach() + TabLayoutMediator(binding!!.rateTabLayout, binding!!.rateViewPager) { tab, position -> + }.attach() - // Set to last position - binding?.rateViewPager?.setCurrentItem(rateYears.size - 1, false) + // Set to last position + binding?.rateViewPager?.setCurrentItem(rateYears.size - 1, false) - // Set total contribution rate in header - binding?.contributionsRate?.text = viewModel.getLastTotalContributionRateForYear(rateYears[rateYears.size - 1]).toString() + // Set total contribution rate in header + binding?.contributionsRate?.text = + viewModel.getLastTotalContributionRateForYear(rateYears[rateYears.size - 1]).toString() + } } }) viewModel.getContributionsRatioLiveData().observe(viewLifecycleOwner, { ratios -> - Timber.d("ratios $ratios") - // FIXME - val adapter = RatioLegendAdapter() - binding?.ratioLegendRecycler?.layoutManager = FlexboxLayoutManager(requireContext()) - binding?.ratioLegendRecycler?.adapter = adapter + if (ratios != null) { + + Timber.d("ratios $ratios") + + // FIXME + val adapter = RatioLegendAdapter() + binding?.ratioLegendRecycler?.layoutManager = FlexboxLayoutManager(requireContext()) + binding?.ratioLegendRecycler?.adapter = adapter - if (binding?.ratioChart != null) { - val plot = ContributionsRatioPlot() - plot.setupPlot(binding!!.ratioChart, ratios) - adapter.setItems(plot.getRatioLegendItems(binding!!.ratioChart, ratios)) + if (binding?.ratioChart != null) { + val plot = ContributionsRatioPlot() + plot.setupPlot(binding!!.ratioChart, ratios) + adapter.setItems(plot.getRatioLegendItems(binding!!.ratioChart, ratios)) + } } }) diff --git a/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_per_year/YearContributionsFragment.kt b/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_per_year/YearContributionsFragment.kt index c8be8322..2ae4216c 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_per_year/YearContributionsFragment.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_per_year/YearContributionsFragment.kt @@ -9,9 +9,11 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import by.alexandr7035.gitstat.R import by.alexandr7035.gitstat.databinding.ViewPlotContributionsYearBinding +import by.alexandr7035.gitstat.extensions.debug import by.alexandr7035.gitstat.view.contributions.ContributionsViewModel import by.alexandr7035.gitstat.view.contributions.plots.LinePlotFill import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber @AndroidEntryPoint class YearContributionsFragment: Fragment() { @@ -31,40 +33,45 @@ class YearContributionsFragment: Fragment() { viewModel.getContributionYearsWithDaysLiveData().observe(viewLifecycleOwner, { yearsData -> - // FIXME find better solution (obtain certain year from data layer) - val yearData = yearsData.findLast { - it.year.id == year - }!! - - // Set contributions count to cart title - val contributionsCount = yearData.contributionDays.sumOf { it.count } - binding?.contributionsCountView?.text = contributionsCount.toString() - - // Get contributions rate (for the year) and apply to the view - val contributionsRate = viewModel.getContributionRateForYear(yearData) - // Set same color to the rate view as for the plot - val bg = ContextCompat.getDrawable(requireContext(), R.drawable.background_rounded_shape) - val plotFill = LinePlotFill.getPlotFillForYear(requireContext(), yearData.year.id) - bg?.setTint(plotFill.lineColor) - binding?.contributionsRateView?.background = bg - binding?.contributionsRateView?.text = contributionsRate.toString() - - - // Show stub if no contributions for this year - if (contributionsCount == 0) { - binding?.emptyPlotStub?.visibility = View.VISIBLE - - binding?.contributionsChart?.visibility = View.GONE - binding?.contributionsRateView?.visibility = View.GONE - binding?.contributionsCountView?.visibility = View.GONE - binding?.yearCRLabel?.visibility = View.GONE - } - - // Set plot data - val contributionsCountPlot = ContributionsCountPlot() - if (binding?.contributionsChart != null) { - contributionsCountPlot.setupPLot(binding!!.contributionsChart) - contributionsCountPlot.setYearData(binding!!.contributionsChart, yearData) + Timber.debug("$year $yearsData") + + if (! yearsData.isNullOrEmpty()) { + + // FIXME find better solution (obtain certain year from data layer) + val yearData = yearsData.findLast { + it.year.id == year + }!! + + // Set contributions count to cart title + val contributionsCount = yearData.contributionDays.sumOf { it.count } + binding?.contributionsCountView?.text = contributionsCount.toString() + + // Get contributions rate (for the year) and apply to the view + val contributionsRate = viewModel.getContributionRateForYear(yearData) + // Set same color to the rate view as for the plot + val bg = ContextCompat.getDrawable(requireContext(), R.drawable.background_rounded_shape) + val plotFill = LinePlotFill.getPlotFillForYear(requireContext(), yearData.year.id) + bg?.setTint(plotFill.lineColor) + binding?.contributionsRateView?.background = bg + binding?.contributionsRateView?.text = contributionsRate.toString() + + + // Show stub if no contributions for this year + if (contributionsCount == 0) { + binding?.emptyPlotStub?.visibility = View.VISIBLE + + binding?.contributionsChart?.visibility = View.GONE + binding?.contributionsRateView?.visibility = View.GONE + binding?.contributionsCountView?.visibility = View.GONE + binding?.yearCRLabel?.visibility = View.GONE + } + + // Set plot data + val contributionsCountPlot = ContributionsCountPlot() + if (binding?.contributionsChart != null) { + contributionsCountPlot.setupPLot(binding!!.contributionsChart) + contributionsCountPlot.setYearData(binding!!.contributionsChart, yearData) + } } }) diff --git a/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_rate/YearContributionRatesFragment.kt b/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_rate/YearContributionRatesFragment.kt index 8bc720e3..e76e02a7 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_rate/YearContributionRatesFragment.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/view/contributions/plots/contributions_rate/YearContributionRatesFragment.kt @@ -32,37 +32,40 @@ class YearContributionRatesFragment : Fragment() { // Observe the result viewModel.getContributionYearsWithRatesLiveData().observe(viewLifecycleOwner, { yearsData -> - // FIXME find better solution (obtain certain year from data layer) - val yearData = yearsData.findLast { - it.year.id == year - }!! - - // Setup plot - if (binding?.rateChart != null) { - val plot = ContributionRatePlot() - plot.setupPLot(binding!!.rateChart) - plot.setYearData(binding!!.rateChart, yearData) - } - - // Set year title - binding?.year?.text = yearData.year.id.toString() - - // Background for contribution rate views - // Set same color as for the plot - val plotFill = LinePlotFill.getPlotFillForYear(requireContext(), yearData.year.id) - val bg = ContextCompat.getDrawable(requireContext(), R.drawable.background_rounded_shape) - bg?.setTint(plotFill.lineColor) - - // Peak contribution rate - val maxContributionsRate = viewModel.getMaxContributionRateForYear(yearData) - binding?.peakCRView?.background = bg - binding?.peakCRView?.text = maxContributionsRate.toString() - - // Last contribution rate (end of the year) - val lastContributionRate = viewModel.getLastTotalContributionRateForYear(yearData) - binding?.lastCRView?.background = bg - binding?.lastCRView?.text = lastContributionRate.toString() + if (! yearsData.isNullOrEmpty()) { + + // FIXME find better solution (obtain certain year from data layer) + val yearData = yearsData.findLast { + it.year.id == year + }!! + + // Setup plot + if (binding?.rateChart != null) { + val plot = ContributionRatePlot() + plot.setupPLot(binding!!.rateChart) + plot.setYearData(binding!!.rateChart, yearData) + } + + // Set year title + binding?.year?.text = yearData.year.id.toString() + + // Background for contribution rate views + // Set same color as for the plot + val plotFill = LinePlotFill.getPlotFillForYear(requireContext(), yearData.year.id) + val bg = ContextCompat.getDrawable(requireContext(), R.drawable.background_rounded_shape) + bg?.setTint(plotFill.lineColor) + + // Peak contribution rate + val maxContributionsRate = viewModel.getMaxContributionRateForYear(yearData) + binding?.peakCRView?.background = bg + binding?.peakCRView?.text = maxContributionsRate.toString() + + // Last contribution rate (end of the year) + val lastContributionRate = viewModel.getLastTotalContributionRateForYear(yearData) + binding?.lastCRView?.background = bg + binding?.lastCRView?.text = lastContributionRate.toString() + } }) } diff --git a/app/src/main/java/by/alexandr7035/gitstat/view/profile/ProfileFragment.kt b/app/src/main/java/by/alexandr7035/gitstat/view/profile/ProfileFragment.kt index fc323464..295e5471 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/view/profile/ProfileFragment.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/view/profile/ProfileFragment.kt @@ -16,6 +16,7 @@ import by.alexandr7035.gitstat.databinding.FragmentProfileBinding import by.alexandr7035.gitstat.view.MainActivity import com.squareup.picasso.Picasso import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber @AndroidEntryPoint @@ -49,39 +50,42 @@ class ProfileFragment : Fragment() { // Update profile data viewModel.getUserLiveData().observe(viewLifecycleOwner, { - Picasso.get().load(it.avatar_url).into(binding!!.profileImageView) + Timber.tag("DEBUG_TAG").d("livedata updated $it") - // This field can be empty - if (it.name.isEmpty()) { - binding?.nameView?.visibility = View.GONE - } - else { - binding?.nameView?.visibility = View.VISIBLE - binding?.nameView?.text = it.name - } + if (it != null) { - binding!!.loginView.text = "@${it.login}" + Picasso.get().load(it.avatar_url).into(binding!!.profileImageView) - binding!!.idView.text = it.id.toString() + // This field can be empty + if (it.name.isEmpty()) { + binding?.nameView?.visibility = View.GONE + } else { + binding?.nameView?.visibility = View.VISIBLE + binding?.nameView?.text = it.name + } - binding!!.createdView.text = DateFormat.format("dd.MM.yyyy HH:mm", it.created_at) - binding!!.updatedView.text = DateFormat.format("dd.MM.yyyy HH:mm", it.updated_at) + binding!!.loginView.text = "@${it.login}" - binding!!.followersView.text = it.followers.toString() + binding!!.idView.text = it.id.toString() - // This field can be empty - if (it.location.isEmpty()) { - binding!!.locationContainer.visibility = View.GONE - } - else { - binding!!.locationContainer.visibility = View.VISIBLE - binding!!.locationView.text = it.location - } + binding!!.createdView.text = DateFormat.format("dd.MM.yyyy HH:mm", it.created_at) + binding!!.updatedView.text = DateFormat.format("dd.MM.yyyy HH:mm", it.updated_at) - binding!!.totalReposView.text = it.total_repos_count.toString() - binding!!.privateReposView.text = it.private_repos_count.toString() - binding!!.publicReposView.text = it.public_repos_count.toString() + binding!!.followersView.text = it.followers.toString() + // This field can be empty + if (it.location.isEmpty()) { + binding!!.locationContainer.visibility = View.GONE + } else { + binding!!.locationContainer.visibility = View.VISIBLE + binding!!.locationView.text = it.location + } + + binding!!.totalReposView.text = it.total_repos_count.toString() + binding!!.privateReposView.text = it.private_repos_count.toString() + binding!!.publicReposView.text = it.public_repos_count.toString() + + } }) binding!!.reposStatDetailedBtn.setOnClickListener { @@ -91,6 +95,7 @@ class ProfileFragment : Fragment() { binding?.drawerBtn?.setOnClickListener { (requireActivity() as MainActivity).openDrawerMenu() } + } diff --git a/app/src/main/java/by/alexandr7035/gitstat/view/repositories/ReposOverviewFragment.kt b/app/src/main/java/by/alexandr7035/gitstat/view/repositories/ReposOverviewFragment.kt index c7233f36..cdeb32fe 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/view/repositories/ReposOverviewFragment.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/view/repositories/ReposOverviewFragment.kt @@ -12,6 +12,7 @@ import by.alexandr7035.gitstat.databinding.FragmentReposOverviewBinding import by.alexandr7035.gitstat.view.MainActivity import by.alexandr7035.gitstat.view.repositories.plots.languages_plot.LanguagesPlot import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber @AndroidEntryPoint class ReposOverviewFragment : Fragment() { @@ -34,28 +35,32 @@ class ReposOverviewFragment : Fragment() { plot.setupPlot(binding!!.languagesChart) } - viewModel.getAllRepositoriesListLiveData().observe(viewLifecycleOwner, { repos -> + viewModel.getRepositoriesLiveData().observe(viewLifecycleOwner, { repos -> - binding!!.totalReposCountView.text = repos.size.toString() - binding!!.privateReposCountView.text = repos.filter { it.isPrivate }.size.toString() - binding!!.publicReposCountView.text = repos.filter { !it.isPrivate }.size.toString() + if (repos != null) { - // Show stup instead of plot if list is empty - if (repos.isNullOrEmpty()) { - binding?.languagesChart?.visibility = View.GONE - binding?.noReposStub?.visibility = View.VISIBLE - } - else { - binding?.languagesChart?.visibility = View.VISIBLE - binding?.noReposStub?.visibility = View.GONE + Timber.tag("DEBUG_TAG").d("repos $repos") + + binding!!.totalReposCountView.text = repos.size.toString() + binding!!.privateReposCountView.text = repos.filter { it.isPrivate }.size.toString() + binding!!.publicReposCountView.text = repos.filter { !it.isPrivate }.size.toString() + + // Show stup instead of plot if list is empty + if (repos.isNullOrEmpty()) { + binding?.languagesChart?.visibility = View.GONE + binding?.noReposStub?.visibility = View.VISIBLE + } else { + binding?.languagesChart?.visibility = View.VISIBLE + binding?.noReposStub?.visibility = View.GONE - // Populate chart with data - plot.setLanguagesData( - chart = binding!!.languagesChart, - languages = viewModel.getLanguagesForReposList(repos), - totalReposCount = repos.size - ) + // Populate chart with data + plot.setLanguagesData( + chart = binding!!.languagesChart, + languages = viewModel.getLanguagesForReposList(repos), + totalReposCount = repos.size + ) + } } }) @@ -68,8 +73,8 @@ class ReposOverviewFragment : Fragment() { (requireActivity() as MainActivity).openDrawerMenu() } - // FIXME find better solution (see viewmodel) - viewModel.updateAllRepositoriesLiveData() +// // FIXME find better solution (see viewmodel) +// viewModel.updateAllRepositoriesLiveData() } diff --git a/app/src/main/java/by/alexandr7035/gitstat/view/repositories/RepositoriesViewModel.kt b/app/src/main/java/by/alexandr7035/gitstat/view/repositories/RepositoriesViewModel.kt index 5aafd419..77bd4520 100644 --- a/app/src/main/java/by/alexandr7035/gitstat/view/repositories/RepositoriesViewModel.kt +++ b/app/src/main/java/by/alexandr7035/gitstat/view/repositories/RepositoriesViewModel.kt @@ -22,6 +22,10 @@ class RepositoriesViewModel @Inject constructor(private val repository: ReposRep private val archivedReposLiveData = MutableLiveData>() private val tabRefreshedLiveData = MutableLiveData() + fun getRepositoriesLiveData(): LiveData> { + return repository.getRepositoriesLiveData() + } + // Repos livedata fun getAllRepositoriesListLiveData(): LiveData> { return allRepositoriesLiveData