diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/OnlineLibraryManager.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt similarity index 91% rename from core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/OnlineLibraryManager.kt rename to app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt index d73fb479e..241d494a8 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/OnlineLibraryManager.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/OnlineLibraryManager.kt @@ -16,13 +16,13 @@ * */ -package org.kiwix.kiwixmobile.core.zim_manager +package org.kiwix.kiwixmobile.zimManager import org.kiwix.kiwixmobile.core.entity.LibkiwixBook import org.kiwix.libkiwix.Library import org.kiwix.libkiwix.Manager -class OnlineLibraryManager(val library: Library, val manager: Manager) { +class OnlineLibraryManager(private val library: Library, private val manager: Manager) { suspend fun parseOPDSStream(content: String?, urlHost: String): Boolean = runCatching { manager.readOpds(content, urlHost) 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 6f131e129..aa3794222 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt @@ -96,7 +96,6 @@ import org.kiwix.kiwixmobile.core.zim_manager.ConnectivityBroadcastReceiver import org.kiwix.kiwixmobile.core.zim_manager.Language import org.kiwix.kiwixmobile.core.zim_manager.NetworkState import org.kiwix.kiwixmobile.core.zim_manager.NetworkState.CONNECTED -import org.kiwix.kiwixmobile.core.zim_manager.OnlineLibraryManager import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode.MULTI diff --git a/core/detekt_baseline.xml b/core/detekt_baseline.xml index 93e357e6b..2b70850fb 100644 --- a/core/detekt_baseline.xml +++ b/core/detekt_baseline.xml @@ -50,7 +50,6 @@ PackageNaming:TagsView.kt$package org.kiwix.kiwixmobile.core.zim_manager PackageNaming:ConnectivityBroadcastReceiver.kt$package org.kiwix.kiwixmobile.core.zim_manager PackageNaming:NetworkState.kt$package org.kiwix.kiwixmobile.core.zim_manager - PackageNaming:OnlineLibraryManager.kt$package org.kiwix.kiwixmobile.core.zim_manager ReturnCount:FileUtils.kt$FileUtils$@JvmStatic fun getAllZimParts(book: Book): List<File> ReturnCount:FileUtils.kt$FileUtils$@JvmStatic suspend fun getLocalFilePathByUri( context: Context, uri: Uri ): String? ReturnCount:FileUtils.kt$FileUtils$@JvmStatic suspend fun hasPart(file: File): Boolean diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookOnDisk.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookOnDisk.kt new file mode 100644 index 000000000..8a5f7b90a --- /dev/null +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookOnDisk.kt @@ -0,0 +1,239 @@ +/* + * 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 android.os.Build +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks.Companion.TAG +import org.kiwix.kiwixmobile.core.di.modules.LOCAL_BOOKS_LIBRARY +import org.kiwix.kiwixmobile.core.di.modules.LOCAL_BOOKS_MANAGER +import org.kiwix.kiwixmobile.core.entity.LibkiwixBook +import org.kiwix.kiwixmobile.core.extensions.isFileExist +import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil +import org.kiwix.kiwixmobile.core.utils.files.Log +import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk +import org.kiwix.libkiwix.Book +import org.kiwix.libkiwix.Library +import org.kiwix.libkiwix.Manager +import java.io.File +import javax.inject.Inject +import javax.inject.Named + +class LibkiwixBookOnDisk @Inject constructor( + @Named(LOCAL_BOOKS_LIBRARY) private val library: Library, + @Named(LOCAL_BOOKS_MANAGER) private val manager: Manager, + private val sharedPreferenceUtil: SharedPreferenceUtil +) { + private var libraryBooksList: List = arrayListOf() + private var localBooksList: List = arrayListOf() + + /** + * Request new data from Libkiwix when changes occur inside it; otherwise, + * return the previous data to avoid unnecessary data load on Libkiwix. + */ + private var booksChanged: Boolean = false + private val localBookFolderPath: String by lazy { + if (Build.DEVICE.contains("generic")) { + // Workaround for emulators: Emulators have limited memory and + // restrictions on creating folders, so we will use the default + // path for saving the bookmark file. + sharedPreferenceUtil.context.filesDir.path + } else { + "${sharedPreferenceUtil.defaultStorage()}/ZIMFiles/" + } + } + + private val libraryFile: File by lazy { + File("$localBookFolderPath/library.xml") + } + + init { + // Check if ZIM files folder exist if not then create the folder first. + if (runBlocking { !File(localBookFolderPath).isFileExist() }) File(localBookFolderPath).mkdir() + // Check if library file exist if not then create the file to save the library with book information. + if (runBlocking { !libraryFile.isFileExist() }) libraryFile.createNewFile() + // set up manager to read the library from this file + manager.readFile(libraryFile.canonicalPath) + } + + @Suppress("InjectDispatcher") + private val localBooksFlow: MutableStateFlow> by lazy { + MutableStateFlow>(emptyList()).also { flow -> + CoroutineScope(Dispatchers.IO).launch { + runCatching { + flow.emit(getBooksList()) + }.onFailure { it.printStackTrace() } + } + } + } + + private suspend fun getBooksList(dispatcher: CoroutineDispatcher = Dispatchers.IO): List = + withContext(dispatcher) { + if (!booksChanged && localBooksList.isNotEmpty()) { + // No changes, return the cached data + return@withContext localBooksList.distinctBy(LibkiwixBook::path) + } + // Retrieve the list of books from the library. + val booksIds = library.booksIds.toList() + + // Create a list to store LibkiwixBook objects. + localBooksList = + booksIds.mapNotNull { bookId -> + val book = library.getBookById(bookId) + return@mapNotNull LibkiwixBook(book).also { + // set the books change to false to avoid reloading the data from libkiwix + booksChanged = false + } + } + + return@withContext localBooksList.distinctBy(LibkiwixBook::path) + } + + @OptIn(ExperimentalCoroutinesApi::class) + fun books(dispatcher: CoroutineDispatcher = Dispatchers.IO) = + localBooksFlow + .mapLatest { booksList -> + removeBooksThatAreInTrashFolder(booksList) + removeBooksThatDoNotExist(booksList.toMutableList()) + booksList.mapNotNull { book -> + try { + if (book.zimReaderSource.exists() && + !isInTrashFolder(book.zimReaderSource.toDatabase()) + ) { + book + } else { + null + } + } catch (_: Exception) { + null + } + } + } + .map { it.map(::BookOnDisk) } + .flowOn(dispatcher) + + suspend fun getBooks() = getBooksList().map(::BookOnDisk) + + suspend fun insert(libkiwixBooks: List) { + withContext(Dispatchers.IO) { + val existingBookIds = library.booksIds.toSet() + val existingBookPaths = existingBookIds + .mapNotNull { id -> library.getBookById(id)?.path } + .toSet() + + val newBooks = libkiwixBooks.filterNot { book -> + book.id in existingBookIds || book.path in existingBookPaths + } + newBooks.forEach { book -> + runCatching { + library.addBook(book) + Log.d(TAG, "Added book to library: ${book.title}, ID=${book.id}") + }.onFailure { + Log.e(TAG, "Failed to add book: ${book.title} - ${it.message}") + } + } + + if (newBooks.isNotEmpty()) { + writeBookMarksAndSaveLibraryToFile() + updateLocalBooksFlow() + } + } + } + + private fun addBookToLibraryIfNotExist(libKiwixBook: Book?) { + libKiwixBook?.let { book -> + if (!isBookAlreadyExistInLibrary(book.id)) { + library.addBook(libKiwixBook).also { + // now library has changed so update our library list. + libraryBooksList = library.booksIds.toList() + Log.e( + TAG, + "Added Book to Library:\n" + + "ZIM File Path: ${book.path}\n" + + "Book ID: ${book.id}\n" + + "Book Title: ${book.title}" + ) + } + } + } + } + + private fun isBookAlreadyExistInLibrary(bookId: String): Boolean { + if (libraryBooksList.isEmpty()) { + // store booksIds in a list to avoid multiple data call on libkiwix + libraryBooksList = library.booksIds.toList() + } + return libraryBooksList.any { it == bookId } + } + + private suspend fun removeBooksThatDoNotExist(books: MutableList) { + delete(books.filterNot { it.zimReaderSource.exists() }) + } + + // Remove the existing books from database which are showing on the library screen. + private suspend fun removeBooksThatAreInTrashFolder(books: List) { + delete(books.filter { isInTrashFolder(it.zimReaderSource.toDatabase()) }) + } + + // Check if any existing ZIM file showing on the library screen which is inside the trash folder. + private suspend fun isInTrashFolder(filePath: String) = + Regex("/\\.Trash/").containsMatchIn(filePath) + + private suspend fun delete(books: List) { + runCatching { + books.forEach { + library.removeBookById(it.id) + } + }.onFailure { it.printStackTrace() } + writeBookMarksAndSaveLibraryToFile() + // TODO test when getting books it will not goes to circular dependencies mode. + updateLocalBooksFlow() + } + + fun delete(bookId: String) { + runCatching { + library.removeBookById(bookId) + }.onFailure { it.printStackTrace() } + } + + /** + * Asynchronously writes the library data to their respective file in a background thread + * to prevent potential data loss and ensures that the library holds the updated ZIM file data. + */ + private suspend fun writeBookMarksAndSaveLibraryToFile() { + // Save the library, which contains ZIM file data. + library.writeToFile(libraryFile.canonicalPath) + // set the bookmark change to true so that libkiwix will return the new data. + booksChanged = true + } + + private suspend fun updateLocalBooksFlow() { + localBooksFlow.emit(getBooksList()) + } +} diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookmarks.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookmarks.kt index dfcfff529..73d3c4b3d 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookmarks.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/LibkiwixBookmarks.kt @@ -33,6 +33,8 @@ import kotlinx.coroutines.withContext import org.kiwix.kiwixmobile.core.CoreApp import org.kiwix.kiwixmobile.core.DarkModeConfig import org.kiwix.kiwixmobile.core.R +import org.kiwix.kiwixmobile.core.di.modules.BOOKMARK_LIBRARY +import org.kiwix.kiwixmobile.core.di.modules.BOOKMARK_MANAGER import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isCustomApp import org.kiwix.kiwixmobile.core.extensions.deleteFile import org.kiwix.kiwixmobile.core.extensions.getFavicon @@ -53,11 +55,12 @@ import org.kiwix.libzim.Archive import org.kiwix.libzim.SuggestionSearcher import java.io.File import javax.inject.Inject +import javax.inject.Named class LibkiwixBookmarks @Inject constructor( - val library: Library, - manager: Manager, - val sharedPreferenceUtil: SharedPreferenceUtil, + @Named(BOOKMARK_LIBRARY) private val library: Library, + @Named(BOOKMARK_MANAGER) private val manager: Manager, + private val sharedPreferenceUtil: SharedPreferenceUtil, private val bookDao: NewBookDao, private val zimReaderContainer: ZimReaderContainer? ) : PageDao { @@ -69,16 +72,14 @@ class LibkiwixBookmarks @Inject constructor( private var bookmarkList: List = arrayListOf() private var libraryBooksList: List = arrayListOf() - @Suppress("InjectDispatcher", "TooGenericExceptionCaught") + @Suppress("InjectDispatcher") private val bookmarkListFlow: MutableStateFlow> by lazy { MutableStateFlow>(emptyList()).also { flow -> CoroutineScope(Dispatchers.IO).launch { - try { + runCatching { val bookmarks = getBookmarksList() flow.emit(bookmarks) - } catch (e: Exception) { - e.printStackTrace() - } + }.onFailure { it.printStackTrace() } } } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToLibkiwixMigrator.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToLibkiwixMigrator.kt index c99886a0d..f2aab474a 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToLibkiwixMigrator.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/data/remote/ObjectBoxToLibkiwixMigrator.kt @@ -24,7 +24,9 @@ import io.objectbox.kotlin.boxFor import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.kiwix.kiwixmobile.core.CoreApp +import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks +import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity import org.kiwix.kiwixmobile.core.dao.entities.BookmarkEntity import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil @@ -43,14 +45,44 @@ class ObjectBoxToLibkiwixMigrator { @Inject lateinit var libkiwixBookmarks: LibkiwixBookmarks + + @Inject + lateinit var libkiwixBookOnDisk: LibkiwixBookOnDisk private val migrationMutex = Mutex() - suspend fun migrateBookmarksToLibkiwix() { + suspend fun migrateObjectBoxDataToLibkiwix() { CoreApp.coreComponent.inject(this) - migrateBookMarks(boxStore.boxFor()) + if (!sharedPreferenceUtil.prefIsBookmarksMigrated) { + migrateBookMarks(boxStore.boxFor()) + } + if (!sharedPreferenceUtil.prefIsBookOnDiskMigrated) { + migrateLocalBooks(boxStore.boxFor()) + } // TODO we will migrate here for other entities } + suspend fun migrateLocalBooks(box: Box) { + val bookOnDiskList = box.all + migrationMutex.withLock { + runCatching { + val libkiwixBooks = bookOnDiskList.map { + val archive = Archive(it.file.path) + Book().apply { + update(archive) + } + } + libkiwixBookOnDisk.insert(libkiwixBooks) + }.onFailure { + Log.e( + "MIGRATING_BOOK_ON_DISK", + "there is an error while migrating the bookOnDisk \n" + + "Original exception is = $it" + ) + } + } + sharedPreferenceUtil.putPrefBookOnDiskMigrated(true) + } + suspend fun migrateBookMarks(box: Box) { val bookMarksList = box.all // run migration with mutex to do the migration one by one. 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 cb941d13e..83648865c 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.dao.DownloadRoomDao import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks +import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao @@ -99,6 +100,7 @@ interface CoreComponent { fun connectivityManager(): ConnectivityManager fun objectBoxToLibkiwixMigrator(): ObjectBoxToLibkiwixMigrator fun libkiwixBookmarks(): LibkiwixBookmarks + fun libkiwixBooks(): LibkiwixBookOnDisk fun recentSearchRoomDao(): RecentSearchRoomDao fun historyRoomDao(): HistoryRoomDao fun webViewHistoryRoomDao(): WebViewHistoryRoomDao diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/JNIModule.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/JNIModule.kt index dda7e0329..f1f788aa3 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/JNIModule.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/JNIModule.kt @@ -21,12 +21,14 @@ import android.content.Context import dagger.Module import dagger.Provides import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks +import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.libkiwix.JNIKiwix import org.kiwix.libkiwix.Library import org.kiwix.libkiwix.Manager +import javax.inject.Named import javax.inject.Singleton @Module @@ -36,20 +38,47 @@ class JNIModule { @Provides @Singleton - fun provideLibrary(): Library = Library() + @Named(BOOKMARK_LIBRARY) + fun provideBookmarkLibrary(): Library = Library() @Provides @Singleton - fun providesManager(library: Library): Manager = Manager(library) + @Named(BOOKMARK_MANAGER) + fun providesBookmarkManager(@Named(BOOKMARK_LIBRARY) library: Library): Manager = + Manager(library) @Provides @Singleton fun providesLibkiwixBookmarks( - library: Library, - manager: Manager, + @Named(BOOKMARK_LIBRARY) library: Library, + @Named(BOOKMARK_MANAGER) manager: Manager, sharedPreferenceUtil: SharedPreferenceUtil, bookDao: NewBookDao, zimReaderContainer: ZimReaderContainer ): LibkiwixBookmarks = LibkiwixBookmarks(library, manager, sharedPreferenceUtil, bookDao, zimReaderContainer) + + @Provides + @Singleton + @Named(LOCAL_BOOKS_LIBRARY) + fun provideLocalBooksLibrary(): Library = Library() + + @Provides + @Singleton + @Named(LOCAL_BOOKS_MANAGER) + fun providesLocalBooksManager(@Named(LOCAL_BOOKS_LIBRARY) library: Library): Manager = + Manager(library) + + @Provides + @Singleton + fun providesLibkiwixBooks( + @Named(LOCAL_BOOKS_LIBRARY) library: Library, + @Named(LOCAL_BOOKS_MANAGER) manager: Manager, + sharedPreferenceUtil: SharedPreferenceUtil, + ): LibkiwixBookOnDisk = LibkiwixBookOnDisk(library, manager, sharedPreferenceUtil) } + +const val BOOKMARK_LIBRARY = "bookmarkLibrary" +const val BOOKMARK_MANAGER = "bookmarkManager" +const val LOCAL_BOOKS_LIBRARY = "localBooksLibrary" +const val LOCAL_BOOKS_MANAGER = "localBooksManager" diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/entity/LibkiwixBook.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/entity/LibkiwixBook.kt index bb77e6505..c1d359a3f 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/entity/LibkiwixBook.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/entity/LibkiwixBook.kt @@ -19,6 +19,7 @@ package org.kiwix.kiwixmobile.core.entity import org.kiwix.kiwixmobile.core.extensions.getFavicon +import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.libkiwix.Book import java.io.File @@ -43,6 +44,7 @@ data class LibkiwixBook( private var _bookName: String? = null, private var _favicon: String = "", private var _tags: String? = null, + private var _path: String? = "", var searchMatches: Int = 0, var file: File? = null ) { @@ -130,6 +132,15 @@ data class LibkiwixBook( _tags = tags } + var path: String? + get() = _path ?: nativeBook?.path + set(path) { + _path = path + } + + val zimReaderSource: ZimReaderSource + get() = ZimReaderSource(File(path.orEmpty())) + // Two books are equal if their ids match override fun equals(other: Any?): Boolean { if (other is LibkiwixBook) { diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt index 40e372209..2a5b96f9d 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt @@ -121,9 +121,8 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { super.onCreate(savedInstanceState) if (!BuildConfig.DEBUG) { val appContext = applicationContext - Thread.setDefaultUncaughtExceptionHandler { - paramThread: Thread?, - paramThrowable: Throwable? -> + Thread.setDefaultUncaughtExceptionHandler { paramThread: Thread?, + paramThrowable: Throwable? -> val intent = Intent(appContext, ErrorActivity::class.java) val extras = Bundle() extras.putSerializable(ErrorActivity.EXCEPTION_KEY, paramThrowable) @@ -137,11 +136,9 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { } setMainActivityToCoreApp() - if (!sharedPreferenceUtil.prefIsBookmarksMigrated) { - // run the migration on background thread to avoid any UI related issues. - CoroutineScope(Dispatchers.IO).launch { - objectBoxToLibkiwixMigrator.migrateBookmarksToLibkiwix() - } + // run the migration on background thread to avoid any UI related issues. + CoroutineScope(Dispatchers.IO).launch { + objectBoxToLibkiwixMigrator.migrateObjectBoxDataToLibkiwix() } // run the migration on background thread to avoid any UI related issues. CoroutineScope(Dispatchers.IO).launch { 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 0386f0df2..5d3f503c3 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 @@ -114,6 +114,9 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) { val prefIsAppDirectoryMigrated: Boolean get() = sharedPreferences.getBoolean(PREF_APP_DIRECTORY_TO_PUBLIC_MIGRATED, false) + val prefIsBookOnDiskMigrated: Boolean + get() = sharedPreferences.getBoolean(PREF_BOOK_ON_DISK_MIGRATED, false) + val prefStorage: String get() { val storage = sharedPreferences.getString(PREF_STORAGE, null) @@ -163,6 +166,9 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) { fun putPrefAppDirectoryMigrated(isMigrated: Boolean) = sharedPreferences.edit { putBoolean(PREF_APP_DIRECTORY_TO_PUBLIC_MIGRATED, isMigrated) } + fun putPrefBookOnDiskMigrated(isMigrated: Boolean) = + sharedPreferences.edit { putBoolean(PREF_BOOK_ON_DISK_MIGRATED, isMigrated) } + fun putPrefLanguage(language: String) = sharedPreferences.edit { putString(PREF_LANG, language) } @@ -345,6 +351,7 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) { const val PREF_HISTORY_MIGRATED = "pref_history_migrated" 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_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 = diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/BooksOnDiskListItem.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/BooksOnDiskListItem.kt index c5d9bab1c..1a59e3fc2 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/BooksOnDiskListItem.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/BooksOnDiskListItem.kt @@ -54,6 +54,10 @@ sealed class BooksOnDiskListItem { book.language.convertToLocal() } + @Deprecated( + "Now we are using the libkiwix to store and retrieve the local " + + "books so this constructor is no longer used." + ) constructor(bookOnDiskEntity: BookOnDiskEntity) : this( databaseId = bookOnDiskEntity.id, file = bookOnDiskEntity.file, @@ -70,5 +74,10 @@ sealed class BooksOnDiskListItem { book = zimFileReader.toBook(), zimReaderSource = zimFileReader.zimReaderSource ) + + constructor(libkiwixBook: LibkiwixBook) : this( + book = libkiwixBook, + zimReaderSource = libkiwixBook.zimReaderSource + ) } }