Fixed: WebView was not occupying full height when the BottomAppBar was hidden.

* Moved the scrolling logic of the WebView into the Compose UI, as custom scroll handling in the WebView was causing issues.
* Removed ToolbarScrollingKiwixWebView since it's no longer needed—scrolling is now managed entirely within Compose.
* Added animations for opening and closing the tab switcher view.
This commit is contained in:
MohitMaliFtechiz 2025-06-25 01:50:22 +05:30
parent 3ebb37d5cc
commit db22e245b7
5 changed files with 107 additions and 264 deletions

View File

@ -21,7 +21,6 @@ package org.kiwix.kiwixmobile.nav.destination.reader
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.view.Menu
import android.view.MenuInflater
import android.view.View
@ -48,8 +47,6 @@ import org.kiwix.kiwixmobile.core.extensions.snack
import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.extensions.update
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.CoreWebViewClient
import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView
import org.kiwix.kiwixmobile.core.main.reader.CoreReaderFragment
import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin
import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin.FromExternalLaunch
@ -57,6 +54,7 @@ import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin.FromSearchScreen
import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue
import org.kiwix.kiwixmobile.core.utils.DimenUtils.getToolbarHeight
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE
import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
@ -299,19 +297,14 @@ class KiwixReaderFragment : CoreReaderFragment() {
}
}
@Throws(IllegalArgumentException::class)
override fun createWebView(attrs: AttributeSet?): ToolbarScrollingKiwixWebView? {
return ToolbarScrollingKiwixWebView(
requireContext(),
this,
attrs ?: throw IllegalArgumentException("AttributeSet must not be null"),
requireNotNull(readerScreenState.value.fullScreenItem.second),
CoreWebViewClient(this, requireNotNull(zimReaderContainer)),
onToolbarOffsetChanged = { offsetY -> toolbarOffsetY.value = offsetY },
onBottomAppBarOffsetChanged = { bottomOffsetY -> bottomAppBarOffsetY.value = bottomOffsetY },
sharedPreferenceUtil = requireNotNull(sharedPreferenceUtil),
parentNavigationBar = requireActivity().findViewById(R.id.bottom_nav_view)
)
override fun updateNavigationBarHeight(toolbarOffset: Float) {
// if no activity exist simply return.
if (activity == null) return
activity?.findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.let { view ->
val toolbarHeightPx = activity?.getToolbarHeight() ?: 0f
val offsetFactor = view.height / toolbarHeightPx.toFloat()
view.translationY = -1 * toolbarOffset * offsetFactor
}
}
override fun onFullscreenVideoToggled(isFullScreen: Boolean) {

View File

@ -13,7 +13,7 @@
<ID>LongParameterList:MainMenu.kt$MainMenu.Factory$( menu: Menu, webViews: MutableList&lt;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, 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>LongParameterList:ToolbarScrollingKiwixWebView.kt$ToolbarScrollingKiwixWebView$( context: Context, callback: WebViewCallback, attrs: AttributeSet, videoView: ViewGroup?, webViewClient: CoreWebViewClient, sharedPreferenceUtil: SharedPreferenceUtil )</ID>
<ID>MagicNumber:ArticleCount.kt$ArticleCount$3</ID>
<ID>MagicNumber:CompatFindActionModeCallback.kt$CompatFindActionModeCallback$100</ID>
<ID>MagicNumber:DownloadItem.kt$DownloadItem$1000L</ID>

View File

@ -1,136 +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.main
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
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")
class ToolbarScrollingKiwixWebView @JvmOverloads constructor(
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
) : KiwixWebView(
context,
callback,
attrs,
videoView,
webViewClient,
sharedPreferenceUtil
) {
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.
*/
private fun fixInitalScrollingIssue() {
moveToolbar(0)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
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)
}
}

View File

@ -148,7 +148,6 @@ 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.TabsAdapter
import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView
import org.kiwix.kiwixmobile.core.main.UNINITIALISER_ADDRESS
import org.kiwix.kiwixmobile.core.main.WebViewCallback
import org.kiwix.kiwixmobile.core.main.WebViewProvider
@ -226,9 +225,6 @@ abstract class CoreReaderFragment :
var drawerLayout: DrawerLayout? = null
protected var tableDrawerRightContainer: NavigationView? = null
var contentFrame: FrameLayout? = null
var tabSwitcherRoot: View? = null
var activityMainRoot: View? = null
@ -318,8 +314,6 @@ 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
@ -502,6 +496,9 @@ abstract class CoreReaderFragment :
ReaderScreen(
state = readerScreenState.value,
actionMenuItems = readerMenuState?.menuItems.orEmpty(),
onBottomScrollOffsetChanged = { offset ->
updateNavigationBarHeight(offset)
},
navigationIcon = {
NavigationIcon(
iconItem = navigationIcon(),
@ -509,9 +506,7 @@ abstract class CoreReaderFragment :
onClick = { navigationIconClick() },
iconTint = navigationIconTint()
)
},
toolbarOffsetY = toolbarOffsetY,
bottomAppBarOffsetY = bottomAppBarOffsetY
}
)
DialogHost(alertDialogShower as AlertDialogShower)
}
@ -615,6 +610,17 @@ abstract class CoreReaderFragment :
)
}
/**
* This method is for hiding the KiwixMainActivity bottomNavigationView.
* In custom apps we do not have the bottomnavigationView so that's why this method is empty here.
*
* See the implementation in KiwixReaderFragment.
* TODO refactore this when migrating the KiwixMainActivity in compose.
*/
open fun updateNavigationBarHeight(toolbarOffset: Float) {
// Do nothing since in custom apps we do not have the bottomNavigationView.
}
private fun getVideoView() = context?.let {
FrameLayout(it).apply {
layoutParams = ViewGroup.LayoutParams(
@ -698,7 +704,6 @@ abstract class CoreReaderFragment :
fragmentReaderBinding?.let { readerBinding ->
with(readerBinding.root) {
activityMainRoot = findViewById(R.id.activity_main_root)
contentFrame = findViewById(R.id.activity_main_content_frame)
toolbar = findViewById(R.id.toolbar)
tabSwitcherRoot = findViewById(R.id.activity_main_tab_switcher)
tabRecyclerView = findViewById(R.id.tab_switcher_recycler_view)
@ -921,29 +926,6 @@ abstract class CoreReaderFragment :
}
}
/**
* Sets a top margin to the web views.
*
* @param topMargin The top margin to be applied to the web views.
* Use 0 to remove the margin.
*/
protected open fun setTopMarginToWebViews(topMargin: Int) {
for (webView in webViewList) {
if (webView.parent == null) {
// Ensure that the web view has a parent before modifying its layout parameters
// This check is necessary to prevent adding the margin when the web view is not attached to a layout
// Adding the margin without a parent can cause unintended layout issues or empty
// space on top of the webView in the tabs adapter.
val frameLayout = FrameLayout(requireActivity())
// Add the web view to the frame layout
frameLayout.addView(webView)
}
val layoutParams = webView.layoutParams as FrameLayout.LayoutParams?
layoutParams?.topMargin = topMargin
webView.requestLayout()
}
}
protected fun startAnimation(
view: View?,
@AnimRes anim: Int
@ -969,9 +951,6 @@ 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)
}
open fun setUpDrawerToggle() {
@ -1360,7 +1339,6 @@ abstract class CoreReaderFragment :
activityMainRoot = null
tabRecyclerView = null
tabSwitcherRoot = null
contentFrame = null
compatCallback?.finish()
compatCallback = null
toolbar?.setOnTouchListener(null)
@ -1422,15 +1400,13 @@ abstract class CoreReaderFragment :
}
@Throws(IllegalArgumentException::class)
protected open fun createWebView(attrs: AttributeSet?): ToolbarScrollingKiwixWebView? {
return ToolbarScrollingKiwixWebView(
protected open fun createWebView(attrs: AttributeSet?): KiwixWebView? {
return KiwixWebView(
requireContext(),
this,
attrs ?: throw IllegalArgumentException("AttributeSet must not be null"),
requireNotNull(readerScreenState.value.fullScreenItem.second),
CoreWebViewClient(this, requireNotNull(zimReaderContainer)),
onToolbarOffsetChanged = { offsetY -> toolbarOffsetY.value = offsetY },
onBottomAppBarOffsetChanged = { bottomOffsetY -> bottomAppBarOffsetY.value = bottomOffsetY },
requireNotNull(sharedPreferenceUtil)
)
}
@ -1505,7 +1481,6 @@ abstract class CoreReaderFragment :
private fun reopenBook() {
hideNoBookOpenViews()
contentFrame?.visibility = VISIBLE
readerMenuState?.showBookSpecificMenuItems()
}
@ -1517,7 +1492,6 @@ abstract class CoreReaderFragment :
readerScreenTitle = context?.getString(R.string.reader).orEmpty()
)
}
contentFrame?.visibility = GONE
hideProgressBar()
readerMenuState?.hideBookSpecificMenuItems()
if (shouldCloseZimBook) {
@ -1796,16 +1770,16 @@ abstract class CoreReaderFragment :
setUpDrawerToggle()
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
sharedPreferenceUtil?.putPrefFullScreen(false)
updateBottomToolbarVisibility()
val window = requireActivity().window
window.decorView.closeFullScreenMode(window)
getCurrentWebView()?.requestLayout()
readerScreenState.update {
copy(
shouldShowBottomAppBar = true,
shouldShowFullScreenMode = false
)
}
updateBottomToolbarVisibility()
val window = requireActivity().window
window.decorView.closeFullScreenMode(window)
getCurrentWebView()?.requestLayout()
}
override fun openExternalUrl(intent: Intent) {

View File

@ -22,9 +22,14 @@ 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.AnimatedVisibility
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.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@ -37,11 +42,9 @@ 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
@ -56,6 +59,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.BottomAppBarDefaults
import androidx.compose.material3.BottomAppBarScrollBehavior
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
@ -97,9 +101,9 @@ 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 androidx.compose.ui.zIndex
import kotlinx.coroutines.delay
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED
@ -149,12 +153,15 @@ const val CONTENT_LOADING_PROGRESSBAR_TESTING_TAG = "contentLoadingProgressBarTe
fun ReaderScreen(
state: ReaderScreenState,
actionMenuItems: List<ActionMenuItem>,
toolbarOffsetY: MutableState<Float>,
bottomAppBarOffsetY: MutableState<Float>,
onBottomScrollOffsetChanged: (Float) -> Unit,
navigationIcon: @Composable () -> Unit
) {
val bottomNavHeightInDp = with(LocalDensity.current) { state.bottomNavigationHeight.toDp() }
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val bottomAppBarScrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
LaunchedEffect(bottomAppBarScrollBehavior.state.heightOffset) {
onBottomScrollOffsetChanged(scrollBehavior.state.heightOffset)
}
KiwixDialogTheme {
Scaffold(
snackbarHost = { KiwixSnackbarHost(snackbarHostState = state.snackBarHostState) },
@ -162,7 +169,6 @@ fun ReaderScreen(
ReaderTopBar(
state,
actionMenuItems,
toolbarOffsetY,
scrollBehavior,
navigationIcon
)
@ -171,12 +177,13 @@ fun ReaderScreen(
modifier = Modifier
.systemBarsPadding()
.nestedScroll(scrollBehavior.nestedScrollConnection)
.nestedScroll(bottomAppBarScrollBehavior.nestedScrollConnection)
.padding(bottom = bottomNavHeightInDp)
) { paddingValues ->
ReaderContentLayout(
state,
Modifier.padding(paddingValues),
bottomAppBarOffsetY
bottomAppBarScrollBehavior
)
}
}
@ -188,69 +195,87 @@ 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),
modifier = Modifier.offset { IntOffset(x = ZERO, y = animatedOffsetY.roundToPx()) }
searchPlaceHolderIfActive(state.searchPlaceHolderItemForCustomApps)
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ReaderContentLayout(
state: ReaderScreenState,
modifier: Modifier = Modifier,
bottomAppBarOffsetY: MutableState<Float>
bottomAppBarScrollBehavior: BottomAppBarScrollBehavior
) {
Box(modifier = modifier.fillMaxSize()) {
when {
state.showTabSwitcher -> TabSwitcherView(
state.kiwixWebViewList,
state.currentWebViewPosition,
state.onTabClickListener,
state.onCloseAllTabs,
state.darkModeViewPainter
)
TabSwitcherAnimated(state)
if (!state.showTabSwitcher) {
when {
state.isNoBookOpenInReader -> NoBookOpenView(state.onOpenLibraryButtonClicked)
state.fullScreenItem.first -> ShowFullScreenView(state)
state.isNoBookOpenInReader -> NoBookOpenView(state.onOpenLibraryButtonClicked)
state.fullScreenItem.first -> ShowFullScreenView(state)
else -> {
ShowZIMFileContent(state, bottomAppBarOffsetY)
ShowProgressBarIfZIMFilePageIsLoading(state)
Column(Modifier.align(Alignment.BottomCenter)) {
TtsControls(state)
BottomAppBarOfReaderScreen(
state.bookmarkButtonItem,
state.previousPageButtonItem,
state.onHomeButtonClick,
state.nextPageButtonItem,
state.tocButtonItem,
state.shouldShowBottomAppBar,
bottomAppBarOffsetY
else -> {
ShowZIMFileContent(state)
ShowProgressBarIfZIMFilePageIsLoading(state)
Column(Modifier.align(Alignment.BottomCenter)) {
TtsControls(state)
BottomAppBarOfReaderScreen(
state.bookmarkButtonItem,
state.previousPageButtonItem,
state.onHomeButtonClick,
state.nextPageButtonItem,
state.tocButtonItem,
state.shouldShowBottomAppBar,
bottomAppBarScrollBehavior
)
}
CloseFullScreenImageButton(
state.shouldShowFullScreenMode,
state.onExitFullscreenClick
)
}
CloseFullScreenImageButton(
state.shouldShowFullScreenMode,
state.onExitFullscreenClick
)
}
ShowDonationLayout(state)
}
}
}
ShowDonationLayout(state)
@Composable
private fun TabSwitcherAnimated(state: ReaderScreenState) {
val transitionSpec = remember {
slideInVertically(
initialOffsetY = { -it },
animationSpec = tween(durationMillis = 300)
) + fadeIn() togetherWith
slideOutVertically(
targetOffsetY = { -it },
animationSpec = tween(durationMillis = 300)
) + fadeOut()
}
AnimatedVisibility(
visible = state.showTabSwitcher,
enter = transitionSpec.targetContentEnter,
exit = transitionSpec.initialContentExit,
modifier = Modifier.zIndex(1f),
) {
TabSwitcherView(
state.kiwixWebViewList,
state.currentWebViewPosition,
state.onTabClickListener,
state.onCloseAllTabs,
state.darkModeViewPainter
)
}
}
@ -325,15 +350,7 @@ private fun BoxScope.CloseFullScreenImageButton(
}
@Composable
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)
private fun ShowZIMFileContent(state: ReaderScreenState) {
state.selectedWebView?.let { selectedWebView ->
key(selectedWebView) {
AndroidView(
@ -346,10 +363,10 @@ private fun ShowZIMFileContent(
}
},
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(bottom = totalBottomPadding)
.fillMaxSize()
.verticalScroll(rememberScrollState())
)
// TODO handle the unnecessary vertical scroll when webView page chnaged.
}
}
}
@ -458,18 +475,13 @@ private fun BottomAppBarOfReaderScreen(
nextPageButtonItem: Triple<() -> Unit, () -> Unit, Boolean>,
tocButtonItem: Pair<Boolean, () -> Unit>,
shouldShowBottomAppBar: Boolean,
bottomAppBarOffsetY: MutableState<Float>
bottomAppBarScrollBehavior: BottomAppBarScrollBehavior
) {
if (!shouldShowBottomAppBar) return
val animatedOffsetY by animateDpAsState(
targetValue = with(LocalDensity.current) { bottomAppBarOffsetY.value.toDp() },
label = "BottomAppBarOffset"
)
BottomAppBar(
containerColor = Black,
contentColor = White,
scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior(),
modifier = Modifier.offset { IntOffset(ZERO, animatedOffsetY.roundToPx()) }
scrollBehavior = bottomAppBarScrollBehavior,
) {
Row(
modifier = Modifier