mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
Fixed: Clicking on a table of content item wasn’t scrolling the WebView to the selected section because the Compose ScrollState caused recomposition back to the previous scroll position — now replaced with a custom approach to smoothly scroll to the target section. * Fixed: The whole screen was scrolling when scrolling the table of contents.
* Fixed: App was crashing and not opening the intro screen on fresh install. * Fixed: Design and appearance of the table of contents in dark mode.
This commit is contained in:
parent
f041ee9cf0
commit
8afaa8be52
@ -33,6 +33,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
@ -40,7 +41,6 @@ import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import eu.mhutti1.utils.storage.StorageDevice
|
||||
import eu.mhutti1.utils.storage.StorageDeviceUtils
|
||||
@ -128,9 +128,17 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
leftDrawerState = rememberDrawerState(DrawerValue.Closed)
|
||||
uiCoroutineScope = rememberCoroutineScope()
|
||||
bottomAppBarScrollBehaviour = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||
val startDestination = remember {
|
||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
||||
KiwixDestination.Intro.route
|
||||
} else {
|
||||
KiwixDestination.Reader.route
|
||||
}
|
||||
}
|
||||
KiwixMainActivityScreen(
|
||||
navController = navController,
|
||||
leftDrawerContent = leftDrawerMenu,
|
||||
startDestination = startDestination,
|
||||
topLevelDestinationsRoute = topLevelDestinationsRoute,
|
||||
leftDrawerState = leftDrawerState,
|
||||
uiCoroutineScope = uiCoroutineScope,
|
||||
@ -140,12 +148,6 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
)
|
||||
LaunchedEffect(navController) {
|
||||
navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange)
|
||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Reader.route, inclusive = true)
|
||||
.build()
|
||||
navigate(KiwixDestination.Intro.route, navOptions)
|
||||
}
|
||||
}
|
||||
DialogHost(alertDialogShower)
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ import org.kiwix.kiwixmobile.ui.KiwixNavGraph
|
||||
fun KiwixMainActivityScreen(
|
||||
navController: NavHostController,
|
||||
leftDrawerContent: List<DrawerMenuGroup>,
|
||||
startDestination: String,
|
||||
topLevelDestinationsRoute: Set<String>,
|
||||
leftDrawerState: DrawerState,
|
||||
uiCoroutineScope: CoroutineScope,
|
||||
@ -100,6 +101,7 @@ fun KiwixMainActivityScreen(
|
||||
Box(modifier = Modifier.padding(paddingValues)) {
|
||||
KiwixNavGraph(
|
||||
navController = navController,
|
||||
startDestination = startDestination,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
|
@ -221,9 +221,6 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
exitBook()
|
||||
}
|
||||
|
||||
override fun getBottomNavigationView(): BottomNavigationView? = null
|
||||
// requireActivity().findViewById(R.id.bottom_nav_view)
|
||||
|
||||
/**
|
||||
* Restores the view state based on the provided webViewHistoryItemList data and restore origin.
|
||||
*
|
||||
|
@ -77,11 +77,12 @@ import org.kiwix.kiwixmobile.webserver.ZimHostFragment
|
||||
@Composable
|
||||
fun KiwixNavGraph(
|
||||
navController: NavHostController,
|
||||
startDestination: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = KiwixDestination.Reader.route,
|
||||
startDestination = startDestination,
|
||||
modifier = modifier
|
||||
) {
|
||||
composable(
|
||||
|
@ -73,7 +73,6 @@ import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -303,7 +302,6 @@ abstract class CoreReaderFragment :
|
||||
nextPageButtonItem = Triple({ goForward() }, { showForwardHistory() }, false),
|
||||
tocButtonItem = false to { },
|
||||
onCloseAllTabs = { closeAllTabs() },
|
||||
bottomNavigationHeight = ZERO,
|
||||
shouldShowBottomAppBar = true,
|
||||
selectedWebView = null,
|
||||
readerScreenTitle = "",
|
||||
@ -330,9 +328,7 @@ abstract class CoreReaderFragment :
|
||||
appName = "",
|
||||
donateButtonClick = {},
|
||||
laterButtonClick = {},
|
||||
tableOfContentTitle = "",
|
||||
tableContentHeaderClick = { tableOfContentHeaderClick() },
|
||||
tableOfContentSectionClick = { tableOfContentSectionClick(it) },
|
||||
tableOfContentTitle = ""
|
||||
)
|
||||
)
|
||||
private var readerLifeCycleScope: CoroutineScope? = null
|
||||
@ -443,7 +439,6 @@ abstract class CoreReaderFragment :
|
||||
LaunchedEffect(Unit) {
|
||||
readerScreenState.update {
|
||||
copy(
|
||||
bottomNavigationHeight = getBottomNavigationHeight(),
|
||||
readerScreenTitle = context.getString(string.reader),
|
||||
darkModeViewPainter = darkModeViewPainter,
|
||||
fullScreenItem = fullScreenItem.first to getVideoView(),
|
||||
@ -482,7 +477,7 @@ abstract class CoreReaderFragment :
|
||||
},
|
||||
mainActivityBottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour,
|
||||
documentSections = documentSections,
|
||||
showTableOfContentDrawer = shouldTableOfContentDrawer,
|
||||
showTableOfContentDrawer = shouldTableOfContentDrawer
|
||||
)
|
||||
DialogHost(alertDialogShower as AlertDialogShower)
|
||||
}
|
||||
@ -545,8 +540,6 @@ 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.
|
||||
@ -677,31 +670,6 @@ abstract class CoreReaderFragment :
|
||||
documentSections?.clear()
|
||||
}
|
||||
|
||||
private fun tableOfContentHeaderClick() {
|
||||
getCurrentWebView()?.scrollY = 0
|
||||
shouldTableOfContentDrawer.update { false }
|
||||
}
|
||||
|
||||
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 {
|
||||
val documentListSize = documentSections?.size ?: return false
|
||||
return when {
|
||||
position < 0 -> false
|
||||
position >= documentListSize -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
private fun showTabSwitcher() {
|
||||
(requireActivity() as CoreMainActivity).apply {
|
||||
disableDrawer()
|
||||
@ -2699,8 +2667,6 @@ abstract class CoreReaderFragment :
|
||||
* when handling invalid JSON scenarios.
|
||||
*/
|
||||
abstract fun restoreViewStateOnInvalidWebViewHistory()
|
||||
|
||||
abstract fun getBottomNavigationView(): BottomNavigationView?
|
||||
}
|
||||
|
||||
enum class RestoreOrigin {
|
||||
|
@ -33,10 +33,12 @@ import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
@ -86,12 +88,14 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -111,8 +115,10 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.compose.ui.zIndex
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED
|
||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
||||
import org.kiwix.kiwixmobile.core.extensions.update
|
||||
import org.kiwix.kiwixmobile.core.main.DarkModeViewPainter
|
||||
import org.kiwix.kiwixmobile.core.main.KiwixWebView
|
||||
@ -130,6 +136,7 @@ import org.kiwix.kiwixmobile.core.ui.models.toPainter
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.Black
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.DenimBlue800
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.KiwixDialogTheme
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.MineShaftGray700
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.White
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.BACK_TO_TOP_BUTTON_BOTTOM_MARGIN
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.CLOSE_ALL_TAB_BUTTON_BOTTOM_PADDING
|
||||
@ -139,6 +146,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.LARGE_BODY_TEXT_SIZE
|
||||
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
|
||||
@ -171,60 +179,65 @@ fun ReaderScreen(
|
||||
mainActivityBottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
||||
navigationIcon: @Composable () -> Unit
|
||||
) {
|
||||
val bottomNavHeightInDp = with(LocalDensity.current) { state.bottomNavigationHeight.toDp() }
|
||||
val localWebViewScrollState: MutableState<ScrollState?> =
|
||||
remember { mutableStateOf(ScrollState(0)) }
|
||||
val topAppBarScrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
val bottomAppBarScrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||
KiwixDialogTheme {
|
||||
Scaffold(
|
||||
snackbarHost = { KiwixSnackbarHost(snackbarHostState = state.snackBarHostState) },
|
||||
topBar = {
|
||||
ReaderTopBar(
|
||||
state,
|
||||
actionMenuItems,
|
||||
topAppBarScrollBehavior,
|
||||
navigationIcon
|
||||
)
|
||||
},
|
||||
floatingActionButton = { BackToTopFab(state) },
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.padding(bottom = bottomNavHeightInDp)
|
||||
.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(bottomAppBarScrollBehavior.nestedScrollConnection)
|
||||
.let { baseModifier ->
|
||||
mainActivityBottomAppBarScrollBehaviour?.let {
|
||||
baseModifier.nestedScroll(it.nestedScrollConnection)
|
||||
} ?: baseModifier
|
||||
}
|
||||
.semantics { testTag = READER_SCREEN_TESTING_TAG }
|
||||
) { paddingValues ->
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
Scaffold(
|
||||
snackbarHost = { KiwixSnackbarHost(snackbarHostState = state.snackBarHostState) },
|
||||
topBar = {
|
||||
ReaderTopBar(
|
||||
state,
|
||||
actionMenuItems,
|
||||
topAppBarScrollBehavior,
|
||||
navigationIcon
|
||||
)
|
||||
},
|
||||
floatingActionButton = { BackToTopFab(state) },
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(bottomAppBarScrollBehavior.nestedScrollConnection)
|
||||
.let { baseModifier ->
|
||||
mainActivityBottomAppBarScrollBehaviour?.let {
|
||||
baseModifier.nestedScroll(it.nestedScrollConnection)
|
||||
} ?: baseModifier
|
||||
}
|
||||
.semantics { testTag = READER_SCREEN_TESTING_TAG }
|
||||
) { paddingValues ->
|
||||
ReaderContentLayout(
|
||||
state,
|
||||
Modifier.padding(paddingValues),
|
||||
bottomAppBarScrollBehavior
|
||||
bottomAppBarScrollBehavior,
|
||||
localWebViewScrollState.value
|
||||
)
|
||||
}
|
||||
if (showTableOfContentDrawer.value) {
|
||||
// Showing the background color on screen so that it look same as navigation drawer.
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black.copy(alpha = 0.3f))
|
||||
.clickable { showTableOfContentDrawer.update { false } }
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = showTableOfContentDrawer.value,
|
||||
enter = slideInHorizontally(initialOffsetX = { it }) + fadeIn(),
|
||||
exit = slideOutHorizontally(targetOffsetX = { it }) + fadeOut(),
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.align(Alignment.CenterEnd)
|
||||
) {
|
||||
TableDrawerSheet(
|
||||
title = state.tableOfContentTitle,
|
||||
sections = documentSections.orEmpty(),
|
||||
localWebViewScrollState,
|
||||
state.selectedWebView,
|
||||
showTableOfContentDrawer
|
||||
)
|
||||
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 } }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,7 +269,8 @@ private fun ReaderTopBar(
|
||||
private fun ReaderContentLayout(
|
||||
state: ReaderScreenState,
|
||||
modifier: Modifier = Modifier,
|
||||
bottomAppBarScrollBehavior: BottomAppBarScrollBehavior
|
||||
bottomAppBarScrollBehavior: BottomAppBarScrollBehavior,
|
||||
webViewScrollState: ScrollState?
|
||||
) {
|
||||
Box(modifier = modifier.fillMaxSize()) {
|
||||
TabSwitcherAnimated(state)
|
||||
@ -266,7 +280,7 @@ private fun ReaderContentLayout(
|
||||
state.fullScreenItem.first -> ShowFullScreenView(state)
|
||||
|
||||
else -> {
|
||||
ShowZIMFileContent(state)
|
||||
ShowZIMFileContent(state, webViewScrollState)
|
||||
ShowProgressBarIfZIMFilePageIsLoading(state)
|
||||
Column(Modifier.align(Alignment.BottomCenter)) {
|
||||
TtsControls(state)
|
||||
@ -295,23 +309,40 @@ private fun ReaderContentLayout(
|
||||
fun TableDrawerSheet(
|
||||
title: String,
|
||||
sections: List<DocumentSection>,
|
||||
onHeaderClick: () -> Unit,
|
||||
onSectionClick: (Int) -> Unit
|
||||
webViewScrollState: MutableState<ScrollState?>,
|
||||
selectedWebView: KiwixWebView?,
|
||||
showTableOfContentDrawer: MutableState<Boolean>
|
||||
) {
|
||||
val drawerBackgroundColor = if (isSystemInDarkTheme()) {
|
||||
MineShaftGray700
|
||||
} else {
|
||||
White
|
||||
}
|
||||
var scrollToSectionIndex by remember { mutableStateOf<Int?>(null) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
LaunchedEffect(scrollToSectionIndex) {
|
||||
scrollToSectionIndex?.let {
|
||||
webViewScrollState.value = null
|
||||
}
|
||||
}
|
||||
ModalDrawerSheet(
|
||||
modifier = Modifier.width(NAVIGATION_DRAWER_WIDTH)
|
||||
modifier = Modifier.width(NAVIGATION_DRAWER_WIDTH),
|
||||
drawerShape = RectangleShape,
|
||||
drawerContainerColor = drawerBackgroundColor
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
LazyColumn(modifier = Modifier.fillMaxHeight()) {
|
||||
item {
|
||||
Text(
|
||||
text = title.ifEmpty { stringResource(id = R.string.no_section_info) },
|
||||
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onHeaderClick() }
|
||||
.clickable {
|
||||
coroutineScope.launch {
|
||||
webViewScrollState.value?.animateScrollTo(ZERO)
|
||||
}
|
||||
showTableOfContentDrawer.update { false }
|
||||
}
|
||||
.padding(horizontal = SIXTEEN_DP, vertical = TWELVE_DP)
|
||||
)
|
||||
}
|
||||
@ -319,15 +350,46 @@ fun TableDrawerSheet(
|
||||
val paddingStart = (section.level - ONE) * TWELVE
|
||||
Text(
|
||||
text = section.title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
style = MaterialTheme.typography.bodyMedium.copy(
|
||||
fontWeight = FontWeight.Light,
|
||||
fontSize = LARGE_BODY_TEXT_SIZE
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onSectionClick(index) }
|
||||
.clickable { scrollToSectionIndex = index }
|
||||
.padding(start = paddingStart.dp, top = EIGHT_DP, bottom = EIGHT_DP, end = SIXTEEN_DP)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(webViewScrollState.value) {
|
||||
if (webViewScrollState.value == null &&
|
||||
scrollToSectionIndex != null &&
|
||||
hasItemForPositionInDocumentSectionsList(scrollToSectionIndex!!, sections)
|
||||
) {
|
||||
val targetId = sections[scrollToSectionIndex!!].id.replace("'", "\\'")
|
||||
selectedWebView?.evaluateJavascript(
|
||||
"document.getElementById('$targetId')?.scrollIntoView();",
|
||||
null
|
||||
)
|
||||
delay(100)
|
||||
webViewScrollState.value = ScrollState(selectedWebView?.scrollY ?: ZERO)
|
||||
scrollToSectionIndex = null
|
||||
showTableOfContentDrawer.update { false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasItemForPositionInDocumentSectionsList(
|
||||
position: Int,
|
||||
sections: List<DocumentSection>
|
||||
): Boolean {
|
||||
val documentListSize = sections.size
|
||||
return when {
|
||||
position < 0 -> false
|
||||
position >= documentListSize -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -433,12 +495,13 @@ private fun BoxScope.CloseFullScreenImageButton(
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun ShowZIMFileContent(state: ReaderScreenState) {
|
||||
private fun ShowZIMFileContent(state: ReaderScreenState, webViewScrollState: ScrollState?) {
|
||||
state.selectedWebView?.let { selectedWebView ->
|
||||
key(selectedWebView) {
|
||||
ScrollableWebViewWithNestedScroll(
|
||||
selectedWebView = selectedWebView,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
webViewScrollState = webViewScrollState
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -448,12 +511,19 @@ private fun ShowZIMFileContent(state: ReaderScreenState) {
|
||||
@Composable
|
||||
fun ScrollableWebViewWithNestedScroll(
|
||||
selectedWebView: KiwixWebView,
|
||||
modifier: Modifier = Modifier
|
||||
modifier: Modifier = Modifier,
|
||||
webViewScrollState: ScrollState?
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.let { baseModifier ->
|
||||
webViewScrollState?.let {
|
||||
baseModifier.verticalScroll(it)
|
||||
} ?: run {
|
||||
baseModifier
|
||||
}
|
||||
}
|
||||
) {
|
||||
AndroidView(
|
||||
factory = { context ->
|
||||
|
@ -139,10 +139,6 @@ data class ReaderScreenState(
|
||||
*/
|
||||
val tocButtonItem: Pair<Boolean, () -> Unit>,
|
||||
val onCloseAllTabs: () -> Unit,
|
||||
/**
|
||||
* Stores the height of the bottom navigation bar in pixels.
|
||||
*/
|
||||
val bottomNavigationHeight: Int,
|
||||
/**
|
||||
* Manages the showing of Reader's [BottomAppBarOfReaderScreen].
|
||||
*/
|
||||
@ -172,13 +168,5 @@ data class ReaderScreenState(
|
||||
/**
|
||||
* 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
|
||||
val tableOfContentTitle: String
|
||||
)
|
||||
|
@ -173,9 +173,6 @@ class CustomReaderFragment : CoreReaderFragment() {
|
||||
openHomeScreen()
|
||||
}
|
||||
|
||||
// Since custom apps do not have the bottomNavigationView, so returning null.
|
||||
override fun getBottomNavigationView(): BottomNavigationView? = null
|
||||
|
||||
/**
|
||||
* Restores the view state when the webViewHistory data is valid.
|
||||
* This method restores the tabs with webView pages history.
|
||||
|
Loading…
x
Reference in New Issue
Block a user