From 0fdaa35d69b272588a4751c674f48e0e832ddf10 Mon Sep 17 00:00:00 2001 From: lmj0011 <9396189+lmj0011@users.noreply.github.com> Date: Mon, 15 Mar 2021 12:13:25 -0500 Subject: [PATCH] - version bump v1.4 - use enqueueUniqueWork for Workers making DB transactions to prevent duplicate row entries - display progress indicator when syncing libraries/projects --- app/build.gradle.kts | 4 +- app/deps.list.txt | 2 +- .../ui/libraries/LibrariesFragment.kt | 25 +++++++++- .../ui/projectsyncs/ProjectSyncsFragment.kt | 19 ++++++-- .../main/res/layout/fragment_libraries.xml | 48 +++++++++++++++++++ .../res/layout/fragment_project_syncs.xml | 13 +++++ app/src/main/res/values/strings.xml | 5 ++ 7 files changed, 108 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3f60e86..1ebc70a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -25,7 +25,7 @@ android { minSdkVersion(19) targetSdkVersion(30) versionCode(getCommitCount().toInt()) - versionName = "1.3" + versionName = "1.4" vectorDrawables { useSupportLibrary = true @@ -137,7 +137,7 @@ dependencies { implementation("androidx.core:core-ktx:1.3.2") implementation("androidx.appcompat:appcompat:1.2.0") - implementation("com.google.android.material:material:1.2.1") + implementation("com.google.android.material:material:1.3.0") implementation("androidx.constraintlayout:constraintlayout:2.0.1") implementation("androidx.vectordrawable:vectordrawable:1.1.0") implementation("androidx.navigation:navigation-fragment:${findProperty("fragment.version")}") diff --git a/app/deps.list.txt b/app/deps.list.txt index 2089b91..c1c0df9 100644 --- a/app/deps.list.txt +++ b/app/deps.list.txt @@ -8,7 +8,7 @@ org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.4.10 org.jetbrains.kotlin:kotlin-stdlib:1.4.10 androidx.core:core-ktx:1.3.2 androidx.appcompat:appcompat:1.2.0 -com.google.android.material:material:1.2.1 +com.google.android.material:material:1.3.0 androidx.constraintlayout:constraintlayout:2.0.1 androidx.vectordrawable:vectordrawable:1.1.0 androidx.navigation:navigation-fragment:2.3.0 diff --git a/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/libraries/LibrariesFragment.kt b/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/libraries/LibrariesFragment.kt index a4e1111..24287d7 100644 --- a/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/libraries/LibrariesFragment.kt +++ b/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/libraries/LibrariesFragment.kt @@ -11,9 +11,11 @@ import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import androidx.recyclerview.widget.DividerItemDecoration +import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.android.synthetic.main.fragment_libraries.* import kotlinx.coroutines.* import name.lmj0011.jetpackreleasetracker.MainActivity import name.lmj0011.jetpackreleasetracker.R @@ -59,6 +61,10 @@ class LibrariesFragment : Fragment(R.layout.fragment_libraries), SearchableRecyc binding = FragmentLibrariesBinding.bind(view) binding.lifecycleOwner = this binding.homeViewModel = librariesViewModel + binding.fetchLibrariesButton.setOnClickListener { + enqueueNewLibraryRefreshWorkerRequest() + (requireActivity() as MainActivity).showToastMessage(requireContext().getString(R.string.toast_message_fetching_libraries)) + } } private fun setupAdapter() { @@ -137,7 +143,12 @@ class LibrariesFragment : Fragment(R.layout.fragment_libraries), SearchableRecyc // if it's always empty, there's a problem with the network if (it.isEmpty()) { + binding.swipeRefresh.visibility = View.GONE + binding.emptyListContainer.visibility = View.VISIBLE enqueueNewLibraryRefreshWorkerRequest() + } else { + binding.swipeRefresh.visibility = View.VISIBLE + binding.emptyListContainer.visibility = View.GONE } listAdapter.submitLibArtifacts(it.toList()) @@ -164,20 +175,32 @@ class LibrariesFragment : Fragment(R.layout.fragment_libraries), SearchableRecyc .addTag(requireContext().getString(R.string.update_one_time_worker_tag)) .build() + progress_indicator.visibility = View.VISIBLE + WorkManager.getInstance(requireContext()) .getWorkInfoByIdLiveData(libraryRefreshWorkerRequest.id) .observe(viewLifecycleOwner, Observer { workInfo -> if (workInfo != null) { val progress = workInfo.progress val value = progress.getInt(ProjectSyncAllWorker.Progress, 0) + progress_indicator.progress = value + + /** + * start in indeterminate mode until ~20% complete, + * to give an immediate visual que of work being done + */ + if (value >= 20) progress_indicator.isIndeterminate = false if (value >= 100) { librariesViewModel.refreshLibraries() + progress_indicator.visibility = View.GONE + progress_indicator.isIndeterminate = true } } }) - WorkManager.getInstance(requireContext()).enqueue(libraryRefreshWorkerRequest) + WorkManager.getInstance(requireContext()) + .enqueueUniqueWork(getString(R.string.unique_work_name_fetch_libraries), ExistingWorkPolicy.KEEP, libraryRefreshWorkerRequest) } private fun refreshListAdapter(query: String? = null) { diff --git a/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/projectsyncs/ProjectSyncsFragment.kt b/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/projectsyncs/ProjectSyncsFragment.kt index aadcc58..1d3f75c 100644 --- a/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/projectsyncs/ProjectSyncsFragment.kt +++ b/app/src/main/java/name/lmj0011/jetpackreleasetracker/ui/projectsyncs/ProjectSyncsFragment.kt @@ -4,16 +4,16 @@ import android.os.Bundle import android.view.* import androidx.appcompat.widget.SearchView import androidx.core.os.bundleOf -import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.DividerItemDecoration +import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager +import kotlinx.android.synthetic.main.fragment_libraries.* import kotlinx.coroutines.* import name.lmj0011.jetpackreleasetracker.MainActivity import name.lmj0011.jetpackreleasetracker.R @@ -137,21 +137,32 @@ class ProjectSyncsFragment : Fragment(R.layout.fragment_project_syncs), Searchab .addTag(requireContext().getString(R.string.project_sync_all_one_time_worker_tag)) .build() + progress_indicator.visibility = View.VISIBLE + WorkManager.getInstance(requireActivity().application) .getWorkInfoByIdLiveData(projectSyncAllWorkRequest.id) .observe(viewLifecycleOwner, Observer { workInfo -> if (workInfo != null) { val progress = workInfo.progress val value = progress.getInt(Progress, 0) + progress_indicator.progress = value + + /** + * start in indeterminate mode until ~20% complete, + * to give an immediate visual que of work being done + */ + if (value >= 20) progress_indicator.isIndeterminate = false if (value >= 100) { projectSyncsViewModel.refreshProjectSyncs() + progress_indicator.visibility = View.GONE + progress_indicator.isIndeterminate = true } } }) - WorkManager.getInstance(requireActivity().application) - .enqueue(projectSyncAllWorkRequest) + WorkManager.getInstance(requireContext()) + .enqueueUniqueWork(getString(R.string.unique_work_name_sync_projects), ExistingWorkPolicy.KEEP, projectSyncAllWorkRequest) binding.swipeRefresh.isRefreshing = false (requireActivity() as MainActivity).showToastMessage(requireContext().getString(R.string.toast_message_syncing_projects)) diff --git a/app/src/main/res/layout/fragment_libraries.xml b/app/src/main/res/layout/fragment_libraries.xml index 4cea593..2ba5882 100644 --- a/app/src/main/res/layout/fragment_libraries.xml +++ b/app/src/main/res/layout/fragment_libraries.xml @@ -15,6 +15,54 @@ android:layout_height="match_parent" tools:context=".ui.libraries.LibrariesFragment"> + + + + + + +