mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-08 23:07:26 -04:00
Fixed: Tabs were being automatically restored after closing them, navigating away from the reader screen, and then returning.
* Removed unused code from the reader screen. * Refactored fullscreen mode functionality to align with Compose UI. * Improved the `CloseAllTabs` button styling to match the app theme. * Refactored the "Back to Top" button functionality using Compose, and enhanced its UI. * Fixed: `Long-press` on bottom app bar buttons was not working due to `IconButton` consuming the touch event. * Removed the unused `AnimationUtils` file. * Fixed: Navigation history (forward and backward) was not being displayed.
This commit is contained in:
parent
b694ae3170
commit
234e9169f6
@ -29,15 +29,12 @@ import android.view.View.GONE
|
|||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.kiwix.kiwixmobile.R
|
import org.kiwix.kiwixmobile.R
|
||||||
import org.kiwix.kiwixmobile.cachedComponent
|
import org.kiwix.kiwixmobile.cachedComponent
|
||||||
import org.kiwix.kiwixmobile.core.R.anim
|
|
||||||
import org.kiwix.kiwixmobile.core.R.drawable
|
|
||||||
import org.kiwix.kiwixmobile.core.R.string
|
import org.kiwix.kiwixmobile.core.R.string
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super
|
||||||
@ -47,7 +44,6 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggl
|
|||||||
import org.kiwix.kiwixmobile.core.extensions.coreMainActivity
|
import org.kiwix.kiwixmobile.core.extensions.coreMainActivity
|
||||||
import org.kiwix.kiwixmobile.core.extensions.isFileExist
|
import org.kiwix.kiwixmobile.core.extensions.isFileExist
|
||||||
import org.kiwix.kiwixmobile.core.extensions.setBottomMarginToFragmentContainerView
|
import org.kiwix.kiwixmobile.core.extensions.setBottomMarginToFragmentContainerView
|
||||||
import org.kiwix.kiwixmobile.core.extensions.setImageDrawableCompat
|
|
||||||
import org.kiwix.kiwixmobile.core.extensions.snack
|
import org.kiwix.kiwixmobile.core.extensions.snack
|
||||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||||
import org.kiwix.kiwixmobile.core.extensions.update
|
import org.kiwix.kiwixmobile.core.extensions.update
|
||||||
@ -184,32 +180,6 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
|||||||
* @see closeAllTabs
|
* @see closeAllTabs
|
||||||
*/
|
*/
|
||||||
override fun hideTabSwitcher(shouldCloseZimBook: Boolean) {
|
override fun hideTabSwitcher(shouldCloseZimBook: Boolean) {
|
||||||
actionBar?.let { actionBar ->
|
|
||||||
actionBar.setDisplayShowTitleEnabled(true)
|
|
||||||
toolbar?.let { activity?.setupDrawerToggle(it, true) }
|
|
||||||
|
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
|
||||||
|
|
||||||
closeAllTabsButton?.setImageDrawableCompat(drawable.ic_close_black_24dp)
|
|
||||||
if (tabSwitcherRoot?.isVisible == true) {
|
|
||||||
tabSwitcherRoot?.visibility = GONE
|
|
||||||
startAnimation(tabSwitcherRoot, anim.slide_up)
|
|
||||||
progressBar?.visibility = View.GONE
|
|
||||||
progressBar?.progress = 0
|
|
||||||
contentFrame?.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
readerMenuState?.showWebViewOptions(true)
|
|
||||||
if (webViewList.isEmpty()) {
|
|
||||||
exitBook(shouldCloseZimBook)
|
|
||||||
} else {
|
|
||||||
// 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 main app.
|
|
||||||
setTopMarginToWebViews(0)
|
|
||||||
selectTab(currentWebViewIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actionBar?.setDisplayShowTitleEnabled(true)
|
|
||||||
toolbar?.let { activity?.setupDrawerToggle(it, true) }
|
toolbar?.let { activity?.setupDrawerToggle(it, true) }
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
if (webViewList.isEmpty()) {
|
if (webViewList.isEmpty()) {
|
||||||
|
@ -52,10 +52,7 @@ import android.view.ViewGroup
|
|||||||
import android.view.animation.AnimationUtils
|
import android.view.animation.AnimationUtils
|
||||||
import android.webkit.WebBackForwardList
|
import android.webkit.WebBackForwardList
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.ImageButton
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -79,16 +76,12 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.constraintlayout.widget.Group
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.core.view.isGone
|
|
||||||
import androidx.core.view.isInvisible
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.ContentLoadingProgressBar
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@ -96,10 +89,8 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
|
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
|
||||||
import com.google.android.material.bottomappbar.BottomAppBar
|
import com.google.android.material.bottomappbar.BottomAppBar
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -134,8 +125,6 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.observeNavigatio
|
|||||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.requestNotificationPermission
|
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.requestNotificationPermission
|
||||||
import org.kiwix.kiwixmobile.core.extensions.ViewGroupExtensions.findFirstTextView
|
import org.kiwix.kiwixmobile.core.extensions.ViewGroupExtensions.findFirstTextView
|
||||||
import org.kiwix.kiwixmobile.core.extensions.closeFullScreenMode
|
import org.kiwix.kiwixmobile.core.extensions.closeFullScreenMode
|
||||||
import org.kiwix.kiwixmobile.core.extensions.getToolbarNavigationIcon
|
|
||||||
import org.kiwix.kiwixmobile.core.extensions.setToolTipWithContentDescription
|
|
||||||
import org.kiwix.kiwixmobile.core.extensions.showFullScreenMode
|
import org.kiwix.kiwixmobile.core.extensions.showFullScreenMode
|
||||||
import org.kiwix.kiwixmobile.core.extensions.snack
|
import org.kiwix.kiwixmobile.core.extensions.snack
|
||||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||||
@ -185,7 +174,6 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen
|
|||||||
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.rememberBottomNavigationVisibility
|
import org.kiwix.kiwixmobile.core.ui.components.rememberBottomNavigationVisibility
|
||||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||||
import org.kiwix.kiwixmobile.core.utils.AnimationUtils.rotate
|
|
||||||
import org.kiwix.kiwixmobile.core.utils.DimenUtils.getWindowWidth
|
import org.kiwix.kiwixmobile.core.utils.DimenUtils.getWindowWidth
|
||||||
import org.kiwix.kiwixmobile.core.utils.DonationDialogHandler
|
import org.kiwix.kiwixmobile.core.utils.DonationDialogHandler
|
||||||
import org.kiwix.kiwixmobile.core.utils.DonationDialogHandler.ShowDonationDialogCallback
|
import org.kiwix.kiwixmobile.core.utils.DonationDialogHandler.ShowDonationDialogCallback
|
||||||
@ -237,24 +225,16 @@ abstract class CoreReaderFragment :
|
|||||||
private var fragmentReaderBinding: FragmentReaderBinding? = null
|
private var fragmentReaderBinding: FragmentReaderBinding? = null
|
||||||
|
|
||||||
var toolbar: Toolbar? = null
|
var toolbar: Toolbar? = null
|
||||||
var toolbarContainer: AppBarLayout? = null
|
|
||||||
var progressBar: ContentLoadingProgressBar? = null
|
|
||||||
|
|
||||||
var drawerLayout: DrawerLayout? = null
|
var drawerLayout: DrawerLayout? = null
|
||||||
protected var tableDrawerRightContainer: NavigationView? = null
|
protected var tableDrawerRightContainer: NavigationView? = null
|
||||||
|
|
||||||
var contentFrame: FrameLayout? = null
|
var contentFrame: FrameLayout? = null
|
||||||
|
|
||||||
var bottomToolbar: BottomAppBar? = null
|
|
||||||
|
|
||||||
var tabSwitcherRoot: View? = null
|
var tabSwitcherRoot: View? = null
|
||||||
|
|
||||||
var closeAllTabsButton: FloatingActionButton? = null
|
|
||||||
|
|
||||||
var videoView: ViewGroup? = null
|
var videoView: ViewGroup? = null
|
||||||
|
|
||||||
var noOpenBookButton: Button? = null
|
|
||||||
|
|
||||||
var activityMainRoot: View? = null
|
var activityMainRoot: View? = null
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@ -273,10 +253,6 @@ abstract class CoreReaderFragment :
|
|||||||
@Inject
|
@Inject
|
||||||
var darkModeConfig: DarkModeConfig? = null
|
var darkModeConfig: DarkModeConfig? = null
|
||||||
|
|
||||||
@JvmField
|
|
||||||
@Inject
|
|
||||||
var menuFactory: MainMenu.Factory? = null
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@Inject
|
@Inject
|
||||||
var libkiwixBookmarks: LibkiwixBookmarks? = null
|
var libkiwixBookmarks: LibkiwixBookmarks? = null
|
||||||
@ -299,29 +275,7 @@ abstract class CoreReaderFragment :
|
|||||||
|
|
||||||
var toolbarWithSearchPlaceholder: ConstraintLayout? = null
|
var toolbarWithSearchPlaceholder: ConstraintLayout? = null
|
||||||
|
|
||||||
var backToTopButton: FloatingActionButton? = null
|
|
||||||
|
|
||||||
private var stopTTSButton: Button? = null
|
|
||||||
|
|
||||||
var pauseTTSButton: Button? = null
|
|
||||||
|
|
||||||
var ttsControls: Group? = null
|
|
||||||
|
|
||||||
private var exitFullscreenButton: ImageButton? = null
|
|
||||||
|
|
||||||
private var bottomToolbarBookmark: ImageView? = null
|
|
||||||
|
|
||||||
private var bottomToolbarArrowBack: ImageView? = null
|
|
||||||
|
|
||||||
private var bottomToolbarArrowForward: ImageView? = null
|
|
||||||
|
|
||||||
private var bottomToolbarHome: ImageView? = null
|
|
||||||
|
|
||||||
private var tabRecyclerView: RecyclerView? = null
|
private var tabRecyclerView: RecyclerView? = null
|
||||||
|
|
||||||
private var noOpenBookText: TextView? = null
|
|
||||||
private var bottomToolbarToc: ImageView? = null
|
|
||||||
|
|
||||||
private var isFirstTimeMainPageLoaded = true
|
private var isFirstTimeMainPageLoaded = true
|
||||||
private var isFromManageExternalLaunch = false
|
private var isFromManageExternalLaunch = false
|
||||||
private val savingTabsMutex = Mutex()
|
private val savingTabsMutex = Mutex()
|
||||||
@ -384,7 +338,6 @@ abstract class CoreReaderFragment :
|
|||||||
fullScreenItem = false to null,
|
fullScreenItem = false to null,
|
||||||
showBackToTopButton = false,
|
showBackToTopButton = false,
|
||||||
backToTopButtonClick = { backToTop() },
|
backToTopButtonClick = { backToTop() },
|
||||||
showFullscreenButton = false,
|
|
||||||
onExitFullscreenClick = { closeFullScreen() },
|
onExitFullscreenClick = { closeFullScreen() },
|
||||||
showTtsControls = false,
|
showTtsControls = false,
|
||||||
onPauseTtsClick = { pauseTts() },
|
onPauseTtsClick = { pauseTts() },
|
||||||
@ -420,7 +373,8 @@ abstract class CoreReaderFragment :
|
|||||||
override fun onCloseTab(position: Int) {
|
override fun onCloseTab(position: Int) {
|
||||||
closeTab(position)
|
closeTab(position)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
shouldShowFullScreenMode = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private var readerLifeCycleScope: CoroutineScope? = null
|
private var readerLifeCycleScope: CoroutineScope? = null
|
||||||
@ -699,29 +653,13 @@ abstract class CoreReaderFragment :
|
|||||||
private fun prepareViews() {
|
private fun prepareViews() {
|
||||||
fragmentReaderBinding?.let { readerBinding ->
|
fragmentReaderBinding?.let { readerBinding ->
|
||||||
videoView = readerBinding.fullscreenVideoContainer
|
videoView = readerBinding.fullscreenVideoContainer
|
||||||
noOpenBookButton = readerBinding.goToLibraryButtonNoOpenBook
|
|
||||||
noOpenBookText = readerBinding.noOpenBookText
|
|
||||||
with(readerBinding.root) {
|
with(readerBinding.root) {
|
||||||
activityMainRoot = findViewById(R.id.activity_main_root)
|
activityMainRoot = findViewById(R.id.activity_main_root)
|
||||||
contentFrame = findViewById(R.id.activity_main_content_frame)
|
contentFrame = findViewById(R.id.activity_main_content_frame)
|
||||||
toolbar = findViewById(R.id.toolbar)
|
toolbar = findViewById(R.id.toolbar)
|
||||||
toolbarContainer = findViewById(R.id.fragment_main_app_bar)
|
|
||||||
progressBar = findViewById(R.id.main_fragment_progress_view)
|
|
||||||
bottomToolbar = findViewById(R.id.bottom_toolbar)
|
|
||||||
tabSwitcherRoot = findViewById(R.id.activity_main_tab_switcher)
|
tabSwitcherRoot = findViewById(R.id.activity_main_tab_switcher)
|
||||||
closeAllTabsButton = findViewById(R.id.tab_switcher_close_all_tabs)
|
|
||||||
toolbarWithSearchPlaceholder = findViewById(R.id.toolbarWithSearchPlaceholder)
|
toolbarWithSearchPlaceholder = findViewById(R.id.toolbarWithSearchPlaceholder)
|
||||||
backToTopButton = findViewById(R.id.activity_main_back_to_top_fab)
|
|
||||||
stopTTSButton = findViewById(R.id.activity_main_button_stop_tts)
|
|
||||||
pauseTTSButton = findViewById(R.id.activity_main_button_pause_tts)
|
|
||||||
ttsControls = findViewById(R.id.activity_main_tts_controls)
|
|
||||||
exitFullscreenButton = findViewById(R.id.activity_main_fullscreen_button)
|
|
||||||
bottomToolbarBookmark = findViewById(R.id.bottom_toolbar_bookmark)
|
|
||||||
bottomToolbarArrowBack = findViewById(R.id.bottom_toolbar_arrow_back)
|
|
||||||
bottomToolbarArrowForward = findViewById(R.id.bottom_toolbar_arrow_forward)
|
|
||||||
bottomToolbarHome = findViewById(R.id.bottom_toolbar_home)
|
|
||||||
tabRecyclerView = findViewById(R.id.tab_switcher_recycler_view)
|
tabRecyclerView = findViewById(R.id.tab_switcher_recycler_view)
|
||||||
bottomToolbarToc = findViewById(R.id.bottom_toolbar_toc)
|
|
||||||
donationLayout = findViewById(R.id.donation_layout)
|
donationLayout = findViewById(R.id.donation_layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -731,53 +669,6 @@ abstract class CoreReaderFragment :
|
|||||||
toolbarWithSearchPlaceholder?.setOnClickListener {
|
toolbarWithSearchPlaceholder?.setOnClickListener {
|
||||||
openSearch(searchString = "", isOpenedFromTabView = false, false)
|
openSearch(searchString = "", isOpenedFromTabView = false, false)
|
||||||
}
|
}
|
||||||
backToTopButton?.setOnClickListener {
|
|
||||||
backToTop()
|
|
||||||
}
|
|
||||||
stopTTSButton?.setOnClickListener {
|
|
||||||
stopTts()
|
|
||||||
}
|
|
||||||
pauseTTSButton?.setOnClickListener {
|
|
||||||
pauseTts()
|
|
||||||
}
|
|
||||||
exitFullscreenButton?.setOnClickListener {
|
|
||||||
closeFullScreen()
|
|
||||||
}
|
|
||||||
bottomToolbarBookmark?.apply {
|
|
||||||
setOnClickListener {
|
|
||||||
toggleBookmark()
|
|
||||||
}
|
|
||||||
setOnLongClickListener {
|
|
||||||
goToBookmarks()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomToolbarArrowBack?.apply {
|
|
||||||
setOnClickListener {
|
|
||||||
goBack()
|
|
||||||
}
|
|
||||||
setOnLongClickListener {
|
|
||||||
showBackwardHistory()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomToolbarArrowForward?.apply {
|
|
||||||
setOnClickListener {
|
|
||||||
goForward()
|
|
||||||
}
|
|
||||||
setOnLongClickListener {
|
|
||||||
showForwardHistory()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomToolbarToc?.setOnClickListener {
|
|
||||||
openToc()
|
|
||||||
}
|
|
||||||
closeAllTabsButton?.setOnClickListener {
|
|
||||||
closeAllTabs()
|
|
||||||
}
|
|
||||||
bottomToolbarHome?.setOnClickListener {
|
|
||||||
openMainPage()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initTabCallback() {
|
private fun initTabCallback() {
|
||||||
@ -820,7 +711,7 @@ abstract class CoreReaderFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
backToTopButton?.hide()
|
hideBackToTopButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -956,21 +847,6 @@ abstract class CoreReaderFragment :
|
|||||||
|
|
||||||
private fun showTabSwitcher() {
|
private fun showTabSwitcher() {
|
||||||
(requireActivity() as CoreMainActivity).disableDrawer()
|
(requireActivity() as CoreMainActivity).disableDrawer()
|
||||||
actionBar?.apply {
|
|
||||||
setDisplayHomeAsUpEnabled(true)
|
|
||||||
setHomeAsUpIndicator(
|
|
||||||
ContextCompat.getDrawable(requireActivity(), R.drawable.ic_round_add_white_36dp)
|
|
||||||
)
|
|
||||||
// set the contentDescription to UpIndicator icon.
|
|
||||||
toolbar?.getToolbarNavigationIcon()?.setToolTipWithContentDescription(
|
|
||||||
getString(R.string.search_open_in_new_tab)
|
|
||||||
)
|
|
||||||
setDisplayShowTitleEnabled(false)
|
|
||||||
}
|
|
||||||
closeAllTabsButton?.setToolTipWithContentDescription(
|
|
||||||
resources.getString(R.string.close_all_tabs)
|
|
||||||
)
|
|
||||||
setIsCloseAllTabButtonClickable(true)
|
|
||||||
// Set a negative top margin to the web views to remove
|
// Set a negative top margin to the web views to remove
|
||||||
// the unwanted blank space caused by the toolbar.
|
// the unwanted blank space caused by the toolbar.
|
||||||
// setTopMarginToWebViews(-requireActivity().getToolbarHeight())
|
// setTopMarginToWebViews(-requireActivity().getToolbarHeight())
|
||||||
@ -979,13 +855,10 @@ abstract class CoreReaderFragment :
|
|||||||
copy(
|
copy(
|
||||||
shouldShowBottomAppBar = false,
|
shouldShowBottomAppBar = false,
|
||||||
pageLoadingItem = false to ZERO,
|
pageLoadingItem = false to ZERO,
|
||||||
readerScreenTitle = ""
|
readerScreenTitle = "",
|
||||||
|
showBackToTopButton = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
contentFrame?.visibility = GONE
|
|
||||||
progressBar?.visibility = GONE
|
|
||||||
backToTopButton?.hide()
|
|
||||||
setTabSwitcherVisibility(VISIBLE)
|
|
||||||
startAnimation(tabSwitcherRoot, R.anim.slide_down)
|
startAnimation(tabSwitcherRoot, R.anim.slide_down)
|
||||||
tabsAdapter?.let { tabsAdapter ->
|
tabsAdapter?.let { tabsAdapter ->
|
||||||
tabRecyclerView?.let { recyclerView ->
|
tabRecyclerView?.let { recyclerView ->
|
||||||
@ -1053,23 +926,8 @@ abstract class CoreReaderFragment :
|
|||||||
* as closing the ZIM book would require reloading the ZIM file, which can be a resource-intensive operation.
|
* as closing the ZIM book would require reloading the ZIM file, which can be a resource-intensive operation.
|
||||||
*/
|
*/
|
||||||
protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) {
|
protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) {
|
||||||
actionBar?.apply {
|
|
||||||
setDisplayShowTitleEnabled(true)
|
|
||||||
}
|
|
||||||
toolbar?.let(::setUpDrawerToggle)
|
toolbar?.let(::setUpDrawerToggle)
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
closeAllTabsButton?.setImageDrawable(
|
|
||||||
ContextCompat.getDrawable(requireActivity(), R.drawable.ic_close_black_24dp)
|
|
||||||
)
|
|
||||||
tabSwitcherRoot?.let {
|
|
||||||
if (it.isVisible) {
|
|
||||||
setTabSwitcherVisibility(GONE)
|
|
||||||
startAnimation(it, R.anim.slide_up)
|
|
||||||
progressBar?.visibility = VISIBLE
|
|
||||||
contentFrame?.visibility = VISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
progressBar?.hide()
|
|
||||||
selectTab(currentWebViewIndex)
|
selectTab(currentWebViewIndex)
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(
|
copy(
|
||||||
@ -1477,32 +1335,16 @@ abstract class CoreReaderFragment :
|
|||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
private fun unBindViewsAndBinding() {
|
private fun unBindViewsAndBinding() {
|
||||||
activityMainRoot = null
|
activityMainRoot = null
|
||||||
noOpenBookButton = null
|
|
||||||
toolbarWithSearchPlaceholder = null
|
toolbarWithSearchPlaceholder = null
|
||||||
backToTopButton = null
|
|
||||||
stopTTSButton = null
|
|
||||||
pauseTTSButton = null
|
|
||||||
ttsControls = null
|
|
||||||
exitFullscreenButton = null
|
|
||||||
bottomToolbarBookmark = null
|
|
||||||
bottomToolbarArrowBack = null
|
|
||||||
bottomToolbarArrowForward = null
|
|
||||||
bottomToolbarHome = null
|
|
||||||
tabRecyclerView = null
|
tabRecyclerView = null
|
||||||
noOpenBookText = null
|
|
||||||
bottomToolbarToc = null
|
|
||||||
bottomToolbar = null
|
|
||||||
tabSwitcherRoot = null
|
tabSwitcherRoot = null
|
||||||
videoView = null
|
videoView = null
|
||||||
contentFrame = null
|
contentFrame = null
|
||||||
toolbarContainer = null
|
|
||||||
compatCallback?.finish()
|
compatCallback?.finish()
|
||||||
compatCallback = null
|
compatCallback = null
|
||||||
toolbar?.setOnTouchListener(null)
|
toolbar?.setOnTouchListener(null)
|
||||||
toolbar = null
|
toolbar = null
|
||||||
progressBar = null
|
|
||||||
drawerLayout = null
|
drawerLayout = null
|
||||||
closeAllTabsButton = null
|
|
||||||
tableDrawerRightContainer = null
|
tableDrawerRightContainer = null
|
||||||
fragmentReaderBinding?.root?.removeAllViews()
|
fragmentReaderBinding?.root?.removeAllViews()
|
||||||
fragmentReaderBinding = null
|
fragmentReaderBinding = null
|
||||||
@ -1627,18 +1469,17 @@ abstract class CoreReaderFragment :
|
|||||||
if (index <= currentWebViewIndex && currentWebViewIndex > 0) {
|
if (index <= currentWebViewIndex && currentWebViewIndex > 0) {
|
||||||
currentWebViewIndex--
|
currentWebViewIndex--
|
||||||
}
|
}
|
||||||
tabsAdapter?.apply {
|
|
||||||
notifyItemRemoved(index)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
readerScreenState.value.snackBarHostState.snack(
|
readerScreenState.value.snackBarHostState.snack(
|
||||||
requireActivity().getString(R.string.tab_closed),
|
requireActivity().getString(R.string.tab_closed),
|
||||||
actionLabel = requireActivity().getString(R.string.undo),
|
actionLabel = requireActivity().getString(R.string.undo),
|
||||||
actionClick = { restoreDeletedTab(index) },
|
actionClick = { restoreDeletedTab(index) },
|
||||||
lifecycleScope = lifecycleScope,
|
lifecycleScope = lifecycleScope,
|
||||||
snackBarResult = { result ->
|
snackBarResult = { result ->
|
||||||
if (result == SnackbarResult.Dismissed && webViewList.isEmpty() && isAdded) {
|
if (result == SnackbarResult.Dismissed && isAdded) {
|
||||||
closeZimBook()
|
saveTabStates()
|
||||||
|
if (webViewList.isEmpty()) {
|
||||||
|
closeZimBook()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -1774,14 +1615,13 @@ abstract class CoreReaderFragment :
|
|||||||
if (readerScreenState.value.showTtsControls) {
|
if (readerScreenState.value.showTtsControls) {
|
||||||
// currently TTS is running
|
// currently TTS is running
|
||||||
if (isBackToTopEnabled) {
|
if (isBackToTopEnabled) {
|
||||||
readerScreenState.update { copy(showBackToTopButton = true) }
|
showBackToTopButton()
|
||||||
backToTopButton?.show()
|
|
||||||
}
|
}
|
||||||
tts?.stop()
|
tts?.stop()
|
||||||
} else {
|
} else {
|
||||||
// TTS is not running.
|
// TTS is not running.
|
||||||
if (isBackToTopEnabled) {
|
if (isBackToTopEnabled) {
|
||||||
readerScreenState.update { copy(showBackToTopButton = false) }
|
hideBackToTopButton()
|
||||||
}
|
}
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty())
|
copy(pauseTtsButtonText = context?.getString(R.string.tts_pause).orEmpty())
|
||||||
@ -1911,12 +1751,12 @@ abstract class CoreReaderFragment :
|
|||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
protected open fun openFullScreen() {
|
protected open fun openFullScreen() {
|
||||||
(requireActivity() as CoreMainActivity).disableDrawer(false)
|
(requireActivity() as CoreMainActivity).disableDrawer(false)
|
||||||
toolbarContainer?.visibility = GONE
|
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(shouldShowBottomAppBar = false)
|
copy(
|
||||||
|
shouldShowBottomAppBar = false,
|
||||||
|
shouldShowFullScreenMode = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
exitFullscreenButton?.visibility = VISIBLE
|
|
||||||
exitFullscreenButton?.background?.alpha = 153
|
|
||||||
val window = requireActivity().window
|
val window = requireActivity().window
|
||||||
window.decorView.showFullScreenMode(window)
|
window.decorView.showFullScreenMode(window)
|
||||||
getCurrentWebView()?.apply {
|
getCurrentWebView()?.apply {
|
||||||
@ -1931,10 +1771,13 @@ abstract class CoreReaderFragment :
|
|||||||
toolbar?.let(::setUpDrawerToggle)
|
toolbar?.let(::setUpDrawerToggle)
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
sharedPreferenceUtil?.putPrefFullScreen(false)
|
sharedPreferenceUtil?.putPrefFullScreen(false)
|
||||||
toolbarContainer?.visibility = VISIBLE
|
readerScreenState.update {
|
||||||
|
copy(
|
||||||
|
shouldShowBottomAppBar = true,
|
||||||
|
shouldShowFullScreenMode = false
|
||||||
|
)
|
||||||
|
}
|
||||||
updateBottomToolbarVisibility()
|
updateBottomToolbarVisibility()
|
||||||
exitFullscreenButton?.visibility = GONE
|
|
||||||
exitFullscreenButton?.background?.alpha = 255
|
|
||||||
val window = requireActivity().window
|
val window = requireActivity().window
|
||||||
window.decorView.closeFullScreenMode(window)
|
window.decorView.closeFullScreenMode(window)
|
||||||
getCurrentWebView()?.requestLayout()
|
getCurrentWebView()?.requestLayout()
|
||||||
@ -2132,17 +1975,12 @@ abstract class CoreReaderFragment :
|
|||||||
|
|
||||||
private fun closeAllTabs() {
|
private fun closeAllTabs() {
|
||||||
onReadAloudStop()
|
onReadAloudStop()
|
||||||
closeAllTabsButton?.apply {
|
|
||||||
rotate()
|
|
||||||
setIsCloseAllTabButtonClickable(false)
|
|
||||||
}
|
|
||||||
tempZimSourceForUndo = zimReaderContainer?.zimReaderSource
|
tempZimSourceForUndo = zimReaderContainer?.zimReaderSource
|
||||||
tempWebViewListForUndo.apply {
|
tempWebViewListForUndo.apply {
|
||||||
clear()
|
clear()
|
||||||
addAll(webViewList)
|
addAll(webViewList)
|
||||||
}
|
}
|
||||||
webViewList.clear()
|
webViewList.clear()
|
||||||
tabsAdapter?.notifyDataSetChanged()
|
|
||||||
openHomeScreen()
|
openHomeScreen()
|
||||||
readerScreenState.value.snackBarHostState.snack(
|
readerScreenState.value.snackBarHostState.snack(
|
||||||
context?.getString(R.string.tabs_closed).orEmpty(),
|
context?.getString(R.string.tabs_closed).orEmpty(),
|
||||||
@ -2150,17 +1988,16 @@ abstract class CoreReaderFragment :
|
|||||||
actionClick = { restoreDeletedTabs() },
|
actionClick = { restoreDeletedTabs() },
|
||||||
lifecycleScope = lifecycleScope,
|
lifecycleScope = lifecycleScope,
|
||||||
snackBarResult = { result ->
|
snackBarResult = { result ->
|
||||||
if (result == SnackbarResult.Dismissed && webViewList.isEmpty() && isAdded) {
|
if (result == SnackbarResult.Dismissed && isAdded) {
|
||||||
closeZimBook()
|
saveTabStates()
|
||||||
|
if (webViewList.isEmpty()) {
|
||||||
|
closeZimBook()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setIsCloseAllTabButtonClickable(isClickable: Boolean) {
|
|
||||||
closeAllTabsButton?.isClickable = isClickable
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun restoreDeletedTabs() {
|
private fun restoreDeletedTabs() {
|
||||||
if (tempWebViewListForUndo.isNotEmpty()) {
|
if (tempWebViewListForUndo.isNotEmpty()) {
|
||||||
webViewList.addAll(tempWebViewListForUndo)
|
webViewList.addAll(tempWebViewListForUndo)
|
||||||
@ -2652,12 +2489,20 @@ abstract class CoreReaderFragment :
|
|||||||
isBackToTopEnabled = sharedPreferenceUtil?.prefBackToTop == true
|
isBackToTopEnabled = sharedPreferenceUtil?.prefBackToTop == true
|
||||||
isOpenNewTabInBackground = sharedPreferenceUtil?.prefNewTabBackground == true
|
isOpenNewTabInBackground = sharedPreferenceUtil?.prefNewTabBackground == true
|
||||||
if (!isBackToTopEnabled) {
|
if (!isBackToTopEnabled) {
|
||||||
backToTopButton?.hide()
|
hideBackToTopButton()
|
||||||
}
|
}
|
||||||
openFullScreenIfEnabled()
|
openFullScreenIfEnabled()
|
||||||
updateNightMode()
|
updateNightMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showBackToTopButton() {
|
||||||
|
readerScreenState.update { copy(showBackToTopButton = true) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideBackToTopButton() {
|
||||||
|
readerScreenState.update { copy(showBackToTopButton = false) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current state of tabs and web view history to persistent storage.
|
* Saves the current state of tabs and web view history to persistent storage.
|
||||||
*
|
*
|
||||||
@ -2869,28 +2714,18 @@ abstract class CoreReaderFragment :
|
|||||||
tabsAdapter?.notifyDataSetChanged()
|
tabsAdapter?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NestedBlockDepth", "MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
override fun webViewPageChanged(page: Int, maxPages: Int) {
|
override fun webViewPageChanged(page: Int, maxPages: Int) {
|
||||||
if (isBackToTopEnabled) {
|
if (!isBackToTopEnabled) return
|
||||||
hideBackToTopTimer?.apply {
|
hideBackToTopTimer?.apply {
|
||||||
cancel()
|
cancel()
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
getCurrentWebView()?.scrollY?.let {
|
val scrollY = getCurrentWebView()?.scrollY ?: return
|
||||||
if (it > 200) {
|
if (scrollY > 200 && !readerScreenState.value.showTtsControls) {
|
||||||
if (
|
showBackToTopButton()
|
||||||
(backToTopButton?.isGone == true || backToTopButton?.isInvisible == true) &&
|
} else {
|
||||||
ttsControls?.visibility == GONE
|
hideBackToTopButton()
|
||||||
) {
|
|
||||||
backToTopButton?.show()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
backToTopButton?.isVisible
|
|
||||||
if (backToTopButton?.visibility == VISIBLE) {
|
|
||||||
backToTopButton?.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import android.widget.FrameLayout
|
|||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@ -46,6 +47,7 @@ import androidx.compose.foundation.lazy.LazyRow
|
|||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.BottomAppBar
|
import androidx.compose.material3.BottomAppBar
|
||||||
import androidx.compose.material3.BottomAppBarDefaults
|
import androidx.compose.material3.BottomAppBarDefaults
|
||||||
@ -54,14 +56,16 @@ import androidx.compose.material3.Card
|
|||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.FloatingActionButtonDefaults
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.SmallFloatingActionButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
|
import androidx.compose.material3.minimumInteractiveComponentSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
@ -73,6 +77,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
@ -106,8 +111,10 @@ import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
|||||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem.Drawable
|
import org.kiwix.kiwixmobile.core.ui.models.IconItem.Drawable
|
||||||
import org.kiwix.kiwixmobile.core.ui.models.toPainter
|
import org.kiwix.kiwixmobile.core.ui.models.toPainter
|
||||||
import org.kiwix.kiwixmobile.core.ui.theme.Black
|
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.KiwixDialogTheme
|
||||||
import org.kiwix.kiwixmobile.core.ui.theme.White
|
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
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.CLOSE_ALL_TAB_BUTTON_BOTTOM_PADDING
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.CLOSE_TAB_ICON_ANIMATION_TIMEOUT
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.CLOSE_TAB_ICON_ANIMATION_TIMEOUT
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.CLOSE_TAB_ICON_SIZE
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.CLOSE_TAB_ICON_SIZE
|
||||||
@ -115,8 +122,11 @@ import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP
|
|||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FOUR_DP
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FOUR_DP
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.ONE_DP
|
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_BUTTON_ICON_SIZE
|
||||||
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.READER_BOTTOM_APP_BAR_DISABLE_BUTTON_ALPHA
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.READER_BOTTOM_APP_BAR_LAYOUT_HEIGHT
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.READER_BOTTOM_APP_BAR_LAYOUT_HEIGHT
|
||||||
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SEVEN_DP
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SIXTEEN_DP
|
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.TTS_BUTTONS_CONTROL_ALPHA
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TTS_BUTTONS_CONTROL_ALPHA
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TWO_DP
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.TWO_DP
|
||||||
import org.kiwix.kiwixmobile.core.utils.StyleUtils.fromHtml
|
import org.kiwix.kiwixmobile.core.utils.StyleUtils.fromHtml
|
||||||
@ -166,7 +176,7 @@ private fun ReaderTopBar(
|
|||||||
scrollBehavior: TopAppBarScrollBehavior,
|
scrollBehavior: TopAppBarScrollBehavior,
|
||||||
navigationIcon: @Composable () -> Unit,
|
navigationIcon: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
if (!state.fullScreenItem.first) {
|
if (!state.shouldShowFullScreenMode) {
|
||||||
KiwixAppBar(
|
KiwixAppBar(
|
||||||
title = if (state.showTabSwitcher) "" else state.readerScreenTitle,
|
title = if (state.showTabSwitcher) "" else state.readerScreenTitle,
|
||||||
navigationIcon = navigationIcon,
|
navigationIcon = navigationIcon,
|
||||||
@ -205,6 +215,10 @@ private fun ReaderContentLayout(state: ReaderScreenState, modifier: Modifier = M
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ShowFullScreenView(state)
|
ShowFullScreenView(state)
|
||||||
|
CloseFullScreenImageButton(
|
||||||
|
state.shouldShowFullScreenMode,
|
||||||
|
state.onExitFullscreenClick
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +226,29 @@ private fun ReaderContentLayout(state: ReaderScreenState, modifier: Modifier = M
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun BoxScope.CloseFullScreenImageButton(
|
||||||
|
shouldShowFullScreenMode: Boolean,
|
||||||
|
onExitFullScreen: () -> Unit
|
||||||
|
) {
|
||||||
|
if (shouldShowFullScreenMode) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onExitFullScreen,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.padding(SEVEN_DP)
|
||||||
|
.minimumInteractiveComponentSize()
|
||||||
|
.background(MaterialTheme.colorScheme.onSurface)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = IconItem.Drawable(R.drawable.fullscreen_exit).toPainter(),
|
||||||
|
contentDescription = stringResource(id = R.string.menu_exit_full_screen),
|
||||||
|
tint = MaterialTheme.colorScheme.surface
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ShowZIMFileContent(state: ReaderScreenState) {
|
private fun ShowZIMFileContent(state: ReaderScreenState) {
|
||||||
state.selectedWebView?.let { selectedWebView ->
|
state.selectedWebView?.let { selectedWebView ->
|
||||||
@ -303,12 +340,12 @@ private fun TtsControls(state: ReaderScreenState) {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun BackToTopFab(state: ReaderScreenState) {
|
private fun BackToTopFab(state: ReaderScreenState) {
|
||||||
if (state.showBackToTopButton) {
|
if (state.showBackToTopButton) {
|
||||||
FloatingActionButton(
|
SmallFloatingActionButton(
|
||||||
onClick = state.backToTopButtonClick,
|
onClick = state.backToTopButtonClick,
|
||||||
modifier = Modifier,
|
modifier = Modifier.padding(bottom = BACK_TO_TOP_BUTTON_BOTTOM_MARGIN),
|
||||||
containerColor = MaterialTheme.colorScheme.primary,
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
contentColor = MaterialTheme.colorScheme.onPrimary,
|
contentColor = MaterialTheme.colorScheme.onPrimary,
|
||||||
shape = FloatingActionButtonDefaults.smallShape
|
shape = CircleShape
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = Drawable(R.drawable.action_find_previous).toPainter(),
|
painter = Drawable(R.drawable.action_find_previous).toPainter(),
|
||||||
@ -389,15 +426,26 @@ private fun BottomAppBarButtonIcon(
|
|||||||
shouldEnable: Boolean = true,
|
shouldEnable: Boolean = true,
|
||||||
contentDescription: String
|
contentDescription: String
|
||||||
) {
|
) {
|
||||||
IconButton(
|
Box(
|
||||||
onClick = onClick,
|
modifier = Modifier
|
||||||
modifier = Modifier.combinedClickable(onClick = onClick, onLongClick = onLongClick),
|
.size(READER_BOTTOM_APP_BAR_BUTTON_ICON_SIZE + TEN_DP)
|
||||||
enabled = shouldEnable
|
.clip(CircleShape)
|
||||||
|
.combinedClickable(
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
enabled = shouldEnable
|
||||||
|
),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
buttonIcon.toPainter(),
|
buttonIcon.toPainter(),
|
||||||
contentDescription,
|
contentDescription,
|
||||||
modifier = Modifier.size(READER_BOTTOM_APP_BAR_BUTTON_ICON_SIZE)
|
modifier = Modifier.size(READER_BOTTOM_APP_BAR_BUTTON_ICON_SIZE),
|
||||||
|
tint = if (shouldEnable) {
|
||||||
|
LocalContentColor.current
|
||||||
|
} else {
|
||||||
|
LocalContentColor.current.copy(alpha = READER_BOTTOM_APP_BAR_DISABLE_BUTTON_ALPHA)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,6 +552,8 @@ private fun BoxScope.CloseAllTabButton(onCloseAllTabs: () -> Unit) {
|
|||||||
onCloseAllTabs()
|
onCloseAllTabs()
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
containerColor = DenimBlue800,
|
||||||
|
contentColor = White
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(
|
painter = painterResource(
|
||||||
|
@ -56,13 +56,17 @@ data class ReaderScreenState(
|
|||||||
*/
|
*/
|
||||||
val shouldShowDonationPopup: Boolean,
|
val shouldShowDonationPopup: Boolean,
|
||||||
/**
|
/**
|
||||||
* Manages the showing of "Full screen view".
|
* Manages the showing of "Full screen view" of webView's video.
|
||||||
*
|
*
|
||||||
* A [Pair] containing:
|
* A [Pair] containing:
|
||||||
* - [Boolean]: Whether to show/hide full screen mode.
|
* - [Boolean]: Whether to show/hide full screen mode.
|
||||||
* - [ComposeView]: full screen view.
|
* - [ComposeView]: full screen view.
|
||||||
*/
|
*/
|
||||||
val fullScreenItem: Pair<Boolean, ComposeView?>,
|
val fullScreenItem: Pair<Boolean, ComposeView?>,
|
||||||
|
/**
|
||||||
|
* Manages the showing of "Full screen mode".
|
||||||
|
*/
|
||||||
|
val shouldShowFullScreenMode: Boolean,
|
||||||
/**
|
/**
|
||||||
* Manages the showing of "BackToTop" fab button.
|
* Manages the showing of "BackToTop" fab button.
|
||||||
*/
|
*/
|
||||||
@ -71,7 +75,6 @@ data class ReaderScreenState(
|
|||||||
* Handles the click of "BackToTop" fab button.
|
* Handles the click of "BackToTop" fab button.
|
||||||
*/
|
*/
|
||||||
val backToTopButtonClick: () -> Unit,
|
val backToTopButtonClick: () -> Unit,
|
||||||
val showFullscreenButton: Boolean = false,
|
|
||||||
val onExitFullscreenClick: () -> Unit = {},
|
val onExitFullscreenClick: () -> Unit = {},
|
||||||
val showTtsControls: Boolean = false,
|
val showTtsControls: Boolean = false,
|
||||||
val onPauseTtsClick: () -> Unit = {},
|
val onPauseTtsClick: () -> Unit = {},
|
||||||
|
@ -1,73 +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.utils
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
|
||||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
import android.view.animation.LinearInterpolator
|
|
||||||
import androidx.core.animation.addListener
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
import org.kiwix.kiwixmobile.core.R
|
|
||||||
import org.kiwix.kiwixmobile.core.extensions.setImageDrawableCompat
|
|
||||||
|
|
||||||
private const val HEIGHT_ANIM_DURATION = 100L
|
|
||||||
private const val ROTATE_ANIM_DURATION = 200L
|
|
||||||
private const val FULL_ROTATION = 360.0f
|
|
||||||
|
|
||||||
object AnimationUtils {
|
|
||||||
@JvmStatic fun View.expand() {
|
|
||||||
measure(MATCH_PARENT, WRAP_CONTENT)
|
|
||||||
|
|
||||||
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
|
|
||||||
layoutParams.height = 1
|
|
||||||
visibility = View.VISIBLE
|
|
||||||
|
|
||||||
animateHeight(1, measuredHeight) {
|
|
||||||
layoutParams.height = WRAP_CONTENT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic fun View.collapse() {
|
|
||||||
animateHeight(measuredHeight, 0) { visibility = View.GONE }
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("Recycle")
|
|
||||||
private fun View.animateHeight(start: Int, end: Int, onEndAction: () -> Unit) {
|
|
||||||
ValueAnimator.ofInt(start, end).apply {
|
|
||||||
addUpdateListener {
|
|
||||||
layoutParams.height = it.animatedValue as Int
|
|
||||||
requestLayout()
|
|
||||||
}
|
|
||||||
addListener(onEnd = { onEndAction.invoke() })
|
|
||||||
duration = HEIGHT_ANIM_DURATION
|
|
||||||
interpolator = LinearInterpolator()
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic fun FloatingActionButton.rotate() {
|
|
||||||
animate().apply {
|
|
||||||
withStartAction { setImageDrawableCompat(R.drawable.ic_close_black_24dp) }
|
|
||||||
withEndAction { setImageDrawableCompat(R.drawable.ic_done_white_24dp) }
|
|
||||||
rotationBy(FULL_ROTATION)
|
|
||||||
duration = ROTATE_ANIM_DURATION
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,6 +48,7 @@ object ComposeDimens {
|
|||||||
val TWELVE_DP = 12.dp
|
val TWELVE_DP = 12.dp
|
||||||
val TEN_DP = 10.dp
|
val TEN_DP = 10.dp
|
||||||
val EIGHT_DP = 8.dp
|
val EIGHT_DP = 8.dp
|
||||||
|
val SEVEN_DP = 7.dp
|
||||||
val SIX_DP = 6.dp
|
val SIX_DP = 6.dp
|
||||||
val FIVE_DP = 5.dp
|
val FIVE_DP = 5.dp
|
||||||
val FOUR_DP = 4.dp
|
val FOUR_DP = 4.dp
|
||||||
@ -189,4 +190,6 @@ object ComposeDimens {
|
|||||||
const val TAB_SWITCHER_ICON_CORNER_RADIUS = 10
|
const val TAB_SWITCHER_ICON_CORNER_RADIUS = 10
|
||||||
val CLOSE_TAB_ICON_SIZE = 20.dp
|
val CLOSE_TAB_ICON_SIZE = 20.dp
|
||||||
const val CLOSE_TAB_ICON_ANIMATION_TIMEOUT = 1200L
|
const val CLOSE_TAB_ICON_ANIMATION_TIMEOUT = 1200L
|
||||||
|
val BACK_TO_TOP_BUTTON_BOTTOM_MARGIN = 80.dp
|
||||||
|
const val READER_BOTTOM_APP_BAR_DISABLE_BUTTON_ALPHA = 0.38f
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user