mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 02:36:24 -04:00
Refactored the TOC button functionality to handle cases where custom apps are configured to disable it.
* Fixed: Missing bottom margin in custom apps. * Fixed: Reader's bottom app bar not appearing after closing or selecting a tab. * Fixed: Menu not showing in the toolbar when the application is freshly launched in custom apps. * Refactored the scroll behavior of the toolbar and bottom app bar to sync with WebView scrolling in the Compose UI.
This commit is contained in:
parent
2608694442
commit
3ebb37d5cc
@ -95,10 +95,10 @@ fun LocalLibraryScreen(
|
||||
snackbarHost = { KiwixSnackbarHost(snackbarHostState = state.snackBarHostState) },
|
||||
topBar = {
|
||||
KiwixAppBar(
|
||||
stringResource(R.string.library),
|
||||
navigationIcon,
|
||||
state.actionMenuItems,
|
||||
scrollBehavior
|
||||
title = stringResource(R.string.library),
|
||||
navigationIcon = navigationIcon,
|
||||
actionMenuItems = state.actionMenuItems,
|
||||
topAppBarScrollBehavior = scrollBehavior
|
||||
)
|
||||
},
|
||||
floatingActionButton = { SelectFileButton(fabButtonClick) },
|
||||
|
@ -100,10 +100,10 @@ fun OnlineLibraryScreen(
|
||||
snackbarHost = { KiwixSnackbarHost(snackbarHostState = state.snackBarHostState) },
|
||||
topBar = {
|
||||
KiwixAppBar(
|
||||
stringResource(string.download),
|
||||
navigationIcon,
|
||||
actionMenuItems,
|
||||
scrollBehavior,
|
||||
title = stringResource(string.download),
|
||||
navigationIcon = navigationIcon,
|
||||
actionMenuItems = actionMenuItems,
|
||||
topAppBarScrollBehavior = scrollBehavior,
|
||||
searchBar = searchBarIfActive(state)
|
||||
)
|
||||
},
|
||||
|
@ -211,12 +211,12 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
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(0)
|
||||
}
|
||||
// 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) {
|
||||
@ -233,7 +233,6 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setFragmentContainerBottomMarginToSizeOfNavBar()
|
||||
if (isFullScreenVideo || isInFullScreenMode()) {
|
||||
hideNavBar()
|
||||
}
|
||||
@ -306,11 +305,10 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
requireContext(),
|
||||
this,
|
||||
attrs ?: throw IllegalArgumentException("AttributeSet must not be null"),
|
||||
null,
|
||||
requireNotNull(readerScreenState.value.fullScreenItem.second),
|
||||
CoreWebViewClient(this, requireNotNull(zimReaderContainer)),
|
||||
// requireNotNull(toolbarContainer),
|
||||
// requireNotNull(bottomToolbar),
|
||||
onToolbarOffsetChanged = { offsetY -> toolbarOffsetY.value = offsetY },
|
||||
onBottomAppBarOffsetChanged = { bottomOffsetY -> bottomAppBarOffsetY.value = bottomOffsetY },
|
||||
sharedPreferenceUtil = requireNotNull(sharedPreferenceUtil),
|
||||
parentNavigationBar = requireActivity().findViewById(R.id.bottom_nav_view)
|
||||
)
|
||||
|
@ -87,11 +87,20 @@ fun ZimHostScreen(
|
||||
) {
|
||||
KiwixTheme {
|
||||
Scaffold(topBar = {
|
||||
KiwixAppBar(stringResource(R.string.menu_wifi_hotspot), navigationIcon)
|
||||
KiwixAppBar(
|
||||
title = stringResource(R.string.menu_wifi_hotspot),
|
||||
navigationIcon = navigationIcon
|
||||
)
|
||||
}) { contentPadding ->
|
||||
Column(modifier = Modifier.fillMaxSize().padding(contentPadding)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(contentPadding)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = SIXTEEN_DP),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = SIXTEEN_DP),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
ServerIpText(serverIpText, Modifier.weight(1f), LocalContext.current)
|
||||
|
@ -23,8 +23,7 @@
|
||||
<fragment
|
||||
android:id="@+id/readerFragment"
|
||||
android:name="org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment"
|
||||
android:label="Reader"
|
||||
tools:layout="@layout/fragment_reader">
|
||||
android:label="Reader">
|
||||
<argument
|
||||
android:name="zimFileUri"
|
||||
android:defaultValue=""
|
||||
|
@ -13,7 +13,7 @@
|
||||
<ID>LongParameterList:MainMenu.kt$MainMenu.Factory$( menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, menuClickListener: MenuClickListener, disableReadAloud: Boolean, disableTabs: Boolean )</ID>
|
||||
<ID>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" )</ID>
|
||||
<ID>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 )</ID>
|
||||
<ID>LongParameterList:ToolbarScrollingKiwixWebView.kt$ToolbarScrollingKiwixWebView$( context: Context, callback: WebViewCallback, attrs: AttributeSet, nonVideoView: ViewGroup?, videoView: ViewGroup?, webViewClient: CoreWebViewClient, sharedPreferenceUtil: SharedPreferenceUtil, private val parentNavigationBar: View? = null )</ID>
|
||||
<ID>LongParameterList:ToolbarScrollingKiwixWebView.kt$ToolbarScrollingKiwixWebView$( context: Context, callback: WebViewCallback, attrs: AttributeSet, videoView: ViewGroup?, webViewClient: CoreWebViewClient, private val onToolbarOffsetChanged: ((Float) -> Unit)? = null, private val onBottomAppBarOffsetChanged: ((Float) -> Unit)? = null, sharedPreferenceUtil: SharedPreferenceUtil, private val parentNavigationBar: View? = null )</ID>
|
||||
<ID>MagicNumber:ArticleCount.kt$ArticleCount$3</ID>
|
||||
<ID>MagicNumber:CompatFindActionModeCallback.kt$CompatFindActionModeCallback$100</ID>
|
||||
<ID>MagicNumber:DownloadItem.kt$DownloadItem$1000L</ID>
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.extensions
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
|
||||
fun TextView.setTextAndVisibility(nullableText: String?) =
|
||||
if (nullableText?.isNotEmpty() == true) {
|
||||
text = nullableText
|
||||
visibility = View.VISIBLE
|
||||
} else {
|
||||
visibility = View.GONE
|
||||
}
|
@ -73,7 +73,7 @@ fun HelpScreen(
|
||||
KiwixTheme {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
KiwixAppBar(stringResource(R.string.menu_help), navigationIcon)
|
||||
KiwixAppBar(title = stringResource(R.string.menu_help), navigationIcon = navigationIcon)
|
||||
}
|
||||
) { innerPadding ->
|
||||
Column(modifier = Modifier.padding(innerPadding)) {
|
||||
|
@ -72,7 +72,13 @@ fun AddNoteDialogScreen(
|
||||
KiwixDialogTheme {
|
||||
Scaffold(
|
||||
snackbarHost = { KiwixSnackbarHost(snackbarHostState = snackBarHostState) },
|
||||
topBar = { KiwixAppBar(stringResource(R.string.note), navigationIcon, actionMenuItems) }
|
||||
topBar = {
|
||||
KiwixAppBar(
|
||||
title = stringResource(R.string.note),
|
||||
navigationIcon = navigationIcon,
|
||||
actionMenuItems = actionMenuItems
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
@ -23,10 +23,9 @@ import org.kiwix.videowebview.VideoEnabledWebChromeClient
|
||||
|
||||
class KiwixWebChromeClient(
|
||||
private val callback: WebViewCallback,
|
||||
nonVideoView: ViewGroup?,
|
||||
videoView: ViewGroup?,
|
||||
webView: KiwixWebView?
|
||||
) : VideoEnabledWebChromeClient(nonVideoView, videoView, null, webView) {
|
||||
) : VideoEnabledWebChromeClient(videoView, null, webView) {
|
||||
override fun onProgressChanged(view: WebView, progress: Int) {
|
||||
callback.webViewProgressChanged(progress, view)
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor(
|
||||
context: Context,
|
||||
private val callback: WebViewCallback,
|
||||
attrs: AttributeSet,
|
||||
private var nonVideoView: ViewGroup?,
|
||||
videoView: ViewGroup?,
|
||||
private val webViewClient: CoreWebViewClient,
|
||||
val sharedPreferenceUtil: SharedPreferenceUtil
|
||||
@ -102,7 +101,7 @@ open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor(
|
||||
clearCache(true)
|
||||
setWebViewClient(webViewClient)
|
||||
webChromeClient =
|
||||
KiwixWebChromeClient(callback, nonVideoView, videoView, this).apply {
|
||||
KiwixWebChromeClient(callback, videoView, this).apply {
|
||||
setOnToggledFullscreen(
|
||||
object : ToggledFullscreenCallback {
|
||||
override fun toggledFullscreen(fullscreen: Boolean) {
|
||||
@ -154,7 +153,6 @@ open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor(
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
nonVideoView = null
|
||||
textZoomJob?.cancel()
|
||||
textZoomJob = null
|
||||
}
|
||||
|
@ -23,8 +23,12 @@ import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import org.kiwix.kiwixmobile.core.utils.DimenUtils.getToolbarHeight
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.COMPOSE_BOTTOM_APP_BAR_DEFAULT_HEIGHT
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.COMPOSE_TOOLBAR_DEFAULT_HEIGHT
|
||||
import org.kiwix.kiwixmobile.core.utils.DimenUtils.dpToPx
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
@Suppress("UnusedPrivateProperty")
|
||||
@ -32,28 +36,72 @@ class ToolbarScrollingKiwixWebView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
callback: WebViewCallback,
|
||||
attrs: AttributeSet,
|
||||
nonVideoView: ViewGroup?,
|
||||
videoView: ViewGroup?,
|
||||
webViewClient: CoreWebViewClient,
|
||||
private val onToolbarOffsetChanged: ((Float) -> Unit)? = null,
|
||||
private val onBottomAppBarOffsetChanged: ((Float) -> Unit)? = null,
|
||||
sharedPreferenceUtil: SharedPreferenceUtil,
|
||||
private val parentNavigationBar: View? = null
|
||||
) : KiwixWebView(
|
||||
context,
|
||||
callback,
|
||||
attrs,
|
||||
nonVideoView,
|
||||
videoView,
|
||||
webViewClient,
|
||||
sharedPreferenceUtil
|
||||
) {
|
||||
private val toolbarHeight = context.getToolbarHeight()
|
||||
private val toolbarHeight = context.dpToPx(COMPOSE_TOOLBAR_DEFAULT_HEIGHT)
|
||||
private val bottomAppBarHeightPx = context.dpToPx(COMPOSE_BOTTOM_APP_BAR_DEFAULT_HEIGHT)
|
||||
|
||||
private var startY = 0f
|
||||
private var currentOffset = 0f
|
||||
|
||||
init {
|
||||
fixInitalScrollingIssue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the internal offset of the WebView based on scroll delta.
|
||||
*
|
||||
* Positive scrollDelta = user scrolling down (hide UI)
|
||||
* Negative scrollDelta = user scrolling up (show UI)
|
||||
*/
|
||||
|
||||
private fun moveToolbar(scrollDelta: Int): Boolean {
|
||||
val newOffset = when {
|
||||
scrollDelta > 0 -> max(-toolbarHeight.toFloat(), currentOffset - scrollDelta)
|
||||
else -> min(0f, currentOffset - scrollDelta)
|
||||
}
|
||||
|
||||
if (newOffset != currentOffset) {
|
||||
currentOffset = newOffset
|
||||
notifyOffsetChanged(newOffset)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies Compose UI about toolbar offset.
|
||||
*/
|
||||
private fun notifyOffsetChanged(offset: Float) {
|
||||
onToolbarOffsetChanged?.invoke(offset)
|
||||
|
||||
// Compute offset for bottomAppBar using height ratio
|
||||
val bottomOffset = offset * -1 * (bottomAppBarHeightPx.toFloat() / toolbarHeight)
|
||||
onBottomAppBarOffsetChanged?.invoke(bottomOffset)
|
||||
|
||||
// Optional: Animate parent navigation bar (if still using it)
|
||||
parentNavigationBar?.let { view ->
|
||||
val offsetFactor = view.height / toolbarHeight.toFloat()
|
||||
view.translationY = offset * -1 * offsetFactor
|
||||
}
|
||||
|
||||
// Adjust WebView position to prevent layout jump
|
||||
this.translationY = offset
|
||||
}
|
||||
|
||||
/**
|
||||
* The webview needs to be scrolled with 0 to not be slightly hidden on startup.
|
||||
* See https://github.com/kiwix/kiwix-android/issues/2304 for issue description.
|
||||
@ -62,68 +110,27 @@ class ToolbarScrollingKiwixWebView @JvmOverloads constructor(
|
||||
moveToolbar(0)
|
||||
}
|
||||
|
||||
@Suppress("FunctionOnlyReturningConstant", "UnusedParameter")
|
||||
private fun moveToolbar(scrollDelta: Int): Boolean {
|
||||
// val originalTranslation = toolbarView.translationY
|
||||
// val newTranslation =
|
||||
// if (scrollDelta > 0) {
|
||||
// // scroll down
|
||||
// max(-toolbarHeight.toFloat(), originalTranslation - scrollDelta)
|
||||
// } else {
|
||||
// // scroll up
|
||||
// min(0f, originalTranslation - scrollDelta)
|
||||
// }
|
||||
//
|
||||
// toolbarView.translationY = newTranslation
|
||||
// bottomBarView.translationY =
|
||||
// newTranslation * -1 * (bottomBarView.height / toolbarHeight.toFloat())
|
||||
// parentNavigationBar?.let {
|
||||
// it.translationY = newTranslation * -1 * (it.height / toolbarHeight.toFloat())
|
||||
// }
|
||||
// this.translationY = newTranslation + toolbarHeight
|
||||
// return toolbarHeight + newTranslation != 0f && newTranslation != 0f
|
||||
return false
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
// val transY = toolbarView.translationY.toInt()
|
||||
// when (event.actionMasked) {
|
||||
// MotionEvent.ACTION_DOWN -> startY = event.rawY
|
||||
// MotionEvent.ACTION_MOVE -> {
|
||||
// // If we are in fullscreen don't scroll bar
|
||||
// if (sharedPreferenceUtil.prefFullScreen) {
|
||||
// return super.onTouchEvent(event)
|
||||
// }
|
||||
// // Filter out zooms since we don't want to affect the toolbar when zooming
|
||||
// if (event.pointerCount == 1) {
|
||||
// val diffY = (event.rawY - startY).toInt()
|
||||
// startY = event.rawY
|
||||
// if (moveToolbar(-diffY)) {
|
||||
// event.offsetLocation(0f, -diffY.toFloat())
|
||||
// return super.onTouchEvent(event)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // If the toolbar is half-visible,
|
||||
// // either open or close it entirely depending on how far it is visible
|
||||
// MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL ->
|
||||
// if (transY != 0 && transY > -toolbarHeight) {
|
||||
// if (transY > -toolbarHeight / 2) {
|
||||
// ensureToolbarDisplayed()
|
||||
// } else {
|
||||
// ensureToolbarHidden()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (sharedPreferenceUtil.prefFullScreen) return super.onTouchEvent(event)
|
||||
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
startY = event.rawY
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (event.pointerCount == 1) {
|
||||
val diffY = (event.rawY - startY).toInt()
|
||||
startY = event.rawY
|
||||
if (moveToolbar(-diffY)) {
|
||||
event.offsetLocation(0f, -diffY.toFloat())
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
|
||||
private fun ensureToolbarDisplayed() {
|
||||
moveToolbar(-toolbarHeight)
|
||||
}
|
||||
|
||||
private fun ensureToolbarHidden() {
|
||||
moveToolbar(toolbarHeight)
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,6 @@ import androidx.annotation.AnimRes
|
||||
import androidx.appcompat.app.ActionBar
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
@ -171,7 +170,6 @@ import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen
|
||||
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
||||
import org.kiwix.kiwixmobile.core.ui.components.rememberBottomNavigationVisibility
|
||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.White
|
||||
import org.kiwix.kiwixmobile.core.utils.DimenUtils.getWindowWidth
|
||||
@ -320,6 +318,8 @@ abstract class CoreReaderFragment :
|
||||
private var isReadSelection = false
|
||||
private var isReadAloudServiceRunning = false
|
||||
private var libkiwixBook: Book? = null
|
||||
val toolbarOffsetY = mutableStateOf(0f)
|
||||
val bottomAppBarOffsetY = mutableStateOf(0f)
|
||||
|
||||
protected var readerMenuState: ReaderMenuState? = null
|
||||
private var composeView: ComposeView? = null
|
||||
@ -348,7 +348,7 @@ abstract class CoreReaderFragment :
|
||||
previousPageButtonItem = Triple({ goBack() }, { showBackwardHistory() }, false),
|
||||
onHomeButtonClick = { openMainPage() },
|
||||
nextPageButtonItem = Triple({ goForward() }, { showForwardHistory() }, false),
|
||||
onTocClick = { openToc() },
|
||||
tocButtonItem = false to { },
|
||||
onCloseAllTabs = { closeAllTabs() },
|
||||
bottomNavigationHeight = ZERO,
|
||||
shouldShowBottomAppBar = true,
|
||||
@ -473,11 +473,6 @@ abstract class CoreReaderFragment :
|
||||
readerMenuState = createMainMenu()
|
||||
composeView?.apply {
|
||||
setContent {
|
||||
val lazyListState = rememberLazyListState()
|
||||
val isBottomNavVisible = rememberBottomNavigationVisibility(lazyListState)
|
||||
LaunchedEffect(isBottomNavVisible) {
|
||||
(activity as? CoreMainActivity)?.toggleBottomNavigation(isBottomNavVisible)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
snapshotFlow { webViewList.size }
|
||||
.distinctUntilChanged()
|
||||
@ -491,7 +486,8 @@ abstract class CoreReaderFragment :
|
||||
bottomNavigationHeight = getBottomNavigationHeight(),
|
||||
readerScreenTitle = context.getString(R.string.reader),
|
||||
darkModeViewPainter = darkModeViewPainter,
|
||||
fullScreenItem = fullScreenItem.first to getVideoView()
|
||||
fullScreenItem = fullScreenItem.first to getVideoView(),
|
||||
tocButtonItem = getTocButtonStateAndAction()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -514,7 +510,8 @@ abstract class CoreReaderFragment :
|
||||
iconTint = navigationIconTint()
|
||||
)
|
||||
},
|
||||
listState = lazyListState
|
||||
toolbarOffsetY = toolbarOffsetY,
|
||||
bottomAppBarOffsetY = bottomAppBarOffsetY
|
||||
)
|
||||
DialogHost(alertDialogShower as AlertDialogShower)
|
||||
}
|
||||
@ -629,6 +626,20 @@ abstract class CoreReaderFragment :
|
||||
|
||||
private fun getBottomNavigationHeight(): Int = getBottomNavigationView()?.measuredHeight ?: ZERO
|
||||
|
||||
/**
|
||||
* Provides the visibility state and click action for the TOC (Table of Contents) button
|
||||
* shown in the reader's bottom app bar.
|
||||
*
|
||||
* @return A [Pair] containing:
|
||||
* - [Boolean]: Indicates whether the TOC button should be enabled (e.g., can be disabled
|
||||
* in certain custom app configurations where the sidebar is turned off).
|
||||
* - [() -> Unit]: The action to perform when the TOC button is clicked.
|
||||
*
|
||||
* Note: If modifying this method, ensure it is thoroughly tested in custom app variants
|
||||
* where sidebar behavior may differ.
|
||||
*/
|
||||
open fun getTocButtonStateAndAction(): Pair<Boolean, () -> Unit> = true to { openToc() }
|
||||
|
||||
private fun navigationIconContentDescription() =
|
||||
if (readerMenuState?.isInTabSwitcher == true) {
|
||||
R.string.search_open_in_new_tab
|
||||
@ -949,7 +960,6 @@ abstract class CoreReaderFragment :
|
||||
protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) {
|
||||
setUpDrawerToggle()
|
||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
selectTab(currentWebViewIndex)
|
||||
readerScreenState.update {
|
||||
copy(
|
||||
shouldShowBottomAppBar = true,
|
||||
@ -958,6 +968,7 @@ abstract class CoreReaderFragment :
|
||||
}
|
||||
showSearchPlaceHolderInToolbar(false)
|
||||
readerMenuState?.showWebViewOptions(urlIsValid())
|
||||
selectTab(currentWebViewIndex)
|
||||
// Reset the top margin of web views to 0 to remove any previously set margin
|
||||
// This ensures that the web views are displayed without any additional top margin for kiwix custom apps.
|
||||
// setTopMarginToWebViews(0)
|
||||
@ -1077,7 +1088,7 @@ abstract class CoreReaderFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun openToc() {
|
||||
protected fun openToc() {
|
||||
drawerLayout?.openDrawer(GravityCompat.END)
|
||||
}
|
||||
|
||||
@ -1413,14 +1424,13 @@ abstract class CoreReaderFragment :
|
||||
@Throws(IllegalArgumentException::class)
|
||||
protected open fun createWebView(attrs: AttributeSet?): ToolbarScrollingKiwixWebView? {
|
||||
return ToolbarScrollingKiwixWebView(
|
||||
requireActivity(),
|
||||
requireContext(),
|
||||
this,
|
||||
attrs ?: throw IllegalArgumentException("AttributeSet must not be null"),
|
||||
null,
|
||||
requireNotNull(readerScreenState.value.fullScreenItem.second),
|
||||
CoreWebViewClient(this, requireNotNull(zimReaderContainer)),
|
||||
// requireNotNull(toolbarContainer),
|
||||
// requireNotNull(bottomToolbar),
|
||||
onToolbarOffsetChanged = { offsetY -> toolbarOffsetY.value = offsetY },
|
||||
onBottomAppBarOffsetChanged = { bottomOffsetY -> bottomAppBarOffsetY.value = bottomOffsetY },
|
||||
requireNotNull(sharedPreferenceUtil)
|
||||
)
|
||||
}
|
||||
@ -1821,7 +1831,6 @@ abstract class CoreReaderFragment :
|
||||
// Show content if there is `Open Library` button showing
|
||||
// and we are opening the ZIM file
|
||||
hideNoBookOpenViews()
|
||||
contentFrame?.visibility = VISIBLE
|
||||
openAndSetInContainer(zimReaderSource)
|
||||
updateTitle()
|
||||
} else {
|
||||
@ -2203,7 +2212,7 @@ abstract class CoreReaderFragment :
|
||||
|
||||
private fun updateBottomToolbarVisibility() {
|
||||
readerScreenState.update {
|
||||
copy(shouldShowBottomAppBar = !showTabSwitcher && !isInFullScreenMode())
|
||||
copy(shouldShowBottomAppBar = readerMenuState?.isInTabSwitcher == false && !isInFullScreenMode())
|
||||
}
|
||||
}
|
||||
|
||||
@ -2882,6 +2891,7 @@ abstract class CoreReaderFragment :
|
||||
}
|
||||
selectTab(currentTab)
|
||||
onComplete.invoke()
|
||||
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)
|
||||
|
@ -61,7 +61,7 @@ const val TAB_MENU_ITEM_TESTING_TAG = "tabMenuItemTestingTag"
|
||||
@Stable
|
||||
class ReaderMenuState(
|
||||
private val menuClickListener: MenuClickListener,
|
||||
private val isUrlValidInitially: Boolean,
|
||||
isUrlValidInitially: Boolean,
|
||||
private val disableReadAloud: Boolean = false,
|
||||
private val disableTabs: Boolean = false,
|
||||
private val disableSearch: Boolean = false
|
||||
|
@ -22,6 +22,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.widget.FrameLayout
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
@ -36,9 +37,11 @@ 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
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
@ -94,6 +97,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import kotlinx.coroutines.delay
|
||||
@ -144,12 +148,12 @@ const val CONTENT_LOADING_PROGRESSBAR_TESTING_TAG = "contentLoadingProgressBarTe
|
||||
@Composable
|
||||
fun ReaderScreen(
|
||||
state: ReaderScreenState,
|
||||
listState: LazyListState,
|
||||
actionMenuItems: List<ActionMenuItem>,
|
||||
toolbarOffsetY: MutableState<Float>,
|
||||
bottomAppBarOffsetY: MutableState<Float>,
|
||||
navigationIcon: @Composable () -> Unit
|
||||
) {
|
||||
val (bottomNavHeight, lazyListState) =
|
||||
rememberScrollBehavior(state.bottomNavigationHeight, listState)
|
||||
val bottomNavHeightInDp = with(LocalDensity.current) { state.bottomNavigationHeight.toDp() }
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
KiwixDialogTheme {
|
||||
Scaffold(
|
||||
@ -158,6 +162,7 @@ fun ReaderScreen(
|
||||
ReaderTopBar(
|
||||
state,
|
||||
actionMenuItems,
|
||||
toolbarOffsetY,
|
||||
scrollBehavior,
|
||||
navigationIcon
|
||||
)
|
||||
@ -166,9 +171,13 @@ fun ReaderScreen(
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.padding(bottom = bottomNavHeight.value)
|
||||
.padding(bottom = bottomNavHeightInDp)
|
||||
) { paddingValues ->
|
||||
ReaderContentLayout(state, Modifier.padding(paddingValues))
|
||||
ReaderContentLayout(
|
||||
state,
|
||||
Modifier.padding(paddingValues),
|
||||
bottomAppBarOffsetY
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,23 +188,33 @@ fun ReaderScreen(
|
||||
private fun ReaderTopBar(
|
||||
state: ReaderScreenState,
|
||||
actionMenuItems: List<ActionMenuItem>,
|
||||
toolbarOffsetY: MutableState<Float>,
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
navigationIcon: @Composable () -> Unit,
|
||||
) {
|
||||
if (!state.shouldShowFullScreenMode && !state.fullScreenItem.first) {
|
||||
val animatedOffsetY by animateDpAsState(
|
||||
targetValue = with(LocalDensity.current) { toolbarOffsetY.value.toDp() },
|
||||
label = "ToolbarScrollOffset"
|
||||
)
|
||||
KiwixAppBar(
|
||||
title = if (state.showTabSwitcher) "" else state.readerScreenTitle,
|
||||
navigationIcon = navigationIcon,
|
||||
actionMenuItems = actionMenuItems,
|
||||
topAppBarScrollBehavior = scrollBehavior,
|
||||
searchBar =
|
||||
searchPlaceHolderIfActive(state.searchPlaceHolderItemForCustomApps)
|
||||
searchPlaceHolderIfActive(state.searchPlaceHolderItemForCustomApps),
|
||||
modifier = Modifier.offset { IntOffset(x = ZERO, y = animatedOffsetY.roundToPx()) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ReaderContentLayout(state: ReaderScreenState, modifier: Modifier = Modifier) {
|
||||
private fun ReaderContentLayout(
|
||||
state: ReaderScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
bottomAppBarOffsetY: MutableState<Float>
|
||||
) {
|
||||
Box(modifier = modifier.fillMaxSize()) {
|
||||
when {
|
||||
state.showTabSwitcher -> TabSwitcherView(
|
||||
@ -210,7 +229,7 @@ private fun ReaderContentLayout(state: ReaderScreenState, modifier: Modifier = M
|
||||
state.fullScreenItem.first -> ShowFullScreenView(state)
|
||||
|
||||
else -> {
|
||||
ShowZIMFileContent(state)
|
||||
ShowZIMFileContent(state, bottomAppBarOffsetY)
|
||||
ShowProgressBarIfZIMFilePageIsLoading(state)
|
||||
Column(Modifier.align(Alignment.BottomCenter)) {
|
||||
TtsControls(state)
|
||||
@ -219,8 +238,9 @@ private fun ReaderContentLayout(state: ReaderScreenState, modifier: Modifier = M
|
||||
state.previousPageButtonItem,
|
||||
state.onHomeButtonClick,
|
||||
state.nextPageButtonItem,
|
||||
state.onTocClick,
|
||||
state.shouldShowBottomAppBar
|
||||
state.tocButtonItem,
|
||||
state.shouldShowBottomAppBar,
|
||||
bottomAppBarOffsetY
|
||||
)
|
||||
}
|
||||
CloseFullScreenImageButton(
|
||||
@ -305,7 +325,15 @@ private fun BoxScope.CloseFullScreenImageButton(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ShowZIMFileContent(state: ReaderScreenState) {
|
||||
private fun ShowZIMFileContent(
|
||||
state: ReaderScreenState,
|
||||
bottomAppBarOffsetY: MutableState<Float>
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
||||
val bottomNavHeightDp = with(density) { state.bottomNavigationHeight.toDp() }
|
||||
val bottomAppBarOffsetDp = with(density) { -bottomAppBarOffsetY.value.toDp() }
|
||||
val totalBottomPadding = (bottomNavHeightDp + bottomAppBarOffsetDp).coerceAtLeast(ZERO.dp)
|
||||
state.selectedWebView?.let { selectedWebView ->
|
||||
key(selectedWebView) {
|
||||
AndroidView(
|
||||
@ -317,7 +345,10 @@ private fun ShowZIMFileContent(state: ReaderScreenState) {
|
||||
addView(selectedWebView)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxSize()
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight()
|
||||
.padding(bottom = totalBottomPadding)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -425,14 +456,20 @@ private fun BottomAppBarOfReaderScreen(
|
||||
previousPageButtonItem: Triple<() -> Unit, () -> Unit, Boolean>,
|
||||
onHomeButtonClick: () -> Unit,
|
||||
nextPageButtonItem: Triple<() -> Unit, () -> Unit, Boolean>,
|
||||
onTocClick: () -> Unit,
|
||||
shouldShowBottomAppBar: Boolean
|
||||
tocButtonItem: Pair<Boolean, () -> Unit>,
|
||||
shouldShowBottomAppBar: Boolean,
|
||||
bottomAppBarOffsetY: MutableState<Float>
|
||||
) {
|
||||
if (!shouldShowBottomAppBar) return
|
||||
val animatedOffsetY by animateDpAsState(
|
||||
targetValue = with(LocalDensity.current) { bottomAppBarOffsetY.value.toDp() },
|
||||
label = "BottomAppBarOffset"
|
||||
)
|
||||
BottomAppBar(
|
||||
containerColor = Black,
|
||||
contentColor = White,
|
||||
scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||
scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior(),
|
||||
modifier = Modifier.offset { IntOffset(ZERO, animatedOffsetY.roundToPx()) }
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -472,7 +509,8 @@ private fun BottomAppBarOfReaderScreen(
|
||||
)
|
||||
// Toggle Icon(to open the table of content in right side bar)
|
||||
BottomAppBarButtonIcon(
|
||||
onClick = onTocClick,
|
||||
shouldEnable = tocButtonItem.first,
|
||||
onClick = tocButtonItem.second,
|
||||
buttonIcon = Drawable(R.drawable.ic_toc_24dp),
|
||||
contentDescription = stringResource(R.string.table_of_contents)
|
||||
)
|
||||
|
@ -132,8 +132,12 @@ data class ReaderScreenState(
|
||||
val nextPageButtonItem: Triple<() -> Unit, () -> Unit, Boolean>,
|
||||
/**
|
||||
* Handles the click to open right sidebar button click in reader bottom toolbar.
|
||||
*
|
||||
* A [Pair] containing:
|
||||
* - [Boolean]: Handles the button should enable or not(Specially for custom apps).
|
||||
* - [Unit]: Handles the click of button.
|
||||
*/
|
||||
val onTocClick: () -> Unit,
|
||||
val tocButtonItem: Pair<Boolean, () -> Unit>,
|
||||
val onCloseAllTabs: () -> Unit,
|
||||
/**
|
||||
* Stores the height of the bottom navigation bar in pixels.
|
||||
|
@ -70,7 +70,13 @@ fun NavigationHistoryDialogScreen(
|
||||
) {
|
||||
KiwixDialogTheme {
|
||||
Scaffold(
|
||||
topBar = { KiwixAppBar(stringResource(titleId), navigationIcon, actionMenuItems) }
|
||||
topBar = {
|
||||
KiwixAppBar(
|
||||
title = stringResource(titleId),
|
||||
navigationIcon = navigationIcon,
|
||||
actionMenuItems = actionMenuItems
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
@ -72,6 +72,7 @@ const val TOOLBAR_TITLE_TESTING_TAG = "toolbarTitle"
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun KiwixAppBar(
|
||||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
navigationIcon: @Composable () -> Unit,
|
||||
actionMenuItems: List<ActionMenuItem> = emptyList(),
|
||||
@ -92,7 +93,8 @@ fun KiwixAppBar(
|
||||
// Edge-to-Edge mode is already enabled in our application,
|
||||
// so we don't need to apply additional top insets.
|
||||
// This prevents unwanted extra margin at the top.
|
||||
windowInsets = WindowInsets.statusBars.only(WindowInsetsSides.Horizontal)
|
||||
windowInsets = WindowInsets.statusBars.only(WindowInsetsSides.Horizontal),
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -193,4 +193,6 @@ object ComposeDimens {
|
||||
val BACK_TO_TOP_BUTTON_BOTTOM_MARGIN = 80.dp
|
||||
const val READER_BOTTOM_APP_BAR_DISABLE_BUTTON_ALPHA = 0.38f
|
||||
val SEARCH_PLACEHOLDER_TEXT_SIZE = 12.sp
|
||||
val COMPOSE_TOOLBAR_DEFAULT_HEIGHT = 64.dp
|
||||
val COMPOSE_BOTTOM_APP_BAR_DEFAULT_HEIGHT = 80.dp
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import android.os.Build
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.TypedValue
|
||||
import androidx.appcompat.R
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
object DimenUtils {
|
||||
@JvmStatic fun Context.getToolbarHeight(): Int {
|
||||
@ -33,6 +34,14 @@ object DimenUtils {
|
||||
)
|
||||
}
|
||||
|
||||
fun Context.dpToPx(dp: Dp): Int {
|
||||
return TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
dp.value,
|
||||
resources.displayMetrics
|
||||
).toInt()
|
||||
}
|
||||
|
||||
@JvmStatic fun Activity.getWindowHeight(): Int =
|
||||
computedDisplayMetric.heightPixels
|
||||
|
||||
|
@ -55,7 +55,6 @@ open class VideoEnabledWebChromeClient :
|
||||
fun toggledFullscreen(fullscreen: Boolean)
|
||||
}
|
||||
|
||||
private var activityNonVideoView: View? = null
|
||||
private var activityVideoView: ViewGroup? = null
|
||||
private var loadingView: View? = null
|
||||
private var webView: VideoEnabledWebView? = null
|
||||
@ -84,14 +83,11 @@ open class VideoEnabledWebChromeClient :
|
||||
/**
|
||||
* Builds a video enabled WebChromeClient.
|
||||
*
|
||||
* @param activityNonVideoView A View in the activity's layout that contains every other view that
|
||||
* should be hidden when the video goes full-screen.
|
||||
* @param activityVideoView A ViewGroup in the activity's layout that will display the video.
|
||||
* Typically you would like this to fill the whole layout.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
constructor(activityNonVideoView: View?, activityVideoView: ViewGroup?) {
|
||||
this.activityNonVideoView = activityNonVideoView
|
||||
constructor(activityVideoView: ViewGroup?) {
|
||||
this.activityVideoView = activityVideoView
|
||||
loadingView = null
|
||||
webView = null
|
||||
@ -101,8 +97,6 @@ open class VideoEnabledWebChromeClient :
|
||||
/**
|
||||
* Builds a video enabled WebChromeClient.
|
||||
*
|
||||
* @param activityNonVideoView A View in the activity's layout that contains every other view that
|
||||
* should be hidden when the video goes full-screen.
|
||||
* @param activityVideoView A ViewGroup in the activity's layout that will display the video.
|
||||
* Typically you would like this to fill the whole layout.
|
||||
* @param loadingView A View to be shown while the video is loading (typically only used in API
|
||||
@ -110,11 +104,9 @@ open class VideoEnabledWebChromeClient :
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
constructor(
|
||||
activityNonVideoView: View?,
|
||||
activityVideoView: ViewGroup?,
|
||||
loadingView: View?
|
||||
) {
|
||||
this.activityNonVideoView = activityNonVideoView
|
||||
this.activityVideoView = activityVideoView
|
||||
this.loadingView = loadingView
|
||||
webView = null
|
||||
@ -124,8 +116,6 @@ open class VideoEnabledWebChromeClient :
|
||||
/**
|
||||
* Builds a video enabled WebChromeClient.
|
||||
*
|
||||
* @param activityNonVideoView A View in the activity's layout that contains every other view that
|
||||
* should be hidden when the video goes full-screen.
|
||||
* @param activityVideoView A ViewGroup in the activity's layout that will display the video.
|
||||
* Typically you would like this to fill the whole layout.
|
||||
* @param loadingView A View to be shown while the video is loading (typically only used in API
|
||||
@ -137,12 +127,10 @@ open class VideoEnabledWebChromeClient :
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
constructor(
|
||||
activityNonVideoView: View?,
|
||||
activityVideoView: ViewGroup?,
|
||||
loadingView: View?,
|
||||
webView: VideoEnabledWebView?
|
||||
) {
|
||||
this.activityNonVideoView = activityNonVideoView
|
||||
this.activityVideoView = activityVideoView
|
||||
this.loadingView = loadingView
|
||||
this.webView = webView
|
||||
@ -177,9 +165,6 @@ open class VideoEnabledWebChromeClient :
|
||||
isVideoFullscreen = true
|
||||
videoViewContainer = view
|
||||
videoViewCallback = callback
|
||||
|
||||
// Hide the non-video view, add the video view, and show it
|
||||
activityNonVideoView?.visibility = View.INVISIBLE
|
||||
activityVideoView?.addView(
|
||||
videoViewContainer,
|
||||
ViewGroup.LayoutParams(
|
||||
@ -248,7 +233,6 @@ open class VideoEnabledWebChromeClient :
|
||||
// Hide the video view, remove it, and show the non-video view
|
||||
activityVideoView?.visibility = View.INVISIBLE
|
||||
activityVideoView?.removeView(videoViewContainer)
|
||||
activityNonVideoView?.visibility = View.VISIBLE
|
||||
|
||||
// Call back (only in API level <19, because in API level 19+ with chromium webview it crashes)
|
||||
videoViewCallback?.let {
|
||||
|
@ -23,7 +23,6 @@ import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
@ -78,12 +77,6 @@ class CustomReaderFragment : CoreReaderFragment() {
|
||||
|
||||
if (isAdded) {
|
||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
if (BuildConfig.DISABLE_SIDEBAR) {
|
||||
val toolbarToc =
|
||||
activity?.findViewById<ImageView>(org.kiwix.kiwixmobile.core.R.id.bottom_toolbar_toc)
|
||||
toolbarToc?.isEnabled = false
|
||||
// TODO refactor this with compose UI.
|
||||
}
|
||||
with(activity as AppCompatActivity) {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
setUpDrawerToggle()
|
||||
@ -98,6 +91,20 @@ class CustomReaderFragment : CoreReaderFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TOC (Table of Contents) button's enabled state and click action.
|
||||
*
|
||||
* In this custom app variant, the TOC button is disabled if [BuildConfig.DISABLE_SIDEBAR] is `true`.
|
||||
* This is typically used when the sidebar functionality is intentionally turned off.
|
||||
*
|
||||
* @return A [Pair] containing:
|
||||
* - [Boolean]: `true` if the TOC button should be enabled (i.e., sidebar is allowed),
|
||||
* `false` if it should be disabled (i.e., [DISABLE_SIDEBAR] is `true`).
|
||||
* - [() -> Unit]: Action to execute when the button is clicked. This will only be invoked if enabled.
|
||||
*/
|
||||
override fun getTocButtonStateAndAction(): Pair<Boolean, () -> Unit> =
|
||||
!BuildConfig.DISABLE_SIDEBAR to { openToc() }
|
||||
|
||||
/**
|
||||
* Returns the tint color for the navigation icon.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user