From f041ee9cf087081e8cd02654a8ef1089275190a7 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Sat, 26 Jul 2025 21:18:38 +0530 Subject: [PATCH] Added a Table of Contents drawer to the reader screen and refactored all related code. * Fixed: BottomAppBar was not showing when hiding the tab switcher (tabs view). * Removed some unused code from the project. * Fixed: Some lint, and detekt issues in kiwix app. --- .../kiwixmobile/main/KiwixMainActivity.kt | 2 - .../main/KiwixMainActivityScreen.kt | 2 - .../destination/reader/KiwixReaderFragment.kt | 30 +--- .../org/kiwix/kiwixmobile/ui/KiwixNavGraph.kt | 50 ++++-- core/detekt_baseline.xml | 2 - .../kiwixmobile/core/main/CoreMainActivity.kt | 41 +---- .../kiwixmobile/core/main/DocumentParser.kt | 5 +- .../kiwixmobile/core/main/KiwixWebView.kt | 1 + .../core/main/reader/CoreReaderFragment.kt | 160 ++++++++---------- .../core/main/reader/ReaderScreen.kt | 87 +++++++++- .../core/main/reader/ReaderScreenState.kt | 14 +- .../kiwixmobile/core/search/SearchFragment.kt | 1 - .../core/ui/components/KiwixShowCaseView.kt | 1 + .../custom/main/CustomReaderFragment.kt | 2 - 14 files changed, 217 insertions(+), 181 deletions(-) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivity.kt b/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivity.kt index c9006293d..0ff53c4fd 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivity.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivity.kt @@ -23,7 +23,6 @@ import android.content.res.Configuration import android.os.Bundle import android.os.Handler import android.os.Looper -import android.util.Log import android.view.MenuItem import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity @@ -354,7 +353,6 @@ class KiwixMainActivity : CoreMainActivity() { } override fun showBottomAppBar() { - Log.e("SHOW_BOTTOM_APP", "showBottomAppBar: ") shouldShowBottomAppBar.update { true } } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivityScreen.kt b/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivityScreen.kt index 450ab144a..74dab8c63 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivityScreen.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/main/KiwixMainActivityScreen.kt @@ -18,7 +18,6 @@ package org.kiwix.kiwixmobile.main -import android.util.Log import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize @@ -67,7 +66,6 @@ fun KiwixMainActivityScreen( val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route val shouldShowBottomBar = currentRoute in topLevelDestinationsRoute && shouldShowBottomAppBar - Log.e("CURRENT_DESTINATION", "KiwixMainActivityScreen: $currentRoute and $shouldShowBottomAppBar") KiwixTheme { ModalNavigationDrawer( drawerState = leftDrawerState, diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt index 518144b35..185a495de 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt @@ -175,6 +175,7 @@ class KiwixReaderFragment : CoreReaderFragment() { */ override fun hideTabSwitcher(shouldCloseZimBook: Boolean) { activity?.setupDrawerToggle(true) + (requireActivity() as CoreMainActivity).showBottomAppBar() setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) if (webViewList.isEmpty()) { readerMenuState?.hideTabSwitcher() @@ -195,23 +196,6 @@ class KiwixReaderFragment : CoreReaderFragment() { } } - private fun setFragmentContainerBottomMarginToSizeOfNavBar() { - // val bottomNavigationView = - // requireActivity().findViewById(R.id.bottom_nav_view) - // bottomNavigationView?.let { - // setBottomMarginToNavHostContainer( - // bottomNavigationView.measuredHeight - // ) - // } - } - - // override fun onPause() { - // super.onPause() - // // ScrollingViewWithBottomNavigationBehavior changes the margin to the size of the nav bar, - // // this resets the margin to zero, before fragment navigation. - // setBottomMarginToNavHostContainer(ZERO) - // } - @Suppress("DEPRECATION") override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) { super.onCreateOptionsMenu(menu, menuInflater) @@ -311,28 +295,20 @@ class KiwixReaderFragment : CoreReaderFragment() { override fun closeFullScreen() { super.closeFullScreen() showNavBar() - setFragmentContainerBottomMarginToSizeOfNavBar() } private fun hideNavBar() { - // requireActivity().findViewById(R.id.bottom_nav_view).visibility = GONE - setBottomMarginToNavHostContainer(0) + (requireActivity() as CoreMainActivity).hideBottomAppBar() } private fun showNavBar() { // show the navBar if fullScreenMode is not active. if (!isInFullScreenMode()) { - // requireActivity().findViewById(R.id.bottom_nav_view).visibility = - // VISIBLE + (requireActivity() as CoreMainActivity).showBottomAppBar() } } override fun createNewTab() { newMainPageTab() } - - private fun setBottomMarginToNavHostContainer(margin: Int) { - // coreMainActivity.navHostContainer - // .setBottomMarginToFragmentContainerView(margin) - } } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/ui/KiwixNavGraph.kt b/app/src/main/java/org/kiwix/kiwixmobile/ui/KiwixNavGraph.kt index 15a1464fb..7dc4282ea 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/ui/KiwixNavGraph.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/ui/KiwixNavGraph.kt @@ -87,11 +87,26 @@ fun KiwixNavGraph( composable( route = KiwixDestination.Reader.route, arguments = listOf( - navArgument(ZIM_FILE_URI_KEY) { type = NavType.StringType; defaultValue = "" }, - navArgument(FIND_IN_PAGE_SEARCH_STRING) { type = NavType.StringType; defaultValue = "" }, - navArgument(PAGE_URL_KEY) { type = NavType.StringType; defaultValue = "" }, - navArgument(SHOULD_OPEN_IN_NEW_TAB) { type = NavType.BoolType; defaultValue = false }, - navArgument(SEARCH_ITEM_TITLE_KEY) { type = NavType.StringType; defaultValue = "" } + navArgument(ZIM_FILE_URI_KEY) { + type = NavType.StringType + defaultValue = "" + }, + navArgument(FIND_IN_PAGE_SEARCH_STRING) { + type = NavType.StringType + defaultValue = "" + }, + navArgument(PAGE_URL_KEY) { + type = NavType.StringType + defaultValue = "" + }, + navArgument(SHOULD_OPEN_IN_NEW_TAB) { + type = NavType.BoolType + defaultValue = false + }, + navArgument(SEARCH_ITEM_TITLE_KEY) { + type = NavType.StringType + defaultValue = "" + } ) ) { backStackEntry -> val zimFileUri = backStackEntry.arguments?.getString(ZIM_FILE_URI_KEY).orEmpty() @@ -116,7 +131,10 @@ fun KiwixNavGraph( composable( route = KiwixDestination.Library.route, arguments = listOf( - navArgument(ZIM_FILE_URI_KEY) { type = NavType.StringType; defaultValue = "" } + navArgument(ZIM_FILE_URI_KEY) { + type = NavType.StringType + defaultValue = "" + } ) ) { backStackEntry -> val zimFileUri = backStackEntry.arguments?.getString(ZIM_FILE_URI_KEY).orEmpty() @@ -177,9 +195,18 @@ fun KiwixNavGraph( composable( route = KiwixDestination.Search.route, arguments = listOf( - navArgument(NAV_ARG_SEARCH_STRING) { type = NavType.StringType; defaultValue = "" }, - navArgument(TAG_FROM_TAB_SWITCHER) { type = NavType.BoolType; defaultValue = false }, - navArgument(EXTRA_IS_WIDGET_VOICE) { type = NavType.BoolType; defaultValue = false } + navArgument(NAV_ARG_SEARCH_STRING) { + type = NavType.StringType + defaultValue = "" + }, + navArgument(TAG_FROM_TAB_SWITCHER) { + type = NavType.BoolType + defaultValue = false + }, + navArgument(EXTRA_IS_WIDGET_VOICE) { + type = NavType.BoolType + defaultValue = false + } ) ) { backStackEntry -> val searchString = backStackEntry.arguments?.getString(NAV_ARG_SEARCH_STRING).orEmpty() @@ -314,10 +341,11 @@ sealed class KiwixDestination(val route: String) { object LocalFileTransfer : KiwixDestination("$LOCAL_FILE_TRANSFER_FRAGMENT?uris={uris}") { fun createRoute(uris: String? = null): String { - return if (uris != null) + return if (uris != null) { "$LOCAL_FILE_TRANSFER_FRAGMENT?uris=${Uri.encode(uris)}" - else + } else { "$LOCAL_FILE_TRANSFER_FRAGMENT?uris=null" + } } } } diff --git a/core/detekt_baseline.xml b/core/detekt_baseline.xml index 08630fc8d..bda95d845 100644 --- a/core/detekt_baseline.xml +++ b/core/detekt_baseline.xml @@ -13,7 +13,6 @@ 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 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 MagicNumber:DownloadItem.kt$DownloadItem$1000L @@ -57,7 +56,6 @@ ReturnCount:FileUtils.kt$FileUtils$@Synchronized private fun deleteZimFileParts(path: String): Boolean ReturnCount:ImageUtils.kt$ImageUtils$private fun getBitmapFromView(width: Int, height: Int, viewToDrawFrom: View): Bitmap? ReturnCount:OnSwipeTouchListener.kt$OnSwipeTouchListener.GestureListener$override fun onFling( e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean - ReturnCount:ToolbarScrollingKiwixWebView.kt$ToolbarScrollingKiwixWebView$@SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent): Boolean TooGenericExceptionCaught:CompatFindActionModeCallback.kt$CompatFindActionModeCallback$exception: Exception TooGenericExceptionCaught:JNIInitialiser.kt$JNIInitialiser$e: Exception TooGenericExceptionCaught:LibkiwixBookmarks.kt$LibkiwixBookmarks$exception: Exception 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 67118731e..b7a2f802f 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 @@ -35,7 +35,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.core.net.toUri import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope -import androidx.navigation.NavDestination import androidx.navigation.NavDirections import androidx.navigation.NavHostController import androidx.navigation.NavOptions @@ -249,19 +248,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { } } - open fun configureActivityBasedOn(destination: NavDestination) { - // if (destination.id !in topLevelDestinations) { - // handleDrawerOnNavigation() - // } - // readerTableOfContentsDrawer.setLockMode( - // if (destination.id == readerFragmentResId) { - // LOCK_MODE_UNLOCKED - // } else { - // LOCK_MODE_LOCKED_CLOSED - // } - // ) - } - + @Suppress("UnusedParameter") private fun NavigationView.setLockMode(lockMode: Int) { // drawerContainerLayout.setDrawerLockMode(lockMode, this) } @@ -455,14 +442,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { navController.navigate(route, navOptions) } - fun navigate(fragmentId: Int, bundle: Bundle) { - navController.navigate(fragmentId, bundle) - } - - fun navigate(fragmentId: Int, bundle: Bundle, navOptions: NavOptions) { - navController.navigate(fragmentId, bundle, navOptions) - } - private fun openSettings() { handleDrawerOnNavigation() navigate(settingsFragmentRoute) @@ -492,15 +471,13 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { .setLaunchSingleTop(true) .setPopUpTo(readerFragmentRoute, inclusive = true) .build() - // navigate( - // readerFragmentRoute, - // bundleOf( - // PAGE_URL_KEY to pageUrl, - // ZIM_FILE_URI_KEY to zimFileUri, - // SHOULD_OPEN_IN_NEW_TAB to shouldOpenInNewTab - // ), - // navOptions - // ) + val readerRouteWithArguments = + "$readerFragmentRoute?$PAGE_URL_KEY=$pageUrl&$ZIM_FILE_URI_KEY=$zimFileUri" + + "&$SHOULD_OPEN_IN_NEW_TAB=$shouldOpenInNewTab" + navigate( + readerRouteWithArguments, + navOptions + ) } private fun openBookmarks() { @@ -523,7 +500,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { } fun findInPage(searchString: String) { - // navigate(readerFragmentRoute, bundleOf(FIND_IN_PAGE_SEARCH_STRING to searchString)) + navigate("$readerFragmentRoute?$FIND_IN_PAGE_SEARCH_STRING=$searchString") } private val bookRelatedDrawerGroup by lazy { diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/DocumentParser.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/DocumentParser.kt index 8cf1157d6..10cb67bd4 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/DocumentParser.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/DocumentParser.kt @@ -22,15 +22,14 @@ import android.os.Handler import android.os.Looper import android.webkit.JavascriptInterface import android.webkit.WebView +import org.kiwix.kiwixmobile.core.main.reader.DocumentSection import kotlin.collections.List -import org.kiwix.kiwixmobile.core.main.TableDrawerAdapter.DocumentSection - class DocumentParser(private var listener: DocumentParser.SectionsListener) { private var title: String = "" @Suppress("DoubleMutabilityForCollection") - private var sections = ArrayList() + private var sections = ArrayList() fun initInterface(webView: WebView) { webView.addJavascriptInterface(ParserCallback(), "DocumentParser") diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixWebView.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixWebView.kt index fedef55b5..38042d2d3 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixWebView.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixWebView.kt @@ -54,6 +54,7 @@ import javax.inject.Inject private const val INITIAL_SCALE = 100 @SuppressLint("ViewConstructor") +@Suppress("LongParameterList") open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor( context: Context, private val callback: WebViewCallback, diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/CoreReaderFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/CoreReaderFragment.kt index 39de6517a..2c1fa41f4 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/CoreReaderFragment.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/CoreReaderFragment.kt @@ -62,6 +62,7 @@ import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow +import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.platform.ComposeView import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -71,10 +72,8 @@ import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.bottomnavigation.BottomNavigationView -import com.google.android.material.navigation.NavigationView import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -124,9 +123,6 @@ import org.kiwix.kiwixmobile.core.main.KiwixTextToSpeech.OnSpeakingListener import org.kiwix.kiwixmobile.core.main.KiwixWebView import org.kiwix.kiwixmobile.core.main.MainRepositoryActions import org.kiwix.kiwixmobile.core.main.ServiceWorkerUninitialiser -import org.kiwix.kiwixmobile.core.main.TableDrawerAdapter -import org.kiwix.kiwixmobile.core.main.TableDrawerAdapter.DocumentSection -import org.kiwix.kiwixmobile.core.main.TableDrawerAdapter.TableClickListener import org.kiwix.kiwixmobile.core.main.UNINITIALISER_ADDRESS import org.kiwix.kiwixmobile.core.main.WebViewCallback import org.kiwix.kiwixmobile.core.main.WebViewProvider @@ -199,7 +195,6 @@ abstract class CoreReaderFragment : private val webUrlsFlow = MutableStateFlow("") var drawerLayout: DrawerLayout? = null - protected var tableDrawerRightContainer: NavigationView? = null @JvmField @Inject @@ -256,7 +251,7 @@ abstract class CoreReaderFragment : @Inject var unsupportedMimeTypeHandler: UnsupportedMimeTypeHandler? = null private var hideBackToTopTimer: CountDownTimer? = null - private val documentSections: MutableList? = ArrayList() + private val documentSections: SnapshotStateList? = mutableStateListOf() private var isBackToTopEnabled = false private var isOpenNewTabInBackground = false private var documentParserJs: String? = null @@ -269,8 +264,6 @@ abstract class CoreReaderFragment : private val tempWebViewListForUndo: MutableList = ArrayList() private var tempZimSourceForUndo: ZimReaderSource? = null private var isFirstRun = false - private var tableDrawerAdapter: TableDrawerAdapter? = null - private var tableDrawerRight: RecyclerView? = null private var bookmarkingJob: Job? = null private var isBookmarked = false private lateinit var serviceConnection: ServiceConnection @@ -279,6 +272,7 @@ abstract class CoreReaderFragment : private var isReadSelection = false private var isReadAloudServiceRunning = false private var libkiwixBook: Book? = null + private var shouldTableOfContentDrawer = mutableStateOf(false) protected var readerMenuState: ReaderMenuState? = null private var composeView: ComposeView? = null @@ -296,7 +290,7 @@ abstract class CoreReaderFragment : onExitFullscreenClick = { closeFullScreen() }, showTtsControls = false, onPauseTtsClick = { pauseTts() }, - pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty(), + pauseTtsButtonText = context?.getString(string.tts_pause).orEmpty(), onStopTtsClick = { stopTts() }, kiwixWebViewList = webViewList, bookmarkButtonItem = Triple( @@ -335,7 +329,10 @@ abstract class CoreReaderFragment : }, appName = "", donateButtonClick = {}, - laterButtonClick = {} + laterButtonClick = {}, + tableOfContentTitle = "", + tableContentHeaderClick = { tableOfContentHeaderClick() }, + tableOfContentSectionClick = { tableOfContentSectionClick(it) }, ) ) private var readerLifeCycleScope: CoroutineScope? = null @@ -362,12 +359,12 @@ abstract class CoreReaderFragment : * 2) Permission has been disabled on device */ requireActivity().toast( - R.string.ext_storage_permission_rationale_add_note, + string.ext_storage_permission_rationale_add_note, Toast.LENGTH_LONG ) } else { requireActivity().toast( - R.string.ext_storage_write_permission_denied_add_note, + string.ext_storage_write_permission_denied_add_note, Toast.LENGTH_LONG ) alertDialogShower?.show( @@ -447,7 +444,7 @@ abstract class CoreReaderFragment : readerScreenState.update { copy( bottomNavigationHeight = getBottomNavigationHeight(), - readerScreenTitle = context.getString(R.string.reader), + readerScreenTitle = context.getString(string.reader), darkModeViewPainter = darkModeViewPainter, fullScreenItem = fullScreenItem.first to getVideoView(), tocButtonItem = getTocButtonStateAndAction(), @@ -483,7 +480,9 @@ abstract class CoreReaderFragment : iconTint = navigationIconTint() ) }, - mainActivityBottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour + mainActivityBottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour, + documentSections = documentSections, + showTableOfContentDrawer = shouldTableOfContentDrawer, ) DialogHost(alertDialogShower as AlertDialogShower) } @@ -497,10 +496,7 @@ abstract class CoreReaderFragment : handleLocaleCheck() initHideBackToTopTimer() loadDrawerViews() - tableDrawerRight = - tableDrawerRightContainer?.getHeaderView(0)?.findViewById(R.id.right_drawer_list) addFileReader() - setTableDrawerInfo() activity?.let { compatCallback = CompatFindActionModeCallback(it) } @@ -567,7 +563,7 @@ abstract class CoreReaderFragment : private fun navigationIconContentDescription() = if (readerMenuState?.isInTabSwitcher == true) { - R.string.search_open_in_new_tab + string.search_open_in_new_tab } else { string.open_drawer } @@ -665,54 +661,36 @@ abstract class CoreReaderFragment : sections: List ) { if (isAdded) { - documentSections?.let { - it.addAll(sections) - tableDrawerAdapter?.setTitle(title) - tableDrawerAdapter?.setSections(it) - tableDrawerAdapter?.notifyDataSetChanged() - } + documentSections?.addAll(sections) + readerScreenState.update { copy(tableOfContentTitle = title) } } } override fun clearSections() { documentSections?.clear() - tableDrawerAdapter?.notifyDataSetChanged() } }) } - private fun setTableDrawerInfo() { - tableDrawerRight?.apply { - layoutManager = LinearLayoutManager(requireActivity()) - tableDrawerAdapter = setupTableDrawerAdapter() - adapter = tableDrawerAdapter - tableDrawerAdapter?.notifyDataSetChanged() - } - } - private fun addFileReader() { documentParserJs = requireActivity().readFile("js/documentParser.js") documentSections?.clear() } - private fun setupTableDrawerAdapter(): TableDrawerAdapter { - return TableDrawerAdapter(object : TableClickListener { - override fun onHeaderClick(view: View?) { - getCurrentWebView()?.scrollY = 0 - drawerLayout?.closeDrawer(GravityCompat.END) - } + private fun tableOfContentHeaderClick() { + getCurrentWebView()?.scrollY = 0 + shouldTableOfContentDrawer.update { false } + } - override fun onSectionClick(view: View?, position: Int) { - if (hasItemForPositionInDocumentSectionsList(position)) { // Bug Fix #3796 - loadUrlWithCurrentWebview( - "javascript:document.getElementById('" + - documentSections?.get(position)?.id?.replace("'", "\\'") + - "').scrollIntoView();" - ) - } - drawerLayout?.closeDrawers() - } - }) + private fun tableOfContentSectionClick(position: Int) { + if (hasItemForPositionInDocumentSectionsList(position)) { // Bug Fix #3796 + loadUrlWithCurrentWebview( + "javascript:document.getElementById('" + + documentSections?.get(position)?.id?.replace("'", "\\'") + + "').scrollIntoView();" + ) + } + shouldTableOfContentDrawer.update { false } } private fun hasItemForPositionInDocumentSectionsList(position: Int): Boolean { @@ -772,7 +750,6 @@ abstract class CoreReaderFragment : protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) { setUpDrawerToggle() (requireActivity() as CoreMainActivity).showBottomAppBar() - Log.e("SHOW_BOTTOM_APP", "hideTabSwitcher: ") setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) readerScreenState.update { copy( @@ -862,9 +839,9 @@ abstract class CoreReaderFragment : **/ val dialogFragment = NavigationHistoryDialog( if (isForwardHistory) { - R.string.forward_history + string.forward_history } else { - R.string.backward_history + string.backward_history }, navigationHistoryList, this @@ -885,7 +862,7 @@ abstract class CoreReaderFragment : repositoryActions?.clearWebViewPageHistory() } updateBottomToolbarArrowsAlpha() - toast(R.string.navigation_history_cleared) + toast(string.navigation_history_cleared) } @Suppress("MagicNumber") @@ -900,7 +877,7 @@ abstract class CoreReaderFragment : } protected fun openToc() { - drawerLayout?.openDrawer(GravityCompat.END) + shouldTableOfContentDrawer.update { true } } @Suppress("ReturnCount", "NestedBlockDepth") @@ -1029,7 +1006,7 @@ abstract class CoreReaderFragment : readerScreenState.update { copy( showTtsControls = false, - pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty() + pauseTtsButtonText = context?.getString(string.tts_pause).orEmpty() ) } setActionAndStartTTSService(ACTION_STOP_TTS) @@ -1048,14 +1025,14 @@ abstract class CoreReaderFragment : AudioManager.AUDIOFOCUS_LOSS -> { if (tts?.currentTTSTask?.paused == false) tts?.pauseOrResume() readerScreenState.update { - copy(pauseTtsButtonText = context?.getString(R.string.tts_resume).orEmpty()) + copy(pauseTtsButtonText = context?.getString(string.tts_resume).orEmpty()) } setActionAndStartTTSService(ACTION_PAUSE_OR_RESUME_TTS, true) } AudioManager.AUDIOFOCUS_GAIN -> { readerScreenState.update { - copy(pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty()) + copy(pauseTtsButtonText = context?.getString(string.tts_pause).orEmpty()) } setActionAndStartTTSService(ACTION_PAUSE_OR_RESUME_TTS, false) } @@ -1090,13 +1067,13 @@ abstract class CoreReaderFragment : if (it.paused) { tts?.pauseOrResume() readerScreenState.update { - copy(pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty()) + copy(pauseTtsButtonText = context?.getString(string.tts_pause).orEmpty()) } setActionAndStartTTSService(ACTION_PAUSE_OR_RESUME_TTS, false) } else { tts?.pauseOrResume() readerScreenState.update { - copy(pauseTtsButtonText = context?.getString(R.string.tts_resume).orEmpty()) + copy(pauseTtsButtonText = context?.getString(string.tts_resume).orEmpty()) } setActionAndStartTTSService(ACTION_PAUSE_OR_RESUME_TTS, true) } @@ -1135,8 +1112,6 @@ abstract class CoreReaderFragment : hideBackToTopTimer?.cancel() hideBackToTopTimer = null stopOngoingLoadingAndClearWebViewList() - tableDrawerRight?.adapter = null - tableDrawerAdapter = null tempWebViewListForUndo.clear() // create a base Activity class that class this. deleteCachedFiles(requireActivity()) @@ -1166,7 +1141,6 @@ abstract class CoreReaderFragment : compatCallback?.finish() compatCallback = null drawerLayout = null - tableDrawerRightContainer = null } private fun updateTableOfContents() { @@ -1281,8 +1255,8 @@ abstract class CoreReaderFragment : currentWebViewIndex-- } readerScreenState.value.snackBarHostState.snack( - requireActivity().getString(R.string.tab_closed), - actionLabel = requireActivity().getString(R.string.undo), + requireActivity().getString(string.tab_closed), + actionLabel = requireActivity().getString(string.undo), actionClick = { restoreDeletedTab(index) }, lifecycleScope = lifecycleScope, snackBarResult = { result -> @@ -1307,7 +1281,7 @@ abstract class CoreReaderFragment : readerScreenState.update { copy( shouldShowBottomAppBar = false, - readerScreenTitle = context?.getString(R.string.reader).orEmpty() + readerScreenTitle = context?.getString(string.reader).orEmpty() ) } hideProgressBar() @@ -1342,7 +1316,7 @@ abstract class CoreReaderFragment : tempWebViewForUndo?.let { webViewList.add(index, it) readerScreenState.value.snackBarHostState.snack( - context?.getString(R.string.tab_restored).orEmpty(), + context?.getString(string.tab_restored).orEmpty(), lifecycleScope = lifecycleScope ) setUpWithTextToSpeech(it) @@ -1421,7 +1395,7 @@ abstract class CoreReaderFragment : hideBackToTopButton() } readerScreenState.update { - copy(pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty()) + copy(pauseTtsButtonText = context?.getString(string.tts_pause).orEmpty()) } if (tts?.isInitialized == false) { isReadSelection = false @@ -1621,7 +1595,7 @@ abstract class CoreReaderFragment : exitBook() Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + zimReaderSource.toDatabase()) requireActivity().toast( - getString(R.string.error_file_not_found, zimReaderSource.toDatabase()), + getString(string.error_file_not_found, zimReaderSource.toDatabase()), Toast.LENGTH_LONG ) } @@ -1664,13 +1638,13 @@ abstract class CoreReaderFragment : } readerMenuState?.onFileOpened(urlIsValid()) setUpBookmarks(zimFileReader) - } ?: kotlin.run { + } ?: run { // If the ZIM file is not opened properly (especially for ZIM chunks), exit the book to // disable all controls for this ZIM file. This prevents potential crashes. // See issue #4161 for more details. exitBook() requireActivity().toast( - getString(R.string.error_file_invalid, zimReaderSource.toDatabase()), + getString(string.error_file_invalid, zimReaderSource.toDatabase()), Toast.LENGTH_LONG ) } @@ -1758,8 +1732,8 @@ abstract class CoreReaderFragment : } } else { readerScreenState.value.snackBarHostState.snack( - context?.getString(R.string.request_storage).orEmpty(), - context?.getString(R.string.menu_settings), + context?.getString(string.request_storage).orEmpty(), + context?.getString(string.menu_settings), snackbarDuration = SnackbarDuration.Long, actionClick = { val intent = Intent() @@ -1791,8 +1765,8 @@ abstract class CoreReaderFragment : webViewList.clear() openHomeScreen() readerScreenState.value.snackBarHostState.snack( - context?.getString(R.string.tabs_closed).orEmpty(), - context?.getString(R.string.undo), + context?.getString(string.tabs_closed).orEmpty(), + context?.getString(string.undo), actionClick = { restoreDeletedTabs() }, lifecycleScope = lifecycleScope, snackBarResult = { result -> @@ -1810,7 +1784,7 @@ abstract class CoreReaderFragment : if (tempWebViewListForUndo.isNotEmpty()) { webViewList.addAll(tempWebViewListForUndo) readerScreenState.value.snackBarHostState.snack( - context?.getString(R.string.tabs_restored).orEmpty(), + context?.getString(string.tabs_restored).orEmpty(), lifecycleScope = lifecycleScope ) reopenBook() @@ -1850,7 +1824,7 @@ abstract class CoreReaderFragment : if (isBookmarked) { repositoryActions?.deleteBookmark(libKiwixBook.id, articleUrl) readerScreenState.value.snackBarHostState.snack( - context?.getString(R.string.bookmark_removed).orEmpty(), + context?.getString(string.bookmark_removed).orEmpty(), lifecycleScope = lifecycleScope ) } else { @@ -1859,22 +1833,22 @@ abstract class CoreReaderFragment : LibkiwixBookmarkItem(it, articleUrl, zimFileReader, libKiwixBook) ) readerScreenState.value.snackBarHostState.snack( - context?.getString(R.string.bookmark_added).orEmpty(), + context?.getString(string.bookmark_added).orEmpty(), lifecycleScope = lifecycleScope, - actionLabel = context?.getString(R.string.open), + actionLabel = context?.getString(string.open), actionClick = { goToBookmarks() } ) } } } - } ?: kotlin.run { - requireActivity().toast(R.string.unable_to_add_to_bookmarks, Toast.LENGTH_SHORT) + } ?: run { + requireActivity().toast(string.unable_to_add_to_bookmarks, Toast.LENGTH_SHORT) } } } catch (_: Exception) { // Catch the exception while saving the bookmarks for splitted zim files. // we have an issue with split zim files, see #3827 - requireActivity().toast(R.string.unable_to_add_to_bookmarks, Toast.LENGTH_SHORT) + requireActivity().toast(string.unable_to_add_to_bookmarks, Toast.LENGTH_SHORT) } } @@ -1952,7 +1926,7 @@ abstract class CoreReaderFragment : if (item.shouldOpenInNewTab) { createNewTab() } - item.pageUrl?.let(::loadUrlWithCurrentWebview) ?: kotlin.run { + item.pageUrl?.let(::loadUrlWithCurrentWebview) ?: run { zimReaderContainer?.titleToUrl(item.pageTitle)?.apply { loadUrlWithCurrentWebview(zimReaderContainer?.urlSuffixToParsableUrl(this)) } @@ -2069,7 +2043,7 @@ abstract class CoreReaderFragment : } else { contentUrl } - } ?: kotlin.run { + } ?: run { return@redirectOrOriginal contentUrl } } @@ -2088,7 +2062,7 @@ abstract class CoreReaderFragment : private fun openRandomArticle(retryCount: Int = 2) { // Check if the ZIM file reader is available, if not show an error and exit. if (zimReaderContainer?.zimFileReader == null) { - toast(R.string.error_loading_random_article_zim_not_loaded) + toast(string.error_loading_random_article_zim_not_loaded) return } val articleUrl = zimReaderContainer?.getRandomArticleUrl() @@ -2105,7 +2079,7 @@ abstract class CoreReaderFragment : } else { // if it is failed to find the random article two times then show a error to user. Log.e(TAG_KIWIX, "Failed to load random article after multiple attempts") - toast(R.string.could_not_find_random_article) + toast(string.could_not_find_random_article) } return } @@ -2420,7 +2394,7 @@ abstract class CoreReaderFragment : Log.d( TAG_KIWIX, String.format( - getString(R.string.error_article_url_not_found), + getString(string.error_article_url_not_found), failingUrl ) ) @@ -2500,9 +2474,9 @@ abstract class CoreReaderFragment : if (isOpenNewTabInBackground) { newTabInBackground(url) readerScreenState.value.snackBarHostState.snack( - message = context?.getString(R.string.new_tab_snack_bar).orEmpty(), + message = context?.getString(string.new_tab_snack_bar).orEmpty(), lifecycleScope = lifecycleScope, - actionLabel = context?.getString(R.string.open), + actionLabel = context?.getString(string.open), actionClick = { if (webViewList.size > 1) { selectTab(webViewList.size - 1) @@ -2603,7 +2577,7 @@ abstract class CoreReaderFragment : readerMenuState?.showWebViewOptions(urlIsValid()) } catch (ignore: Exception) { Log.w(TAG_KIWIX, "Kiwix shared preferences corrupted", ignore) - activity.toast(R.string.could_not_restore_tabs, Toast.LENGTH_LONG) + activity.toast(string.could_not_restore_tabs, Toast.LENGTH_LONG) } } @@ -2627,7 +2601,7 @@ abstract class CoreReaderFragment : webViewHistoryItem?.webViewBackForwardListBundle?.let { bundle -> webView.restoreState(bundle) webView.scrollY = webViewHistoryItem.webViewCurrentPosition - } ?: kotlin.run { + } ?: run { zimReaderContainer?.zimFileReader?.let { webView.loadUrl(redirectOrOriginal(contentUrl("${it.mainPage}"))) } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreen.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreen.kt index aa8cef838..7c676bd62 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreen.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreen.kt @@ -27,7 +27,9 @@ import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutVertically import androidx.compose.animation.togetherWith import androidx.compose.foundation.BorderStroke @@ -42,6 +44,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -49,6 +52,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState @@ -68,6 +72,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalDrawerSheet import androidx.compose.material3.Scaffold import androidx.compose.material3.SmallFloatingActionButton import androidx.compose.material3.Text @@ -76,6 +81,7 @@ import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.runtime.mutableStateOf @@ -107,13 +113,16 @@ import androidx.compose.ui.zIndex import kotlinx.coroutines.delay import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED +import org.kiwix.kiwixmobile.core.extensions.update import org.kiwix.kiwixmobile.core.main.DarkModeViewPainter import org.kiwix.kiwixmobile.core.main.KiwixWebView import org.kiwix.kiwixmobile.core.ui.components.ContentLoadingProgressBar import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar import org.kiwix.kiwixmobile.core.ui.components.KiwixButton import org.kiwix.kiwixmobile.core.ui.components.KiwixSnackbarHost +import org.kiwix.kiwixmobile.core.ui.components.ONE import org.kiwix.kiwixmobile.core.ui.components.ProgressBarStyle +import org.kiwix.kiwixmobile.core.ui.components.TWELVE import org.kiwix.kiwixmobile.core.ui.models.ActionMenuItem import org.kiwix.kiwixmobile.core.ui.models.IconItem import org.kiwix.kiwixmobile.core.ui.models.IconItem.Drawable @@ -130,6 +139,7 @@ import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FIVE_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FOUR_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.KIWIX_TOOLBAR_HEIGHT +import org.kiwix.kiwixmobile.core.utils.ComposeDimens.NAVIGATION_DRAWER_WIDTH import org.kiwix.kiwixmobile.core.utils.ComposeDimens.ONE_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.READER_BOTTOM_APP_BAR_BUTTON_ICON_SIZE import org.kiwix.kiwixmobile.core.utils.ComposeDimens.READER_BOTTOM_APP_BAR_DISABLE_BUTTON_ALPHA @@ -140,6 +150,7 @@ import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SIXTEEN_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TEN_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.THREE_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TTS_BUTTONS_CONTROL_ALPHA +import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TWELVE_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TWO_DP import org.kiwix.kiwixmobile.core.utils.StyleUtils.fromHtml @@ -155,6 +166,8 @@ const val TAB_TITLE_TESTING_TAG = "tabTitleTestingTag" fun ReaderScreen( state: ReaderScreenState, actionMenuItems: List, + showTableOfContentDrawer: MutableState, + documentSections: MutableList?, mainActivityBottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?, navigationIcon: @Composable () -> Unit ) { @@ -185,11 +198,34 @@ fun ReaderScreen( } .semantics { testTag = READER_SCREEN_TESTING_TAG } ) { paddingValues -> - ReaderContentLayout( - state, - Modifier.padding(paddingValues), - bottomAppBarScrollBehavior - ) + Box(Modifier.fillMaxSize()) { + ReaderContentLayout( + state, + Modifier.padding(paddingValues), + bottomAppBarScrollBehavior + ) + AnimatedVisibility( + visible = showTableOfContentDrawer.value, + enter = slideInHorizontally(initialOffsetX = { it }) + fadeIn(), + exit = slideOutHorizontally(targetOffsetX = { it }) + fadeOut(), + modifier = Modifier.align(Alignment.CenterEnd) + ) { + TableDrawerSheet( + title = state.tableOfContentTitle, + sections = documentSections.orEmpty(), + onHeaderClick = state.tableContentHeaderClick, + onSectionClick = state.tableOfContentSectionClick + ) + } + if (showTableOfContentDrawer.value) { + Box( + Modifier + .fillMaxSize() + .background(Color.Black.copy(alpha = 0.3f)) + .clickable { showTableOfContentDrawer.update { false } } + ) + } + } } } } @@ -255,6 +291,45 @@ private fun ReaderContentLayout( } } +@Composable +fun TableDrawerSheet( + title: String, + sections: List, + onHeaderClick: () -> Unit, + onSectionClick: (Int) -> Unit +) { + ModalDrawerSheet( + modifier = Modifier.width(NAVIGATION_DRAWER_WIDTH) + ) { + LazyColumn( + modifier = Modifier + .fillMaxHeight() + ) { + item { + Text( + text = title.ifEmpty { stringResource(id = R.string.no_section_info) }, + style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold), + modifier = Modifier + .fillMaxWidth() + .clickable { onHeaderClick() } + .padding(horizontal = SIXTEEN_DP, vertical = TWELVE_DP) + ) + } + itemsIndexed(sections) { index, section -> + val paddingStart = (section.level - ONE) * TWELVE + Text( + text = section.title, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier + .fillMaxWidth() + .clickable { onSectionClick(index) } + .padding(start = paddingStart.dp, top = EIGHT_DP, bottom = EIGHT_DP, end = SIXTEEN_DP) + ) + } + } + } +} + @Composable private fun TabSwitcherAnimated(state: ReaderScreenState) { val transitionSpec = remember { @@ -827,3 +902,5 @@ interface TabClickListener { fun onSelectTab(position: Int) fun onCloseTab(position: Int) } + +data class DocumentSection(var title: String, var id: String, var level: Int) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreenState.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreenState.kt index e6edbfd63..a5abd70c1 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreenState.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/reader/ReaderScreenState.kt @@ -168,5 +168,17 @@ data class ReaderScreenState( /** * Handles the click when user clicks on "Later" button in donation layout. */ - val laterButtonClick: () -> Unit + val laterButtonClick: () -> Unit, + /** + * Manages the showing of header title of "table of content". + */ + val tableOfContentTitle: String, + /** + * Handles the click when user clicks on the "Header" of "table of content". + */ + val tableContentHeaderClick: () -> Unit, + /** + * Handles the click when user clicks on the "section" of "table of content". + */ + val tableOfContentSectionClick: (Int) -> Unit ) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/search/SearchFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/search/SearchFragment.kt index e802363b7..99420137c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/search/SearchFragment.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/search/SearchFragment.kt @@ -29,7 +29,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import androidx.navigation.fragment.findNavController import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/ui/components/KiwixShowCaseView.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/ui/components/KiwixShowCaseView.kt index aa1f2a840..3a0b36313 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/ui/components/KiwixShowCaseView.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/ui/components/KiwixShowCaseView.kt @@ -86,6 +86,7 @@ const val SHOWCASE_VIEW_ROUND_ANIMATION_DURATION = 2000 const val ONE = 1 const val TWO = 2 const val SIXTEEN = 16 +const val TWELVE = 12 const val SHOWCASE_VIEW_NEXT_BUTTON_TESTING_TAG = "showcaseViewNextButtonTestingTag" const val SHOWCASE_VIEW_MESSAGE_TESTING_TAG = "showCaseViewMessageTestingTag" 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 b4c8c5f03..819f48b53 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 @@ -29,14 +29,12 @@ import androidx.compose.material.icons.filled.Menu import androidx.compose.ui.graphics.Color import androidx.core.net.toUri import androidx.drawerlayout.widget.DrawerLayout -import androidx.navigation.fragment.findNavController import com.google.android.material.bottomnavigation.BottomNavigationView import kotlinx.coroutines.launch import org.kiwix.kiwixmobile.core.base.BaseActivity import org.kiwix.kiwixmobile.core.extensions.browserIntent import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.extensions.update -import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.reader.CoreReaderFragment import org.kiwix.kiwixmobile.core.main.reader.ReaderMenuState import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin