From c5d0d8aeea6ee5ea4b9f28cee1fb9b5d59519d79 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Tue, 17 Sep 2024 15:00:02 +0530 Subject: [PATCH] Improved the design of showing the downloading progress of online library. * Also, disabled the refresh layout so avoid unnecessary calls when a request is already in progress. --- .../library/OnlineLibraryFragment.kt | 53 ++++++++++++------- .../zimManager/AppProgressListenerProvider.kt | 7 ++- .../zimManager/OnlineLibraryStatus.kt | 21 ++++++++ .../zimManager/ZimManageViewModel.kt | 33 +++++++----- .../layout/fragment_destination_download.xml | 43 ++++++++++++--- .../core/data/remote/ProgressResponseBody.kt | 24 ++++----- 6 files changed, 128 insertions(+), 53 deletions(-) create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt index f26a4a64d..05fe1a31d 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt @@ -41,6 +41,7 @@ import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.view.MenuHost import androidx.core.view.MenuProvider +import androidx.core.view.isVisible import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Lifecycle import androidx.lifecycle.Observer @@ -86,6 +87,7 @@ import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog.YesNoDialog.WifiOnly import org.kiwix.kiwixmobile.databinding.FragmentDestinationDownloadBinding import org.kiwix.kiwixmobile.zimManager.NetworkState +import org.kiwix.kiwixmobile.zimManager.OnlineLibraryStatus import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel import org.kiwix.kiwixmobile.zimManager.libraryView.AvailableSpaceCalculator import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryAdapter @@ -192,16 +194,11 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { viewLifecycleOwner ) { if (it && !NetworkUtils.isWiFi(requireContext())) { + hideProgressBarOfFetchingOnlineLibrary() showInternetAccessViaMobileNetworkDialog() } } - zimManageViewModel.downloadProgress.observe(viewLifecycleOwner) { progress -> - fragmentDestinationDownloadBinding?.onlineLibraryProgressBar?.progress = progress - } - - zimManageViewModel.downloadStatus.observe(viewLifecycleOwner) { status -> - fragmentDestinationDownloadBinding?.libraryErrorText?.text = status - } + zimManageViewModel.downloadProgress.observe(viewLifecycleOwner, ::onLibraryStatusChanged) setupMenu() // hides keyboard when scrolled @@ -254,13 +251,11 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { dialogShower.show( WifiOnly, { - onRefreshStateChange(true) showRecyclerviewAndHideSwipeDownForLibraryErrorText() sharedPreferenceUtil.putPrefWifiOnly(false) zimManageViewModel.shouldShowWifiOnlyDialog.value = false }, { - onRefreshStateChange(false) context.toast( resources.getString(string.denied_internet_permission_message), Toast.LENGTH_SHORT @@ -285,17 +280,32 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { ) libraryErrorText.visibility = View.VISIBLE libraryList.visibility = View.GONE - onlineLibraryProgressBar.visibility = View.GONE } + hideProgressBarOfFetchingOnlineLibrary() } private fun showProgressBarOfFetchingOnlineLibrary() { + onRefreshStateChange(false) fragmentDestinationDownloadBinding?.apply { - onlineLibraryProgressBar.visibility = View.VISIBLE - libraryErrorText.apply { - visibility = View.VISIBLE - setText(string.reaching_remote_library) - } + librarySwipeRefresh.isEnabled = false + onlineLibraryProgressLayout.visibility = View.VISIBLE + onlineLibraryProgressStatusText.setText(string.reaching_remote_library) + } + } + + private fun hideProgressBarOfFetchingOnlineLibrary() { + onRefreshStateChange(false) + fragmentDestinationDownloadBinding?.apply { + librarySwipeRefresh.isEnabled = true + onlineLibraryProgressLayout.visibility = View.GONE + onlineLibraryProgressStatusText.setText(string.reaching_remote_library) + } + } + + private fun onLibraryStatusChanged(onlineLibraryStatus: OnlineLibraryStatus) { + fragmentDestinationDownloadBinding?.apply { + onlineLibraryProgressBar.progress = onlineLibraryStatus.progress + onlineLibraryProgressStatusText.text = onlineLibraryStatus.status } } @@ -312,17 +322,20 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { } private fun onRefreshStateChange(isRefreshing: Boolean?) { - fragmentDestinationDownloadBinding?.librarySwipeRefresh?.isRefreshing = isRefreshing == true + var refreshing = isRefreshing == true + // do not show the refreshing when the online library is downloading + if (fragmentDestinationDownloadBinding?.onlineLibraryProgressLayout?.isVisible == true) { + refreshing = false + } + fragmentDestinationDownloadBinding?.librarySwipeRefresh?.isRefreshing = refreshing } private fun onNetworkStateChange(networkState: NetworkState?) { when (networkState) { NetworkState.CONNECTED -> { if (NetworkUtils.isWiFi(requireContext())) { - onRefreshStateChange(true) refreshFragment() } else if (noWifiWithWifiOnlyPreferenceSet) { - onRefreshStateChange(false) hideRecyclerviewAndShowSwipeDownForLibraryErrorText() } } @@ -344,7 +357,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { ) fragmentDestinationDownloadBinding?.libraryErrorText?.visibility = View.VISIBLE } - fragmentDestinationDownloadBinding?.librarySwipeRefresh?.isRefreshing = false + hideProgressBarOfFetchingOnlineLibrary() } private fun noInternetSnackbar() { @@ -364,7 +377,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { if (it != null) { libraryAdapter.items = it } - fragmentDestinationDownloadBinding?.onlineLibraryProgressBar?.visibility = View.GONE + hideProgressBarOfFetchingOnlineLibrary() if (it?.isEmpty() == true) { fragmentDestinationDownloadBinding?.libraryErrorText?.setText( if (isNotConnected) string.no_network_connection diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/AppProgressListenerProvider.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/AppProgressListenerProvider.kt index 3e7b588b3..6a51267c2 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/AppProgressListenerProvider.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/AppProgressListenerProvider.kt @@ -26,6 +26,11 @@ class AppProgressListenerProvider( @Suppress("MagicNumber") override fun onProgress(bytesRead: Long, contentLength: Long, done: Boolean) { val progress = if (contentLength == -1L) 0 else (bytesRead * 100 / contentLength).toInt() - zimManageViewModel.downloadProgress.postValue(progress) + zimManageViewModel.downloadProgress.postValue( + OnlineLibraryStatus( + progress, + "Downloading online content" + ) + ) } } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt new file mode 100644 index 000000000..91c0f2c04 --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt @@ -0,0 +1,21 @@ +/* + * Kiwix Android + * Copyright (c) 2024 Kiwix + * 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 . + * + */ + +package org.kiwix.kiwixmobile.zimManager + +data class OnlineLibraryStatus(val progress: Int, val status: String) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt index 0ec056b3f..31715c981 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt @@ -140,8 +140,7 @@ class ZimManageViewModel @Inject constructor( val requestFiltering = BehaviorProcessor.createDefault("") private var compositeDisposable: CompositeDisposable? = CompositeDisposable() - val downloadProgress = MutableLiveData() - val downloadStatus = MutableLiveData() + val downloadProgress = MutableLiveData() init { // add listener to retrofit to get updates of downloading online library @@ -299,14 +298,6 @@ class ZimManageViewModel @Inject constructor( .map { } } } - .doOnEach { - downloadStatus.postValue("Reaching remote library") - } - .switchMap { - Flowable.fromCallable { - downloadStatus.postValue("Starting download of the online library") - } - } .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .flatMap { @@ -314,18 +305,32 @@ class ZimManageViewModel @Inject constructor( .toFlowable() .retry(5) .doOnSubscribe { - downloadStatus.postValue("Downloading library 0%") + downloadProgress.postValue(OnlineLibraryStatus(0, "Downloading library 0%")) } .map { response -> - downloadStatus.postValue("Downloading library... parsing response") + downloadProgress.postValue( + OnlineLibraryStatus( + 0, + "Downloading library... parsing response" + ) + ) response } .doFinally { - downloadStatus.postValue("Remote library downloaded, parsing data") + downloadProgress.postValue( + OnlineLibraryStatus( + 0, + "Remote library downloaded, parsing data" + ) + ) } .onErrorReturn { it.printStackTrace() - downloadStatus.postValue("Failed to download the library") + downloadProgress.postValue( + OnlineLibraryStatus( + 0, "Failed to download the library" + ) + ) LibraryNetworkEntity().apply { book = LinkedList() } } } diff --git a/app/src/main/res/layout/fragment_destination_download.xml b/app/src/main/res/layout/fragment_destination_download.xml index 194c268d4..137ae295c 100644 --- a/app/src/main/res/layout/fragment_destination_download.xml +++ b/app/src/main/res/layout/fragment_destination_download.xml @@ -47,8 +47,8 @@ android:id="@+id/libraryList" android:layout_width="match_parent" android:layout_height="match_parent" - android:scrollbars="vertical" android:contentDescription="@string/library" + android:scrollbars="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:listitem="@layout/item_download" /> @@ -66,13 +66,44 @@ app:layout_constraintVertical_bias="0.45" tools:ignore="RequiredSize" /> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + + + + + + diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ProgressResponseBody.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ProgressResponseBody.kt index ef05bc8b4..e045d056a 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ProgressResponseBody.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ProgressResponseBody.kt @@ -32,18 +32,17 @@ class ProgressResponseBody( private val progressListener: OnlineLibraryProgressListener ) : ResponseBody() { - private var bufferedSource: BufferedSource? = null + private lateinit var bufferedSource: BufferedSource override fun contentType(): MediaType? = responseBody.contentType() override fun contentLength(): Long = responseBody.contentLength() - @Suppress("UnsafeCallOnNullableType") override fun source(): BufferedSource { - if (bufferedSource == null) { + if (!::bufferedSource.isInitialized) { bufferedSource = source(responseBody.source()).buffer() } - return bufferedSource!! + return bufferedSource } private fun source(source: Source): Source { @@ -57,14 +56,15 @@ class ProgressResponseBody( totalBytesRead, responseBody.contentLength(), isDone - ).also { - Log.e( - "PROGRESS", - "onProgress: ${contentLength()} and byteRead = $totalBytesRead\n" + - " sink ${bytesRead == -1L} \n byteRead = $bytesRead " + - "\n bufferedSource = ${bufferedSource?.isOpen}" - ) - } + ) + .also { + Log.e( + "PROGRESS", + "onProgress: ${contentLength()} and byteRead = $totalBytesRead\n" + + " sink ${bytesRead == -1L} \n byteRead = $bytesRead " + + "\n bufferedSource = ${bufferedSource.isOpen}" + ) + } return bytesRead } }