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