diff --git a/app/detekt_baseline.xml b/app/detekt_baseline.xml
index 89953ee69..1c6340c34 100644
--- a/app/detekt_baseline.xml
+++ b/app/detekt_baseline.xml
@@ -5,7 +5,7 @@
EmptyFunctionBlock:None.kt$None${ }
EmptyFunctionBlock:SimplePageChangeListener.kt$SimplePageChangeListener${ }
LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( booksOnFileSystem: List<BookOnDisk>, activeDownloads: List<DownloadModel>, allLanguages: List<Language>, libraryNetworkEntity: LibraryNetworkEntity, filter: String, fileSystemState: FileSystemState )
- LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( private val downloadDao: DownloadRoomDao, private val bookDao: NewBookDao, private val languageDao: NewLanguagesDao, private val storageObserver: StorageObserver, private var kiwixService: KiwixService, private val context: Application, private val connectivityBroadcastReceiver: ConnectivityBroadcastReceiver, private val bookUtils: BookUtils, private val fat32Checker: Fat32Checker, private val defaultLanguageProvider: DefaultLanguageProvider, private val dataSource: DataSource, private val connectivityManager: ConnectivityManager, private val sharedPreferenceUtil: SharedPreferenceUtil )
+ LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( private val downloadDao: DownloadRoomDao, private val bookDao: NewBookDao, private val languageDao: NewLanguagesDao, private val storageObserver: StorageObserver, private var kiwixService: KiwixService, val context: Application, private val connectivityBroadcastReceiver: ConnectivityBroadcastReceiver, private val bookUtils: BookUtils, private val fat32Checker: Fat32Checker, private val defaultLanguageProvider: DefaultLanguageProvider, private val dataSource: DataSource, private val connectivityManager: ConnectivityManager, private val sharedPreferenceUtil: SharedPreferenceUtil )
MagicNumber:LibraryListItem.kt$LibraryListItem.LibraryDownloadItem$1000L
MagicNumber:PeerGroupHandshake.kt$PeerGroupHandshake$15000
MagicNumber:ShareFiles.kt$ShareFiles$24
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 05fe1a31d..47592ffff 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
@@ -87,7 +87,6 @@ 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
@@ -106,7 +105,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
@Inject lateinit var availableSpaceCalculator: AvailableSpaceCalculator
@Inject lateinit var alertDialogShower: AlertDialogShower
private var fragmentDestinationDownloadBinding: FragmentDestinationDownloadBinding? = null
-
+ private val lock = Any()
private var downloadBookItem: LibraryListItem.BookItem? = null
private val zimManageViewModel by lazy {
requireActivity().viewModel(viewModelFactory)
@@ -302,10 +301,11 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
}
}
- private fun onLibraryStatusChanged(onlineLibraryStatus: OnlineLibraryStatus) {
- fragmentDestinationDownloadBinding?.apply {
- onlineLibraryProgressBar.progress = onlineLibraryStatus.progress
- onlineLibraryProgressStatusText.text = onlineLibraryStatus.status
+ private fun onLibraryStatusChanged(libraryStatus: String) {
+ synchronized(lock) {
+ fragmentDestinationDownloadBinding?.apply {
+ onlineLibraryProgressStatusText.text = libraryStatus
+ }
}
}
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 6a51267c2..19dfb5653 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/AppProgressListenerProvider.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/AppProgressListenerProvider.kt
@@ -18,18 +18,27 @@
package org.kiwix.kiwixmobile.zimManager
+import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.data.remote.OnlineLibraryProgressListener
+import org.kiwix.kiwixmobile.core.downloader.downloadManager.DEFAULT_INT_VALUE
+import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED
+import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
class AppProgressListenerProvider(
private val zimManageViewModel: ZimManageViewModel
) : OnlineLibraryProgressListener {
@Suppress("MagicNumber")
- override fun onProgress(bytesRead: Long, contentLength: Long, done: Boolean) {
- val progress = if (contentLength == -1L) 0 else (bytesRead * 100 / contentLength).toInt()
+ override fun onProgress(bytesRead: Long, contentLength: Long) {
+ val progress =
+ if (contentLength == DEFAULT_INT_VALUE.toLong()) {
+ ZERO
+ } else {
+ (bytesRead * HUNDERED / contentLength).toInt() * 3
+ }
zimManageViewModel.downloadProgress.postValue(
- OnlineLibraryStatus(
- progress,
- "Downloading online content"
+ zimManageViewModel.context.getString(
+ R.string.downloading_library,
+ zimManageViewModel.context.getString(R.string.percentage, progress)
)
)
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt
deleted file mode 100644
index 91c0f2c04..000000000
--- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryStatus.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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 31715c981..89b114828 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt
@@ -34,6 +34,7 @@ import io.reactivex.processors.BehaviorProcessor
import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
+import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level.BASIC
import okhttp3.logging.HttpLoggingInterceptor.Level.NONE
@@ -47,6 +48,7 @@ import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
import org.kiwix.kiwixmobile.core.data.DataSource
import org.kiwix.kiwixmobile.core.data.remote.KiwixService
+import org.kiwix.kiwixmobile.core.data.remote.KiwixService.Companion.LIBRARY_NETWORK_PATH
import org.kiwix.kiwixmobile.core.data.remote.ProgressResponseBody
import org.kiwix.kiwixmobile.core.data.remote.UserAgentInterceptor
import org.kiwix.kiwixmobile.core.di.modules.CALL_TIMEOUT
@@ -106,7 +108,7 @@ class ZimManageViewModel @Inject constructor(
private val languageDao: NewLanguagesDao,
private val storageObserver: StorageObserver,
private var kiwixService: KiwixService,
- private val context: Application,
+ val context: Application,
private val connectivityBroadcastReceiver: ConnectivityBroadcastReceiver,
private val bookUtils: BookUtils,
private val fat32Checker: Fat32Checker,
@@ -140,7 +142,7 @@ class ZimManageViewModel @Inject constructor(
val requestFiltering = BehaviorProcessor.createDefault("")
private var compositeDisposable: CompositeDisposable? = CompositeDisposable()
- val downloadProgress = MutableLiveData()
+ val downloadProgress = MutableLiveData()
init {
// add listener to retrofit to get updates of downloading online library
@@ -150,6 +152,7 @@ class ZimManageViewModel @Inject constructor(
}
private fun createKiwixServiceWithProgressListener(): KiwixService {
+ val contentLength = getContentLengthOfLibraryXmlFile()
val customOkHttpClient = OkHttpClient().newBuilder()
.followRedirects(true)
.followSslRedirects(true)
@@ -168,7 +171,8 @@ class ZimManageViewModel @Inject constructor(
.body(
ProgressResponseBody(
originalResponse.body!!,
- AppProgressListenerProvider(this)
+ AppProgressListenerProvider(this),
+ contentLength
)
)
.build()
@@ -177,6 +181,29 @@ class ZimManageViewModel @Inject constructor(
return KiwixService.ServiceCreator.newHackListService(customOkHttpClient, KIWIX_DOWNLOAD_URL)
}
+ private fun getContentLengthOfLibraryXmlFile(): Long {
+ val headRequest = Request.Builder()
+ .url("$KIWIX_DOWNLOAD_URL$LIBRARY_NETWORK_PATH")
+ .head()
+ .header("Accept-Encoding", "identity")
+ .build()
+ val client = OkHttpClient().newBuilder()
+ .followRedirects(true)
+ .followSslRedirects(true)
+ .connectTimeout(CONNECTION_TIMEOUT, SECONDS)
+ .readTimeout(READ_TIMEOUT, SECONDS)
+ .callTimeout(CALL_TIMEOUT, SECONDS)
+ .addNetworkInterceptor(UserAgentInterceptor(USER_AGENT))
+ .build()
+ client.newCall(headRequest).execute().use { response ->
+ if (response.isSuccessful) {
+ return@getContentLengthOfLibraryXmlFile response.header("content-length")?.toLongOrNull()
+ ?: -1L
+ }
+ }
+ return -1L
+ }
+
@VisibleForTesting
fun onClearedExposed() {
onCleared()
@@ -300,37 +327,22 @@ class ZimManageViewModel @Inject constructor(
}
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
- .flatMap {
+ .concatMap {
kiwixService.library
.toFlowable()
.retry(5)
.doOnSubscribe {
- downloadProgress.postValue(OnlineLibraryStatus(0, "Downloading library 0%"))
+ downloadProgress.postValue(context.getString(R.string.start_server_label))
}
.map { response ->
- downloadProgress.postValue(
- OnlineLibraryStatus(
- 0,
- "Downloading library... parsing response"
- )
- )
+ downloadProgress.postValue(context.getString(R.string.parsing_remote_library))
response
}
.doFinally {
- downloadProgress.postValue(
- OnlineLibraryStatus(
- 0,
- "Remote library downloaded, parsing data"
- )
- )
+ downloadProgress.postValue(context.getString(R.string.parsing_remote_library))
}
.onErrorReturn {
it.printStackTrace()
- 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 137ae295c..1d8b7c9ae 100644
--- a/app/src/main/res/layout/fragment_destination_download.xml
+++ b/app/src/main/res/layout/fragment_destination_download.xml
@@ -67,12 +67,12 @@
tools:ignore="RequiredSize" />
+ android:padding="@dimen/find_in_page_button_padding">
+ android:layout_width="40dp"
+ android:layout_height="40dp" />
+ android:textSize="10sp"
+ tools:ignore="SmallSp" />
diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt
index 671c2986b..783340b5b 100644
--- a/buildSrc/src/main/kotlin/Versions.kt
+++ b/buildSrc/src/main/kotlin/Versions.kt
@@ -20,9 +20,9 @@ object Versions {
const val tracing: String = "1.1.0"
- const val com_squareup_retrofit2: String = "2.9.0"
+ const val com_squareup_retrofit2: String = "2.11.0"
- const val com_squareup_okhttp3: String = "4.10.0"
+ const val com_squareup_okhttp3: String = "4.12.0"
const val org_jetbrains_kotlin: String = "1.9.20"
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/OnlineLibraryProgressListener.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/OnlineLibraryProgressListener.kt
index dd2301aec..742eea780 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/OnlineLibraryProgressListener.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/OnlineLibraryProgressListener.kt
@@ -19,5 +19,5 @@
package org.kiwix.kiwixmobile.core.data.remote
interface OnlineLibraryProgressListener {
- fun onProgress(bytesRead: Long, contentLength: Long, done: Boolean)
+ fun onProgress(bytesRead: Long, contentLength: Long)
}
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 e045d056a..503e8a512 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
@@ -25,11 +25,13 @@ import okio.BufferedSource
import okio.ForwardingSource
import okio.Source
import okio.buffer
-import org.kiwix.kiwixmobile.core.utils.files.Log
+import org.kiwix.kiwixmobile.core.downloader.downloadManager.DEFAULT_INT_VALUE
+import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
class ProgressResponseBody(
private val responseBody: ResponseBody,
- private val progressListener: OnlineLibraryProgressListener
+ private val progressListener: OnlineLibraryProgressListener,
+ private val contentLength: Long
) : ResponseBody() {
private lateinit var bufferedSource: BufferedSource
@@ -37,7 +39,6 @@ class ProgressResponseBody(
override fun contentType(): MediaType? = responseBody.contentType()
override fun contentLength(): Long = responseBody.contentLength()
-
override fun source(): BufferedSource {
if (!::bufferedSource.isInitialized) {
bufferedSource = source(responseBody.source()).buffer()
@@ -47,24 +48,11 @@ class ProgressResponseBody(
private fun source(source: Source): Source {
return object : ForwardingSource(source) {
- var totalBytesRead = 0L
+ var totalBytesRead = ZERO.toLong()
override fun read(sink: Buffer, byteCount: Long): Long {
val bytesRead = super.read(sink, byteCount)
- totalBytesRead += if (bytesRead != -1L) bytesRead else 0
- val isDone = bytesRead == -1L
- progressListener.onProgress(
- totalBytesRead,
- responseBody.contentLength(),
- isDone
- )
- .also {
- Log.e(
- "PROGRESS",
- "onProgress: ${contentLength()} and byteRead = $totalBytesRead\n" +
- " sink ${bytesRead == -1L} \n byteRead = $bytesRead " +
- "\n bufferedSource = ${bufferedSource.isOpen}"
- )
- }
+ totalBytesRead += if (bytesRead != DEFAULT_INT_VALUE.toLong()) bytesRead else ZERO.toLong()
+ progressListener.onProgress(totalBytesRead, contentLength)
return bytesRead
}
}
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 3f856f264..5a8ee04b6 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -349,6 +349,9 @@
Allow
Swipe Down for Library
Reaching remote library
+ Parsing remote library
+ Starting download of the online library
+ Downloading library %s
- @string/on
- @string/off