diff --git a/app/detekt_baseline.xml b/app/detekt_baseline.xml
index afafc1a17..70ed398dd 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, 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, private val onlineLibraryManager: OnlineLibraryManager )
MagicNumber:LibraryListItem.kt$LibraryListItem.LibraryDownloadItem$1000L
MagicNumber:PeerGroupHandshake.kt$PeerGroupHandshake$15000
MagicNumber:ShareFiles.kt$ShareFiles$24
diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/ObjectBoxToRoomMigratorTest.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/ObjectBoxToRoomMigratorTest.kt
index 6f1a350f9..b579fab32 100644
--- a/app/src/androidTest/java/org/kiwix/kiwixmobile/ObjectBoxToRoomMigratorTest.kt
+++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/ObjectBoxToRoomMigratorTest.kt
@@ -35,6 +35,7 @@ import kotlinx.coroutines.runBlocking
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo
import org.junit.After
+import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
@@ -44,6 +45,7 @@ import org.junit.runner.RunWith
import org.kiwix.kiwixmobile.KiwixRoomDatabaseTest.Companion.getHistoryItem
import org.kiwix.kiwixmobile.KiwixRoomDatabaseTest.Companion.getNoteListItem
import org.kiwix.kiwixmobile.core.dao.entities.HistoryEntity
+import org.kiwix.kiwixmobile.core.dao.entities.LanguageEntity
import org.kiwix.kiwixmobile.core.dao.entities.NotesEntity
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchEntity
import org.kiwix.kiwixmobile.core.data.KiwixRoomDatabase
@@ -52,6 +54,7 @@ import org.kiwix.kiwixmobile.core.di.modules.DatabaseModule
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
+import org.kiwix.kiwixmobile.core.zim_manager.Language
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.TestUtils
@@ -212,10 +215,13 @@ class ObjectBoxToRoomMigratorTest {
private suspend fun clearRoomAndBoxStoreDatabases(box: Box) {
// delete history for testing other edge cases
- kiwixRoomDatabase.recentSearchRoomDao().deleteSearchHistory()
- kiwixRoomDatabase.historyRoomDao().deleteAllHistory()
- kiwixRoomDatabase.notesRoomDao()
- .deletePages(kiwixRoomDatabase.notesRoomDao().notes().first())
+ with(kiwixRoomDatabase) {
+ recentSearchRoomDao().deleteSearchHistory()
+ historyRoomDao().deleteAllHistory()
+ notesRoomDao()
+ .deletePages(kiwixRoomDatabase.notesRoomDao().notes().first())
+ languageRoomDao().deleteAllLanguages()
+ }
box.removeAll()
}
@@ -470,4 +476,53 @@ class ObjectBoxToRoomMigratorTest {
migrationTime < migrationMaxTime
)
}
+
+ @Test
+ fun migrateLanguages_shouldInsertDataIntoRoomDatabase() =
+ runBlocking {
+ val box = boxStore.boxFor(LanguageEntity::class.java)
+ // clear both databases for history to test more edge cases
+ clearRoomAndBoxStoreDatabases(box)
+
+ val language = Language("eng", true, 10)
+ val language1 = Language("fr", false, 1)
+
+ // insert into object box
+ box.put(LanguageEntity(language))
+ // migrate data into room database
+ objectBoxToRoomMigrator.migrateLanguages(box)
+ // check if data successfully migrated to room
+ var actualDataAfterMigration = kiwixRoomDatabase.languageRoomDao().languages().first()
+ assertEquals(actualDataAfterMigration.size, 1)
+ assertEquals(actualDataAfterMigration[0].language, language.language)
+ assertEquals(actualDataAfterMigration[0].occurencesOfLanguage, language.occurencesOfLanguage)
+ assertEquals(actualDataAfterMigration[0].active, language.active)
+
+ // clear both databases to test more edge cases
+ clearRoomAndBoxStoreDatabases(box)
+
+ // Migrate data from empty ObjectBox database
+ objectBoxToRoomMigrator.migrateLanguages(box)
+ val actualData = kiwixRoomDatabase.languageRoomDao().languages().first()
+ assertTrue(actualData.isEmpty())
+
+ // Test if data successfully migrated to Room and existing data is deleted.
+ kiwixRoomDatabase.languageRoomDao().insert(listOf(language))
+ box.put(LanguageEntity(language1))
+ objectBoxToRoomMigrator.migrateLanguages(box)
+
+ actualDataAfterMigration = kiwixRoomDatabase.languageRoomDao().languages().first()
+ assertEquals(1, actualDataAfterMigration.size)
+ val existingItem =
+ actualDataAfterMigration.find {
+ it.active == language.active && it.language == language.language
+ }
+ Assert.assertNull(existingItem)
+ val newItem =
+ actualDataAfterMigration.find {
+ it.active == language1.active && it.language == language1.language
+ }
+ assertNotNull(newItem)
+ clearRoomAndBoxStoreDatabases(box)
+ }
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/di/components/KiwixComponent.kt b/app/src/main/java/org/kiwix/kiwixmobile/di/components/KiwixComponent.kt
index 1178a6d1d..01587bde3 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/di/components/KiwixComponent.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/di/components/KiwixComponent.kt
@@ -22,17 +22,20 @@ import dagger.Component
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
import org.kiwix.kiwixmobile.di.KiwixScope
import org.kiwix.kiwixmobile.di.components.ServiceComponent.Builder
+import org.kiwix.kiwixmobile.di.modules.JNIModule
import org.kiwix.kiwixmobile.di.modules.KiwixModule
import org.kiwix.kiwixmobile.di.modules.KiwixViewModelModule
import org.kiwix.kiwixmobile.storage.StorageSelectDialog
+import org.kiwix.kiwixmobile.zimManager.OnlineLibraryManager
@KiwixScope
@Component(
dependencies = [CoreComponent::class],
- modules = [KiwixViewModelModule::class, KiwixModule::class]
+ modules = [KiwixViewModelModule::class, KiwixModule::class, JNIModule::class]
)
interface KiwixComponent {
fun activityComponentBuilder(): KiwixActivityComponent.Builder
fun serviceComponent(): Builder
fun inject(storageSelectDialog: StorageSelectDialog)
+ fun providesOnlineLibraryManager(): OnlineLibraryManager
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/di/modules/JNIModule.kt b/app/src/main/java/org/kiwix/kiwixmobile/di/modules/JNIModule.kt
new file mode 100644
index 000000000..6785167cd
--- /dev/null
+++ b/app/src/main/java/org/kiwix/kiwixmobile/di/modules/JNIModule.kt
@@ -0,0 +1,52 @@
+/*
+ * Kiwix Android
+ * Copyright (c) 2025 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.di.modules
+
+import dagger.Module
+import dagger.Provides
+import org.kiwix.kiwixmobile.di.KiwixScope
+import org.kiwix.kiwixmobile.zimManager.OnlineLibraryManager
+import org.kiwix.libkiwix.Library
+import org.kiwix.libkiwix.Manager
+import javax.inject.Named
+
+@Module
+class JNIModule {
+ @Provides
+ @Named(ONLINE_BOOKS_LIBRARY)
+ @KiwixScope
+ fun provideOnlineBooksLibrary(): Library = Library()
+
+ @Provides
+ @Named(ONLINE_BOOKS_MANAGER)
+ @KiwixScope
+ fun providesOnlineBooksManager(
+ @Named(ONLINE_BOOKS_LIBRARY) library: Library
+ ): Manager = Manager(library)
+
+ @Provides
+ @KiwixScope
+ fun provideOnlineLibraryManager(
+ @Named(ONLINE_BOOKS_LIBRARY) library: Library,
+ @Named(ONLINE_BOOKS_MANAGER) manager: Manager,
+ ) = OnlineLibraryManager(library, manager)
+}
+
+const val ONLINE_BOOKS_LIBRARY = "onlineBookLibrary"
+const val ONLINE_BOOKS_MANAGER = "onlineBookManager"
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModel.kt b/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModel.kt
index 434dcb871..45d4e0570 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModel.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModel.kt
@@ -29,7 +29,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import org.kiwix.kiwixmobile.core.base.SideEffect
-import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.language.composables.LanguageListItem.LanguageItem
import org.kiwix.kiwixmobile.language.viewmodel.Action.Filter
import org.kiwix.kiwixmobile.language.viewmodel.Action.SaveAll
@@ -41,7 +41,7 @@ import org.kiwix.kiwixmobile.language.viewmodel.State.Saving
import javax.inject.Inject
class LanguageViewModel @Inject constructor(
- private val languageDao: NewLanguagesDao
+ private val languageRoomDao: LanguageRoomDao
) : ViewModel() {
val state = MutableStateFlow(Loading)
val actions = MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE)
@@ -63,7 +63,7 @@ class LanguageViewModel @Inject constructor(
.launchIn(viewModelScope)
private fun observeLanguages() =
- languageDao.languages()
+ languageRoomDao.languages()
.filter { it.isNotEmpty() }
.onEach { languages -> actions.tryEmit(UpdateLanguages(languages)) }
.launchIn(viewModelScope)
@@ -112,7 +112,7 @@ class LanguageViewModel @Inject constructor(
effects.tryEmit(
SaveLanguagesAndFinish(
currentState.items,
- languageDao,
+ languageRoomDao,
viewModelScope
)
)
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt b/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt
index 9b5bc48a6..c262cbe29 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt
@@ -23,20 +23,20 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.kiwix.kiwixmobile.core.base.SideEffect
-import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.zim_manager.Language
@Suppress("InjectDispatcher")
data class SaveLanguagesAndFinish(
private val languages: List,
- private val languageDao: NewLanguagesDao,
+ private val languageRoomDao: LanguageRoomDao,
private val lifecycleScope: CoroutineScope
) : SideEffect {
override fun invokeWith(activity: AppCompatActivity) {
lifecycleScope.launch {
runCatching {
withContext(Dispatchers.IO) {
- languageDao.insert(languages)
+ languageRoomDao.insert(languages)
}
activity.onBackPressedDispatcher.onBackPressed()
}.onFailure {
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt
index 241d494a8..247491af5 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt
@@ -19,10 +19,17 @@
package org.kiwix.kiwixmobile.zimManager
import org.kiwix.kiwixmobile.core.entity.LibkiwixBook
+import org.kiwix.kiwixmobile.di.modules.ONLINE_BOOKS_LIBRARY
+import org.kiwix.kiwixmobile.di.modules.ONLINE_BOOKS_MANAGER
import org.kiwix.libkiwix.Library
import org.kiwix.libkiwix.Manager
+import javax.inject.Inject
+import javax.inject.Named
-class OnlineLibraryManager(private val library: Library, private val manager: Manager) {
+class OnlineLibraryManager @Inject constructor(
+ @Named(ONLINE_BOOKS_LIBRARY) private val library: Library,
+ @Named(ONLINE_BOOKS_MANAGER) private val manager: Manager,
+) {
suspend fun parseOPDSStream(content: String?, urlHost: String): Boolean =
runCatching {
manager.readOpds(content, urlHost)
@@ -40,4 +47,12 @@ class OnlineLibraryManager(private val library: Library, private val manager: Ma
}.onFailure { it.printStackTrace() }
return onlineBooksList
}
+
+ suspend fun getOnlineBooksLanguage(): List {
+ return runCatching {
+ library.booksLanguages.distinct()
+ }.onFailure {
+ it.printStackTrace()
+ }.getOrDefault(emptyList())
+ }
}
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 66e777f37..2b6c20635 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt
@@ -66,8 +66,8 @@ import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.isWifi
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk
-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.OPDS_LIBRARY_NETWORK_PATH
@@ -89,6 +89,7 @@ import org.kiwix.kiwixmobile.core.ui.components.ONE
import org.kiwix.kiwixmobile.core.ui.components.TWO
import org.kiwix.kiwixmobile.core.utils.BookUtils
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
+import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
import org.kiwix.kiwixmobile.core.utils.files.Log
import org.kiwix.kiwixmobile.core.utils.files.ScanningProgressListener
@@ -121,8 +122,6 @@ import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.Book
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.DividerItem
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.LibraryDownloadItem
import org.kiwix.libkiwix.Book
-import org.kiwix.libkiwix.Library
-import org.kiwix.libkiwix.Manager
import java.util.Locale
import java.util.concurrent.TimeUnit.SECONDS
import javax.inject.Inject
@@ -137,7 +136,7 @@ const val FOUR = 4
class ZimManageViewModel @Inject constructor(
private val downloadDao: DownloadRoomDao,
private val libkiwixBookOnDisk: LibkiwixBookOnDisk,
- private val languageDao: NewLanguagesDao,
+ private val languageRoomDao: LanguageRoomDao,
private val storageObserver: StorageObserver,
private var kiwixService: KiwixService,
val context: Application,
@@ -148,6 +147,7 @@ class ZimManageViewModel @Inject constructor(
private val dataSource: DataSource,
private val connectivityManager: ConnectivityManager,
private val sharedPreferenceUtil: SharedPreferenceUtil,
+ private val onlineLibraryManager: OnlineLibraryManager
) : ViewModel() {
sealed class FileSelectActions {
data class RequestNavigateTo(val bookOnDisk: BookOnDisk) : FileSelectActions()
@@ -160,12 +160,6 @@ class ZimManageViewModel @Inject constructor(
object UserClickedDownloadBooksButton : FileSelectActions()
}
- private val library by lazy { Library() }
- private val manager by lazy { Manager(library) }
-
- private val onlineLibraryManager by lazy {
- OnlineLibraryManager(library, manager)
- }
private var isUnitTestCase: Boolean = false
val sideEffects: MutableSharedFlow> = MutableSharedFlow()
private val _libraryItems = MutableStateFlow>(emptyList())
@@ -294,7 +288,7 @@ class ZimManageViewModel @Inject constructor(
private fun observeCoroutineFlows(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
val downloads = downloadDao.downloads()
val booksFromDao = books()
- val languages = languageDao.languages()
+ val languages = languageRoomDao.languages()
coroutineJobs.apply {
add(scanBooksFromStorage(dispatcher))
add(updateBookItems())
@@ -541,11 +535,11 @@ class ZimManageViewModel @Inject constructor(
.filter { it.isNotEmpty() }
.distinctUntilChanged()
.catch { it.printStackTrace() }
- .onEach { languageDao.insert(it) }
+ .onEach { languageRoomDao.insert(it) }
.flowOn(dispatcher)
.launchIn(viewModelScope)
- private fun combineToLanguageList(
+ private suspend fun combineToLanguageList(
booksFromNetwork: List,
allLanguages: List
) = when {
@@ -579,19 +573,28 @@ class ZimManageViewModel @Inject constructor(
private fun MutableMap.increment(key: K) =
apply { set(key, getOrElse(key) { 0 } + 1) }
- private fun fromLocalesWithNetworkMatchesSetActiveBy(
+ private suspend fun fromLocalesWithNetworkMatchesSetActiveBy(
networkLanguageCounts: MutableMap,
listToActivateBy: List
- ) = Locale.getISOLanguages()
- .map { it.convertToLocal() }
- .filter { networkLanguageCounts.containsKey(it.isO3Language) }
- .map { locale ->
- Language(
- locale.isO3Language,
- languageIsActive(listToActivateBy, locale),
- networkLanguageCounts.getOrElse(locale.isO3Language) { 0 }
- )
+ ) = onlineLibraryManager.getOnlineBooksLanguage()
+ .mapNotNull { code ->
+ runCatching {
+ val locale = code.convertToLocal()
+ val o3 = locale.isO3Language
+ if (networkLanguageCounts.containsKey(o3)) {
+ Language(
+ o3,
+ languageIsActive(listToActivateBy, locale),
+ networkLanguageCounts.getOrElse(o3) { 0 }
+ )
+ } else {
+ null
+ }
+ }.onFailure {
+ Log.w(TAG_KIWIX, "Unsupported locale code: $code", it)
+ }.getOrNull()
}
+ .distinctBy { it.language }
private fun defaultLanguage() =
listOf(
diff --git a/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModelTest.kt b/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModelTest.kt
index aa374e60e..aa13e4f60 100644
--- a/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModelTest.kt
+++ b/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/LanguageViewModelTest.kt
@@ -28,7 +28,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
-import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.zim_manager.Language
import org.kiwix.kiwixmobile.language.composables.LanguageListItem
import org.kiwix.kiwixmobile.language.viewmodel.Action.Filter
@@ -46,7 +46,7 @@ fun languageItem(language: Language = language()) =
@ExtendWith(InstantExecutorExtension::class)
class LanguageViewModelTest {
- private val newLanguagesDao: NewLanguagesDao = mockk()
+ private val languageRoomDao: LanguageRoomDao = mockk()
private lateinit var languageViewModel: LanguageViewModel
private lateinit var languages: MutableStateFlow>
@@ -54,9 +54,9 @@ class LanguageViewModelTest {
fun init() {
clearAllMocks()
languages = MutableStateFlow(emptyList())
- every { newLanguagesDao.languages() } returns languages
+ every { languageRoomDao.languages() } returns languages
languageViewModel =
- LanguageViewModel(newLanguagesDao)
+ LanguageViewModel(languageRoomDao)
}
@Test
@@ -183,7 +183,7 @@ class LanguageViewModelTest {
assertThat(awaitItem()).isEqualTo(
SaveLanguagesAndFinish(
languages,
- newLanguagesDao,
+ languageRoomDao,
languageViewModel.viewModelScope
)
)
diff --git a/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinishTest.kt b/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinishTest.kt
index 1681780a8..3f7384216 100644
--- a/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinishTest.kt
+++ b/app/src/test/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinishTest.kt
@@ -27,13 +27,13 @@ import io.mockk.verify
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
-import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.zim_manager.Language
class SaveLanguagesAndFinishTest {
@Test
fun `invoke saves and finishes`() = runTest {
- val languageDao = mockk()
+ val languageDao = mockk()
val activity = mockk()
val lifeCycleScope = TestScope(testScheduler)
val onBackPressedDispatcher = mockk()
diff --git a/app/src/test/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModelTest.kt b/app/src/test/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModelTest.kt
index deb7cc3fd..a65b0230b 100644
--- a/app/src/test/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModelTest.kt
+++ b/app/src/test/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModelTest.kt
@@ -28,6 +28,7 @@ import app.cash.turbine.TurbineTestContext
import app.cash.turbine.test
import com.jraska.livedata.test
import io.mockk.clearAllMocks
+import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
@@ -53,8 +54,8 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk
-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.downloader.model.DownloadModel
@@ -103,7 +104,7 @@ import kotlin.time.toDuration
class ZimManageViewModelTest {
private val downloadRoomDao: DownloadRoomDao = mockk()
private val libkiwixBookOnDisk: LibkiwixBookOnDisk = mockk()
- private val newLanguagesDao: NewLanguagesDao = mockk()
+ private val languageRoomDao: LanguageRoomDao = mockk()
private val storageObserver: StorageObserver = mockk()
private val kiwixService: KiwixService = mockk()
private val application: Application = mockk()
@@ -129,6 +130,7 @@ class ZimManageViewModelTest {
private val networkStates = MutableStateFlow(NetworkState.NOT_CONNECTED)
private val booksOnDiskListItems = MutableStateFlow>(emptyList())
private val testDispatcher = StandardTestDispatcher()
+ private val onlineLibraryManager = mockk()
@AfterAll
fun teardown() {
@@ -150,7 +152,7 @@ class ZimManageViewModelTest {
any()
)
} returns booksOnFileSystem
- every { newLanguagesDao.languages() } returns languages
+ every { languageRoomDao.languages() } returns languages
every { fat32Checker.fileSystemStates } returns fileSystemStates
every { connectivityBroadcastReceiver.networkStates } returns networkStates
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
@@ -176,7 +178,7 @@ class ZimManageViewModelTest {
ZimManageViewModel(
downloadRoomDao,
libkiwixBookOnDisk,
- newLanguagesDao,
+ languageRoomDao,
storageObserver,
kiwixService,
application,
@@ -186,7 +188,8 @@ class ZimManageViewModelTest {
defaultLanguageProvider,
dataSource,
connectivityManager,
- sharedPreferenceUtil
+ sharedPreferenceUtil,
+ onlineLibraryManager
).apply {
setIsUnitTestCase()
setAlertDialogShower(alertDialogShower)
@@ -279,7 +282,7 @@ class ZimManageViewModelTest {
expectedLanguage
)
advanceUntilIdle()
- verify { newLanguagesDao.insert(listOf(expectedLanguage)) }
+ verify { languageRoomDao.insert(listOf(expectedLanguage)) }
}
@Test
@@ -298,7 +301,7 @@ class ZimManageViewModelTest {
),
language(isActive = true, occurencesOfLanguage = 1)
)
- verify { newLanguagesDao.insert(any()) }
+ verify { languageRoomDao.insert(any()) }
}
@Test
@@ -323,7 +326,7 @@ class ZimManageViewModelTest {
defaultLanguage
)
verify {
- newLanguagesDao.insert(
+ languageRoomDao.insert(
listOf(
defaultLanguage.copy(occurencesOfLanguage = 2),
Language(
@@ -362,7 +365,7 @@ class ZimManageViewModelTest {
)
advanceUntilIdle()
verify(timeout = MOCKK_TIMEOUT_FOR_VERIFICATION) {
- newLanguagesDao.insert(
+ languageRoomDao.insert(
listOf(
dbLanguage.copy(occurencesOfLanguage = 2),
Language(
@@ -386,6 +389,7 @@ class ZimManageViewModelTest {
every { application.getString(any()) } returns ""
every { application.getString(any(), any()) } returns ""
every { defaultLanguageProvider.provide() } returns defaultLanguage
+ coEvery { onlineLibraryManager.getOnlineBooksLanguage() } returns networkBooks.map { it.language }
viewModel.networkLibrary.emit(networkBooks)
advanceUntilIdle()
languages.value = dbBooks
diff --git a/core/detekt_baseline.xml b/core/detekt_baseline.xml
index d2e3edb2c..9d16a483a 100644
--- a/core/detekt_baseline.xml
+++ b/core/detekt_baseline.xml
@@ -12,7 +12,7 @@
LongParameterList:MainMenu.kt$MainMenu$( private val activity: Activity, zimFileReader: ZimFileReader?, menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, disableReadAloud: Boolean = false, disableTabs: Boolean = false, private val menuClickListener: MenuClickListener )
LongParameterList:MainMenu.kt$MainMenu.Factory$( menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, menuClickListener: MenuClickListener, disableReadAloud: Boolean, disableTabs: Boolean )
LongParameterList:PageTestHelpers.kt$( bookmarkTitle: String = "bookmarkTitle", isSelected: Boolean = false, id: Long = 2, zimId: String = "zimId", zimName: String = "zimName", zimFilePath: String = "zimFilePath", bookmarkUrl: String = "bookmarkUrl", favicon: String = "favicon" )
- LongParameterList:Repository.kt$Repository$( private val libkiwixBookOnDisk: LibkiwixBookOnDisk, private val libkiwixBookmarks: LibkiwixBookmarks, private val historyRoomDao: HistoryRoomDao, private val webViewHistoryRoomDao: WebViewHistoryRoomDao, private val notesRoomDao: NotesRoomDao, private val languageDao: NewLanguagesDao, private val recentSearchRoomDao: RecentSearchRoomDao, private val zimReaderContainer: ZimReaderContainer )
+ LongParameterList:Repository.kt$Repository$( private val libkiwixBookOnDisk: LibkiwixBookOnDisk, private val libkiwixBookmarks: LibkiwixBookmarks, private val historyRoomDao: HistoryRoomDao, private val webViewHistoryRoomDao: WebViewHistoryRoomDao, private val notesRoomDao: NotesRoomDao, private val languageRoomDao: LanguageRoomDao, private val recentSearchRoomDao: RecentSearchRoomDao, private val zimReaderContainer: ZimReaderContainer )
LongParameterList:ToolbarScrollingKiwixWebView.kt$ToolbarScrollingKiwixWebView$( context: Context, callback: WebViewCallback, attrs: AttributeSet, videoView: ViewGroup?, webViewClient: CoreWebViewClient, sharedPreferenceUtil: SharedPreferenceUtil )
MagicNumber:ArticleCount.kt$ArticleCount$3
MagicNumber:CompatFindActionModeCallback.kt$CompatFindActionModeCallback$100
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LanguageRoomDao.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LanguageRoomDao.kt
new file mode 100644
index 000000000..9f22ec821
--- /dev/null
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LanguageRoomDao.kt
@@ -0,0 +1,50 @@
+/*
+ * Kiwix Android
+ * Copyright (c) 2025 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.core.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import org.kiwix.kiwixmobile.core.dao.entities.LanguageRoomEntity
+import org.kiwix.kiwixmobile.core.zim_manager.Language
+
+@Dao
+abstract class LanguageRoomDao {
+ @Query("SELECT * FROM LanguageRoomEntity")
+ abstract fun languageAsEntity(): Flow>
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ abstract fun saveLanguages(languageRoomEntityList: List)
+
+ @Query("DELETE FROM LanguageRoomEntity")
+ abstract fun deleteAllLanguages()
+
+ fun languages(): Flow> =
+ languageAsEntity().map { it.map(LanguageRoomEntity::toLanguageModel) }
+
+ @Transaction
+ open fun insert(languages: List) {
+ deleteAllLanguages()
+ saveLanguages(languages.map(::LanguageRoomEntity))
+ }
+}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/LanguageRoomEntity.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/LanguageRoomEntity.kt
new file mode 100644
index 000000000..fb9fc33b6
--- /dev/null
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/LanguageRoomEntity.kt
@@ -0,0 +1,56 @@
+/*
+ * Kiwix Android
+ * Copyright (c) 2025 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.core.dao.entities
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import androidx.room.TypeConverter
+import androidx.room.TypeConverters
+import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
+import org.kiwix.kiwixmobile.core.zim_manager.Language
+import java.util.Locale
+
+@Entity
+data class LanguageRoomEntity(
+ @PrimaryKey(autoGenerate = true) var id: Long = 0,
+ @TypeConverters(StringToLocalRoomConverter::class)
+ var locale: Locale = Locale.ENGLISH,
+ var active: Boolean = false,
+ var occurencesOfLanguage: Int = 0
+) {
+ constructor(language: Language) : this(
+ 0,
+ language.languageCode.convertToLocal(),
+ language.active,
+ language.occurencesOfLanguage
+ )
+
+ fun toLanguageModel() =
+ Language(locale, active, occurencesOfLanguage, id)
+}
+
+class StringToLocalRoomConverter {
+ @TypeConverter
+ fun convertToDatabaseValue(entityProperty: Locale?): String =
+ entityProperty?.isO3Language ?: Locale.ENGLISH.isO3Language
+
+ @TypeConverter
+ fun convertToEntityProperty(databaseValue: String?): Locale =
+ databaseValue?.convertToLocal() ?: Locale.ENGLISH
+}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt
index adb930319..6865ce354 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt
@@ -28,14 +28,17 @@ import androidx.sqlite.db.SupportSQLiteDatabase
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDaoCoverts
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.NotesRoomDao
import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.WebViewHistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.BundleRoomConverter
import org.kiwix.kiwixmobile.core.dao.entities.DownloadRoomEntity
import org.kiwix.kiwixmobile.core.dao.entities.HistoryRoomEntity
+import org.kiwix.kiwixmobile.core.dao.entities.LanguageRoomEntity
import org.kiwix.kiwixmobile.core.dao.entities.NotesRoomEntity
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchRoomEntity
+import org.kiwix.kiwixmobile.core.dao.entities.StringToLocalRoomConverter
import org.kiwix.kiwixmobile.core.dao.entities.WebViewHistoryEntity
import org.kiwix.kiwixmobile.core.dao.entities.ZimSourceRoomConverter
@@ -46,15 +49,17 @@ import org.kiwix.kiwixmobile.core.dao.entities.ZimSourceRoomConverter
HistoryRoomEntity::class,
NotesRoomEntity::class,
DownloadRoomEntity::class,
- WebViewHistoryEntity::class
+ WebViewHistoryEntity::class,
+ LanguageRoomEntity::class
],
- version = 8,
+ version = 9,
exportSchema = false
)
@TypeConverters(
HistoryRoomDaoCoverts::class,
ZimSourceRoomConverter::class,
- BundleRoomConverter::class
+ BundleRoomConverter::class,
+ StringToLocalRoomConverter::class
)
abstract class KiwixRoomDatabase : RoomDatabase() {
abstract fun recentSearchRoomDao(): RecentSearchRoomDao
@@ -62,6 +67,7 @@ abstract class KiwixRoomDatabase : RoomDatabase() {
abstract fun notesRoomDao(): NotesRoomDao
abstract fun downloadRoomDao(): DownloadRoomDao
abstract fun webViewHistoryRoomDao(): WebViewHistoryRoomDao
+ abstract fun languageRoomDao(): LanguageRoomDao
companion object {
private var db: KiwixRoomDatabase? = null
@@ -78,7 +84,8 @@ abstract class KiwixRoomDatabase : RoomDatabase() {
MIGRATION_4_5,
MIGRATION_5_6,
MIGRATION_6_7,
- MIGRATION_7_8
+ MIGRATION_7_8,
+ MIGRATION_8_9
)
.build().also { db = it }
}
@@ -305,6 +312,23 @@ abstract class KiwixRoomDatabase : RoomDatabase() {
}
}
+ @Suppress("MagicNumber")
+ private val MIGRATION_8_9 =
+ object : Migration(8, 9) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `LanguageRoomEntity` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `locale` TEXT NOT NULL DEFAULT 'eng',
+ `active` INTEGER NOT NULL DEFAULT 0,
+ `occurencesOfLanguage` INTEGER NOT NULL DEFAULT 0
+ )
+ """.trimIndent()
+ )
+ }
+ }
+
fun destroyInstance() {
db = null
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/data/Repository.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/data/Repository.kt
index 63d069de7..21662400b 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/data/Repository.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/data/Repository.kt
@@ -24,9 +24,9 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
-import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
import org.kiwix.kiwixmobile.core.dao.NotesRoomDao
import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.WebViewHistoryRoomDao
@@ -56,7 +56,7 @@ class Repository @Inject internal constructor(
private val historyRoomDao: HistoryRoomDao,
private val webViewHistoryRoomDao: WebViewHistoryRoomDao,
private val notesRoomDao: NotesRoomDao,
- private val languageDao: NewLanguagesDao,
+ private val languageRoomDao: LanguageRoomDao,
private val recentSearchRoomDao: RecentSearchRoomDao,
private val zimReaderContainer: ZimReaderContainer
) : DataSource {
@@ -102,7 +102,7 @@ class Repository @Inject internal constructor(
@Suppress("InjectDispatcher")
override suspend fun saveLanguages(languages: List) =
withContext(Dispatchers.IO) {
- languageDao.insert(languages)
+ languageRoomDao.insert(languages)
}
@Suppress("InjectDispatcher")
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToRoomMigrator.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToRoomMigrator.kt
index 6b31f04b0..f6009f202 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToRoomMigrator.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToRoomMigrator.kt
@@ -23,6 +23,7 @@ import io.objectbox.BoxStore
import io.objectbox.kotlin.boxFor
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.dao.entities.HistoryEntity
+import org.kiwix.kiwixmobile.core.dao.entities.LanguageEntity
import org.kiwix.kiwixmobile.core.dao.entities.NotesEntity
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchEntity
import org.kiwix.kiwixmobile.core.data.KiwixRoomDatabase
@@ -49,6 +50,9 @@ class ObjectBoxToRoomMigrator {
if (!sharedPreferenceUtil.prefIsNotesMigrated) {
migrateNotes(boxStore.boxFor())
}
+ if (!sharedPreferenceUtil.prefLanguageListMigrated) {
+ migrateLanguages(boxStore.boxFor())
+ }
// TODO we will migrate here for other entities
}
@@ -87,4 +91,12 @@ class ObjectBoxToRoomMigrator {
}
sharedPreferenceUtil.putPrefNotesMigrated(true)
}
+
+ suspend fun migrateLanguages(box: Box) {
+ kiwixRoomDatabase.languageRoomDao()
+ .insert(
+ box.all.map { it.toLanguageModel() }
+ )
+ sharedPreferenceUtil.putPrefLanguageListMigrated(true)
+ }
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/di/components/CoreComponent.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/di/components/CoreComponent.kt
index 4dee3f60d..30e5e5cfe 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/di/components/CoreComponent.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/di/components/CoreComponent.kt
@@ -30,6 +30,7 @@ import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
+import org.kiwix.kiwixmobile.core.dao.LanguageRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
import org.kiwix.kiwixmobile.core.dao.NewBookDao
@@ -107,6 +108,7 @@ interface CoreComponent {
fun historyRoomDao(): HistoryRoomDao
fun webViewHistoryRoomDao(): WebViewHistoryRoomDao
fun noteRoomDao(): NotesRoomDao
+ fun languageRoomDao(): LanguageRoomDao
fun objectBoxToRoomMigrator(): ObjectBoxToRoomMigrator
fun context(): Context
fun downloader(): Downloader
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/DatabaseModule.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/DatabaseModule.kt
index 0a121bd96..e30a4f7d1 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/DatabaseModule.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/DatabaseModule.kt
@@ -100,4 +100,8 @@ open class DatabaseModule {
db.downloadRoomDao().also {
it.libkiwixBookOnDisk = libkiwixBookOnDisk
}
+
+ @Singleton
+ @Provides
+ fun provideLanguageRoomDao(db: KiwixRoomDatabase) = db.languageRoomDao()
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
index 5d3f503c3..b7d4a2db7 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
@@ -117,6 +117,9 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
val prefIsBookOnDiskMigrated: Boolean
get() = sharedPreferences.getBoolean(PREF_BOOK_ON_DISK_MIGRATED, false)
+ val prefLanguageListMigrated: Boolean
+ get() = sharedPreferences.getBoolean(PREF_LANGUAGE_LIST_MIGRATED, false)
+
val prefStorage: String
get() {
val storage = sharedPreferences.getString(PREF_STORAGE, null)
@@ -169,6 +172,9 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
fun putPrefBookOnDiskMigrated(isMigrated: Boolean) =
sharedPreferences.edit { putBoolean(PREF_BOOK_ON_DISK_MIGRATED, isMigrated) }
+ fun putPrefLanguageListMigrated(isMigrated: Boolean) =
+ sharedPreferences.edit { putBoolean(PREF_LANGUAGE_LIST_MIGRATED, isMigrated) }
+
fun putPrefLanguage(language: String) =
sharedPreferences.edit { putString(PREF_LANG, language) }
@@ -352,6 +358,7 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
const val PREF_NOTES_MIGRATED = "pref_notes_migrated"
const val PREF_APP_DIRECTORY_TO_PUBLIC_MIGRATED = "pref_app_directory_to_public_migrated"
const val PREF_BOOK_ON_DISK_MIGRATED = "pref_book_on_disk_migrated"
+ const val PREF_LANGUAGE_LIST_MIGRATED = "pref_language_list_migrated"
const val PREF_SHOW_COPY_MOVE_STORAGE_SELECTION_DIALOG = "pref_show_copy_move_storage_dialog"
private const val PREF_LATER_CLICKED_MILLIS = "pref_later_clicked_millis"
const val PREF_LAST_DONATION_POPUP_SHOWN_IN_MILLISECONDS =