diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt index 4f6a440cc..6acee4c88 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt @@ -24,6 +24,7 @@ import org.kiwix.kiwixmobile.core.di.ActivityScope import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem +import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk import javax.inject.Inject private const val TAG = "MainPresenter" @@ -33,6 +34,7 @@ class MainRepositoryActions @Inject constructor(private val dataSource: DataSour private var saveHistoryDisposable: Disposable? = null private var saveBookmarkDisposable: Disposable? = null private var saveNoteDisposable: Disposable? = null + private var saveBookDisposable: Disposable? = null private var deleteNoteDisposable: Disposable? = null fun saveHistory(history: HistoryItem) { @@ -61,10 +63,16 @@ class MainRepositoryActions @Inject constructor(private val dataSource: DataSour .subscribe({}, { e -> Log.e(TAG, "Unable to delete note", e) }) } + fun saveBook(book: BookOnDisk) { + saveBookDisposable = dataSource.saveBook(book) + .subscribe({}, { e -> Log.e(TAG, "Unable to save book", e) }) + } + fun dispose() { saveHistoryDisposable?.dispose() saveBookmarkDisposable?.dispose() saveNoteDisposable?.dispose() deleteNoteDisposable?.dispose() + saveBookDisposable?.dispose() } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt index 4b6366ae9..5a85bf35c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt @@ -53,7 +53,7 @@ private const val TAG = "ZimFileReader" class ZimFileReader constructor( val zimFile: File?, - private val assetFileDescriptor: AssetFileDescriptor? = null, + val assetFileDescriptor: AssetFileDescriptor? = null, private val jniKiwixReader: Archive, private val nightModeConfig: NightModeConfig, private val searcher: SuggestionSearcher = SuggestionSearcher(jniKiwixReader) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt index 67642e208..942ba5a10 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt @@ -29,6 +29,7 @@ import android.provider.DocumentsContract import android.util.Log import android.webkit.URLUtil import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.documentfile.provider.DocumentFile import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -402,4 +403,8 @@ object FileUtils { null } } + + @JvmStatic + fun getDemoFilePathForCustomApp(context: Context) = + "${ContextCompat.getExternalFilesDirs(context, null)[0]}/demo.zim" } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/KiwixServer.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/KiwixServer.kt index b2071029b..5d2fef13e 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/KiwixServer.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/KiwixServer.kt @@ -18,7 +18,10 @@ package org.kiwix.kiwixmobile.core.webserver +import android.content.Context import android.util.Log +import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer +import org.kiwix.kiwixmobile.core.utils.files.FileUtils.getDemoFilePathForCustomApp import org.kiwix.libkiwix.Book import org.kiwix.libkiwix.JNIKiwixException import org.kiwix.libkiwix.Library @@ -36,13 +39,32 @@ class KiwixServer @Inject constructor( private val jniKiwixServer: Server ) { - class Factory @Inject constructor() { + class Factory @Inject constructor( + private val context: Context, + private val zimReaderContainer: ZimReaderContainer + ) { + @Suppress("NestedBlockDepth") fun createKiwixServer(selectedBooksPath: ArrayList): KiwixServer { val kiwixLibrary = Library() selectedBooksPath.forEach { path -> try { val book = Book().apply { - update(Archive(path)) + // Determine whether to create an Archive from an asset or a file path + val archive = if (path == getDemoFilePathForCustomApp(context)) { + // For custom apps using a demo file, create an Archive with FileDescriptor + val assetFileDescriptor = zimReaderContainer.zimFileReader?.assetFileDescriptor + val startOffset = assetFileDescriptor?.startOffset ?: 0L + val size = assetFileDescriptor?.length ?: 0L + Archive( + assetFileDescriptor?.parcelFileDescriptor?.dup()?.fileDescriptor, + startOffset, + size + ) + } else { + // For regular files, create an Archive from the file path + Archive(path) + } + update(archive) } kiwixLibrary.addBook(book) } catch (e: JNIKiwixException) { diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/ZimHostFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/ZimHostFragment.kt index c3bdaf0f3..feadfbda9 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/ZimHostFragment.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/webserver/ZimHostFragment.kt @@ -53,6 +53,7 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.requestNotificat import org.kiwix.kiwixmobile.core.extensions.toast import org.kiwix.kiwixmobile.core.navigateToAppSettings import org.kiwix.kiwixmobile.core.reader.ZimFileReader +import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer import org.kiwix.kiwixmobile.core.utils.ConnectivityReporter import org.kiwix.kiwixmobile.core.utils.REQUEST_POST_NOTIFICATION_PERMISSION import org.kiwix.kiwixmobile.core.utils.ServerUtils @@ -60,15 +61,15 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog.StartServer +import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService +import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService.Companion.ACTION_CHECK_IP_ADDRESS +import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService.Companion.ACTION_START_SERVER +import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService.Companion.ACTION_STOP_SERVER import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BookOnDiskDelegate import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk -import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService -import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService.Companion.ACTION_CHECK_IP_ADDRESS -import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService.Companion.ACTION_START_SERVER -import org.kiwix.kiwixmobile.core.webserver.wifi_hotspot.HotspotService.Companion.ACTION_STOP_SERVER import javax.inject.Inject class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View { @@ -87,6 +88,9 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View { @Inject lateinit var zimReaderFactory: ZimFileReader.Factory + @Inject + lateinit var zimReaderContainer: ZimReaderContainer + private lateinit var booksAdapter: BooksOnDiskAdapter private lateinit var bookDelegate: BookOnDiskDelegate.BookDelegate private var hotspotService: HotspotService? = null @@ -485,18 +489,13 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View { val updatedBooksList: MutableList = arrayListOf() books.forEach { if (it is BookOnDisk) { - zimReaderFactory.create(it.file)?.let { zimFileReader -> + zimReaderContainer.zimFileReader?.let { zimFileReader -> val booksOnDiskListItem = - zimFileReader.zimFile?.let { file -> - (BookOnDisk(file, zimFileReader) as BooksOnDiskListItem) - .apply { - isSelected = true - } - } - if (booksOnDiskListItem != null) { - updatedBooksList.add(booksOnDiskListItem) - } - zimFileReader.dispose() + (BookOnDisk(it.file, zimFileReader) as BooksOnDiskListItem) + .apply { + isSelected = true + } + updatedBooksList.add(booksOnDiskListItem) } } else { updatedBooksList.add(it) diff --git a/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt b/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt index 0dcad4b6b..20672ff4e 100644 --- a/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt +++ b/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt @@ -32,6 +32,7 @@ import org.kiwix.kiwixmobile.core.base.BaseActivity import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.observeNavigationResult import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle +import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.main.CoreReaderFragment import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING import org.kiwix.kiwixmobile.core.main.MainMenu @@ -39,11 +40,14 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen import org.kiwix.kiwixmobile.core.utils.LanguageUtils import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower +import org.kiwix.kiwixmobile.core.utils.files.FileUtils.getDemoFilePathForCustomApp import org.kiwix.kiwixmobile.core.utils.titleToUrl import org.kiwix.kiwixmobile.core.utils.urlSuffixToParsableUrl +import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk import org.kiwix.kiwixmobile.custom.BuildConfig import org.kiwix.kiwixmobile.custom.R import org.kiwix.kiwixmobile.custom.customActivityComponent +import java.io.File import java.util.Locale import javax.inject.Inject @@ -149,6 +153,15 @@ class CustomReaderFragment : CoreReaderFragment() { } else { openZimFile(it.file, true) } + // Save book in the database to display it in `ZimHostFragment`. + zimReaderContainer?.zimFileReader?.let { zimFileReader -> + // Check if the file is not null. If the file is null, + // it means we have created zimFileReader with a fileDescriptor, + // so we create a demo file to save it in the database for display on the `ZimHostFragment`. + val file = it.file ?: createDemoFile() + val bookOnDisk = BookOnDisk(file, zimFileReader) + repositoryActions?.saveBook(bookOnDisk) + } } is ValidationState.HasBothFiles -> { it.zimFile.delete() @@ -163,6 +176,11 @@ class CustomReaderFragment : CoreReaderFragment() { ) } + private fun createDemoFile() = + File(getDemoFilePathForCustomApp(requireActivity())).also { + if (!it.isFileExist()) it.createNewFile() + } + @Suppress("DEPRECATION") override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater)