mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
Introduced route-based navigation to pass arguments to fragments. * Removed some unused files. * Fixed: all library controls for navigation (e.g., sharing files, navigating to downloads, etc.).
* Fixed: Open library button not working. * Fixed: opening ZIM file from storage (using the plus button) had too much bottom margin after migrating MainActivity to Compose. * Added support for automatically hiding and showing the BottomAppBar while scrolling, using the Compose approach. * Many other improvements in UI and logics. * Show or hide the BottomAppBar when full screen mode is enabled/disabled or when tabs are visible. * Disable the left drawer when opening full screen mode, tabs, etc.
This commit is contained in:
parent
edae60fa52
commit
877c4a7166
@ -22,11 +22,13 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.NavOptions
|
||||
import org.kiwix.kiwixmobile.cachedComponent
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||
import javax.inject.Inject
|
||||
|
||||
class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtensions {
|
||||
@ -58,7 +60,10 @@ class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtens
|
||||
|
||||
private fun navigateToLibrary() {
|
||||
presenter.setIntroShown()
|
||||
findNavController().navigate(IntroFragmentDirections.actionIntrofragmentToLibraryFragment())
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Intro.route, inclusive = true)
|
||||
.build()
|
||||
(requireActivity() as CoreMainActivity).navigate(KiwixDestination.Library.route, navOptions)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -28,18 +28,22 @@ import android.view.MenuItem
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.compose.material3.BottomAppBarDefaults
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import eu.mhutti1.utils.storage.StorageDevice
|
||||
import eu.mhutti1.utils.storage.StorageDeviceUtils
|
||||
import kotlinx.coroutines.delay
|
||||
@ -59,9 +63,9 @@ import org.kiwix.kiwixmobile.core.main.ACTION_NEW_TAB
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.main.DrawerMenuItem
|
||||
import org.kiwix.kiwixmobile.core.main.NEW_TAB_SHORTCUT_ID
|
||||
import org.kiwix.kiwixmobile.core.main.ZIM_FILE_URI_KEY
|
||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.DialogHost
|
||||
import org.kiwix.kiwixmobile.kiwixActivityComponent
|
||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||
import javax.inject.Inject
|
||||
@ -106,6 +110,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
KiwixDestination.Reader.route
|
||||
)
|
||||
|
||||
private val shouldShowBottomAppBar = mutableStateOf(true)
|
||||
// private lateinit var activityKiwixMainBinding: ActivityKiwixMainBinding
|
||||
|
||||
private var isIntroScreenVisible: Boolean = false
|
||||
@ -116,6 +121,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
}
|
||||
private val storageDeviceList = arrayListOf<StorageDevice>()
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
cachedComponent.inject(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -123,17 +129,27 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
navController = rememberNavController()
|
||||
leftDrawerState = rememberDrawerState(DrawerValue.Closed)
|
||||
uiCoroutineScope = rememberCoroutineScope()
|
||||
bottomAppBarScrollBehaviour = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||
KiwixMainActivityScreen(
|
||||
navController = navController,
|
||||
leftDrawerContent = leftDrawerMenu,
|
||||
topLevelDestinationsRoute = topLevelDestinationsRoute,
|
||||
leftDrawerState = leftDrawerState,
|
||||
uiCoroutineScope = uiCoroutineScope,
|
||||
enableLeftDrawer = enableLeftDrawer.value
|
||||
enableLeftDrawer = enableLeftDrawer.value,
|
||||
shouldShowBottomAppBar = shouldShowBottomAppBar.value,
|
||||
bottomAppBarScrollBehaviour = bottomAppBarScrollBehaviour
|
||||
)
|
||||
LaunchedEffect(navController) {
|
||||
navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange)
|
||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Reader.route, inclusive = true)
|
||||
.build()
|
||||
navigate(KiwixDestination.Intro.route, navOptions)
|
||||
}
|
||||
}
|
||||
DialogHost(alertDialogShower)
|
||||
}
|
||||
// activityKiwixMainBinding.drawerNavView.apply {
|
||||
// setupWithNavController(navController)
|
||||
@ -191,34 +207,12 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
||||
// navigate(KiwixReaderFragmentDirections.actionReaderFragmentToIntroFragment())
|
||||
}
|
||||
if (!sharedPreferenceUtil.prefIsTest) {
|
||||
sharedPreferenceUtil.setIsPlayStoreBuildType(BuildConfig.IS_PLAYSTORE)
|
||||
}
|
||||
setDefaultDeviceLanguage()
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for manually showing/hiding the BottomNavigationView with animation from compose
|
||||
* screens until we migrate the BottomNavigationView to compose. Once we migrate we will remove it.
|
||||
*
|
||||
* TODO Remove this once we migrate to compose.
|
||||
*/
|
||||
override fun toggleBottomNavigation(isVisible: Boolean) {
|
||||
// activityKiwixMainBinding.bottomNavView.animate()
|
||||
// ?.translationY(
|
||||
// if (isVisible) {
|
||||
// ZERO.toFloat()
|
||||
// } else {
|
||||
// activityKiwixMainBinding.bottomNavView.height.toFloat()
|
||||
// }
|
||||
// )
|
||||
// ?.setDuration(KIWIX_BOTTOM_BAR_ANIMATION_DURATION)
|
||||
// ?.start()
|
||||
}
|
||||
|
||||
private fun setDefaultDeviceLanguage() {
|
||||
if (sharedPreferenceUtil.prefDeviceDefaultLanguage.isEmpty()) {
|
||||
ConfigurationCompat.getLocales(
|
||||
@ -256,9 +250,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
|
||||
private fun handleGetContentIntent(intent: Intent?) {
|
||||
if (intent?.action == ACTION_GET_CONTENT) {
|
||||
// activityKiwixMainBinding.bottomNavView.menu.findItem(R.id.downloadsFragment)?.let {
|
||||
// NavigationUI.onNavDestinationSelected(it, navController)
|
||||
// }
|
||||
navigate(KiwixDestination.Downloads.route)
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,12 +278,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
}
|
||||
|
||||
private fun openLocalLibraryWithZimFilePath(path: String) {
|
||||
navigate(
|
||||
R.id.libraryFragment,
|
||||
bundleOf(
|
||||
ZIM_FILE_URI_KEY to path,
|
||||
)
|
||||
)
|
||||
navigate(KiwixDestination.Library.createRoute(zimFileUri = path))
|
||||
}
|
||||
|
||||
private fun handleNotificationIntent(intent: Intent) {
|
||||
@ -307,6 +294,10 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun openZimFromFilePath(path: String) {
|
||||
navigate(KiwixDestination.Reader.createRoute(zimFileUri = path))
|
||||
}
|
||||
|
||||
override fun onNavigationItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
id.menu_host_books -> openZimHostFragment()
|
||||
@ -359,6 +350,24 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
// activityKiwixMainBinding.root.addView(getDialogHostComposeView(alertDialogShower), 0)
|
||||
}
|
||||
|
||||
override fun openSearch(searchString: String, isOpenedFromTabView: Boolean, isVoice: Boolean) {
|
||||
navigate(
|
||||
KiwixDestination.Search.createRoute(
|
||||
searchString = searchString,
|
||||
isOpenedFromTabView = isOpenedFromTabView,
|
||||
isVoice = isVoice
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun hideBottomAppBar() {
|
||||
shouldShowBottomAppBar.value = false
|
||||
}
|
||||
|
||||
override fun showBottomAppBar() {
|
||||
shouldShowBottomAppBar.value = true
|
||||
}
|
||||
|
||||
// Outdated shortcut ids(new_tab, get_content)
|
||||
// Remove if the application has the outdated shortcuts.
|
||||
private fun removeOutdatedIdShortcuts() {
|
||||
|
@ -60,10 +60,11 @@ fun KiwixMainActivityScreen(
|
||||
topLevelDestinationsRoute: Set<String>,
|
||||
leftDrawerState: DrawerState,
|
||||
uiCoroutineScope: CoroutineScope,
|
||||
enableLeftDrawer: Boolean
|
||||
enableLeftDrawer: Boolean,
|
||||
shouldShowBottomAppBar: Boolean,
|
||||
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior
|
||||
) {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val scrollingBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||
KiwixTheme {
|
||||
ModalNavigationDrawer(
|
||||
drawerState = leftDrawerState,
|
||||
@ -77,16 +78,17 @@ fun KiwixMainActivityScreen(
|
||||
Box {
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
if (navBackStackEntry?.destination?.route in topLevelDestinationsRoute) {
|
||||
if (navBackStackEntry?.destination?.route in topLevelDestinationsRoute && shouldShowBottomAppBar) {
|
||||
BottomNavigationBar(
|
||||
navController = navController,
|
||||
scrollBehavior = scrollingBehavior,
|
||||
bottomAppBarScrollBehaviour = bottomAppBarScrollBehaviour,
|
||||
navBackStackEntry = navBackStackEntry,
|
||||
leftDrawerState = leftDrawerState,
|
||||
uiCoroutineScope = uiCoroutineScope
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) { paddingValues ->
|
||||
Box(modifier = Modifier.padding(paddingValues)) {
|
||||
KiwixNavGraph(
|
||||
@ -104,7 +106,7 @@ fun KiwixMainActivityScreen(
|
||||
@Composable
|
||||
fun BottomNavigationBar(
|
||||
navController: NavHostController,
|
||||
scrollBehavior: BottomAppBarScrollBehavior,
|
||||
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior,
|
||||
navBackStackEntry: NavBackStackEntry?,
|
||||
leftDrawerState: DrawerState,
|
||||
uiCoroutineScope: CoroutineScope
|
||||
@ -130,12 +132,14 @@ fun BottomNavigationBar(
|
||||
BottomAppBar(
|
||||
containerColor = Black,
|
||||
contentColor = White,
|
||||
scrollBehavior = scrollBehavior
|
||||
scrollBehavior = bottomAppBarScrollBehaviour
|
||||
) {
|
||||
bottomNavItems.forEach { item ->
|
||||
NavigationBarItem(
|
||||
selected = currentDestinationRoute == item.route,
|
||||
onClick = {
|
||||
// Do not load again fragment that is already loaded.
|
||||
if (item.route == currentDestinationRoute) return@NavigationBarItem
|
||||
uiCoroutineScope.launch {
|
||||
leftDrawerState.close()
|
||||
navController.navigate(item.route)
|
||||
|
@ -39,6 +39,7 @@ import androidx.appcompat.view.ActionMode
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -51,6 +52,7 @@ import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavOptions
|
||||
import eu.mhutti1.utils.storage.Bytes
|
||||
import eu.mhutti1.utils.storage.StorageDevice
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
@ -78,7 +80,6 @@ import org.kiwix.kiwixmobile.core.navigateToSettings
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
|
||||
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
||||
import org.kiwix.kiwixmobile.core.ui.components.rememberBottomNavigationVisibility
|
||||
import org.kiwix.kiwixmobile.core.ui.models.ActionMenuItem
|
||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||
import org.kiwix.kiwixmobile.core.utils.EXTERNAL_SELECT_POSITION
|
||||
@ -173,6 +174,7 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
baseActivity.cachedComponent.inject(this)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@ -183,10 +185,6 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
val lazyListState = rememberLazyListState()
|
||||
val isBottomNavVisible = rememberBottomNavigationVisibility(lazyListState)
|
||||
LaunchedEffect(isBottomNavVisible) {
|
||||
(requireActivity() as KiwixMainActivity).toggleBottomNavigation(isBottomNavVisible)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
updateLibraryScreenState(
|
||||
bottomNavigationHeight = getBottomNavigationHeight(),
|
||||
@ -202,6 +200,7 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
onMultiSelect = { offerAction(RequestSelect(it)) },
|
||||
onRefresh = { onSwipeRefresh() },
|
||||
onDownloadButtonClick = { downloadBookButtonClick() },
|
||||
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour
|
||||
) {
|
||||
NavigationIcon(
|
||||
iconItem = IconItem.Vector(Icons.Filled.Menu),
|
||||
@ -493,9 +492,12 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
zimFileReader.dispose()
|
||||
}
|
||||
}
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Reader.route, false)
|
||||
.build()
|
||||
activity?.navigate(
|
||||
LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationReader()
|
||||
.apply { zimFileUri = file.toUri().toString() }
|
||||
KiwixDestination.Reader.createRoute(zimFileUri = file.toUri().toString()),
|
||||
navOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.BottomAppBarScrollBehavior
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
@ -49,7 +50,6 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import org.kiwix.kiwixmobile.R.string
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.main.reader.CONTENT_LOADING_PROGRESSBAR_TESTING_TAG
|
||||
import org.kiwix.kiwixmobile.core.main.reader.rememberScrollBehavior
|
||||
import org.kiwix.kiwixmobile.core.ui.components.ContentLoadingProgressBar
|
||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar
|
||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixButton
|
||||
@ -60,7 +60,6 @@ import org.kiwix.kiwixmobile.core.ui.theme.Black
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.KiwixTheme
|
||||
import org.kiwix.kiwixmobile.core.ui.theme.White
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FAB_ICON_BOTTOM_MARGIN
|
||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.FOUR_DP
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk
|
||||
@ -85,10 +84,9 @@ fun LocalLibraryScreen(
|
||||
onClick: ((BookOnDisk) -> Unit)? = null,
|
||||
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
||||
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
||||
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior,
|
||||
navigationIcon: @Composable () -> Unit
|
||||
) {
|
||||
val (bottomNavHeight, lazyListState) =
|
||||
rememberScrollBehavior(state.bottomNavigationHeight, listState)
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
KiwixTheme {
|
||||
Scaffold(
|
||||
@ -105,7 +103,7 @@ fun LocalLibraryScreen(
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.padding(bottom = bottomNavHeight.value)
|
||||
.nestedScroll(bottomAppBarScrollBehaviour.nestedScrollConnection)
|
||||
) { contentPadding ->
|
||||
SwipeRefreshLayout(
|
||||
isRefreshing = state.swipeRefreshItem.first,
|
||||
@ -130,7 +128,7 @@ fun LocalLibraryScreen(
|
||||
onClick,
|
||||
onLongClick,
|
||||
onMultiSelect,
|
||||
lazyListState
|
||||
listState
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -178,7 +176,6 @@ private fun SelectFileButton(fabButtonClick: () -> Unit) {
|
||||
FloatingActionButton(
|
||||
onClick = fabButtonClick,
|
||||
modifier = Modifier
|
||||
.padding(bottom = FAB_ICON_BOTTOM_MARGIN)
|
||||
.testTag(SELECT_FILE_BUTTON_TESTING_TAG),
|
||||
containerColor = Black,
|
||||
shape = MaterialTheme.shapes.extraLarge
|
||||
|
@ -34,6 +34,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -75,7 +76,6 @@ import org.kiwix.kiwixmobile.core.navigateToSettings
|
||||
import org.kiwix.kiwixmobile.core.page.SEARCH_ICON_TESTING_TAG
|
||||
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
||||
import org.kiwix.kiwixmobile.core.ui.components.ONE
|
||||
import org.kiwix.kiwixmobile.core.ui.components.rememberBottomNavigationVisibility
|
||||
import org.kiwix.kiwixmobile.core.ui.models.ActionMenuItem
|
||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||
@ -244,14 +244,11 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
composeView?.setContent {
|
||||
val lazyListState = rememberLazyListState()
|
||||
val isBottomNavVisible = rememberBottomNavigationVisibility(lazyListState)
|
||||
LaunchedEffect(isBottomNavVisible) {
|
||||
(requireActivity() as KiwixMainActivity).toggleBottomNavigation(isBottomNavVisible)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
onlineLibraryScreenState.value.update {
|
||||
copy(
|
||||
@ -273,7 +270,8 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
contentDescription = string.open_drawer,
|
||||
onClick = { navigationIconClick(onlineLibraryScreenState.value.value.isSearchActive) }
|
||||
)
|
||||
}
|
||||
},
|
||||
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour
|
||||
)
|
||||
DialogHost(alertDialogShower)
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.BottomAppBarScrollBehavior
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
@ -61,7 +62,6 @@ import org.kiwix.kiwixmobile.core.R.string
|
||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.FIVE
|
||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
||||
import org.kiwix.kiwixmobile.core.extensions.hideKeyboardOnLazyColumnScroll
|
||||
import org.kiwix.kiwixmobile.core.main.reader.rememberScrollBehavior
|
||||
import org.kiwix.kiwixmobile.core.ui.components.ContentLoadingProgressBar
|
||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar
|
||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixSearchView
|
||||
@ -98,10 +98,9 @@ fun OnlineLibraryScreen(
|
||||
state: OnlineLibraryScreenState,
|
||||
actionMenuItems: List<ActionMenuItem>,
|
||||
listState: LazyListState,
|
||||
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior,
|
||||
navigationIcon: @Composable () -> Unit,
|
||||
) {
|
||||
val (bottomNavHeight, lazyListState) =
|
||||
rememberScrollBehavior(state.bottomNavigationHeight, listState)
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
|
||||
KiwixTheme {
|
||||
@ -118,7 +117,7 @@ fun OnlineLibraryScreen(
|
||||
},
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.padding(bottom = bottomNavHeight.value)
|
||||
.nestedScroll(bottomAppBarScrollBehaviour.nestedScrollConnection)
|
||||
) { paddingValues ->
|
||||
SwipeRefreshLayout(
|
||||
isRefreshing = state.isRefreshing && !state.scanningProgressItem.first,
|
||||
@ -132,7 +131,7 @@ fun OnlineLibraryScreen(
|
||||
end = paddingValues.calculateEndPadding(LocalLayoutDirection.current),
|
||||
)
|
||||
) {
|
||||
OnlineLibraryScreenContent(state, lazyListState)
|
||||
OnlineLibraryScreenContent(state, listState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.net.toUri
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavOptions
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import kotlinx.coroutines.launch
|
||||
import org.kiwix.kiwixmobile.cachedComponent
|
||||
@ -55,6 +56,7 @@ import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE
|
||||
import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
|
||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||
import org.kiwix.kiwixmobile.core.utils.files.Log
|
||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||
import java.io.File
|
||||
|
||||
class KiwixReaderFragment : CoreReaderFragment() {
|
||||
@ -70,9 +72,10 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
val activity = activity as CoreMainActivity
|
||||
readerScreenState.update {
|
||||
copy(onOpenLibraryButtonClicked = {
|
||||
activity.navigate(
|
||||
KiwixReaderFragmentDirections.actionNavigationReaderToNavigationLibrary()
|
||||
)
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Reader.route, inclusive = true)
|
||||
.build()
|
||||
activity.navigate(KiwixDestination.Library.route, navOptions)
|
||||
})
|
||||
}
|
||||
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
@ -18,26 +18,52 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.ui
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.doOnAttach
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentContainerView
|
||||
import androidx.fragment.app.commit
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.navArgument
|
||||
import org.kiwix.kiwixmobile.core.main.BOOKMARK_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.DOWNLOAD_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING
|
||||
import org.kiwix.kiwixmobile.core.main.HELP_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.HISTORY_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.INTRO_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.LANGUAGE_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.LOCAL_FILE_TRANSFER_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.LOCAL_LIBRARY_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.NOTES_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.PAGE_URL_KEY
|
||||
import org.kiwix.kiwixmobile.core.main.READER_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.SEARCH_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.SETTINGS_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.SHOULD_OPEN_IN_NEW_TAB
|
||||
import org.kiwix.kiwixmobile.core.main.ZIM_FILE_URI_KEY
|
||||
import org.kiwix.kiwixmobile.core.main.ZIM_HOST_FRAGMENT
|
||||
import org.kiwix.kiwixmobile.core.main.reader.SEARCH_ITEM_TITLE_KEY
|
||||
import org.kiwix.kiwixmobile.core.page.bookmark.BookmarksFragment
|
||||
import org.kiwix.kiwixmobile.core.page.history.HistoryFragment
|
||||
import org.kiwix.kiwixmobile.core.page.notes.NotesFragment
|
||||
import org.kiwix.kiwixmobile.core.search.NAV_ARG_SEARCH_STRING
|
||||
import org.kiwix.kiwixmobile.core.search.SearchFragment
|
||||
import org.kiwix.kiwixmobile.core.utils.EXTRA_IS_WIDGET_VOICE
|
||||
import org.kiwix.kiwixmobile.core.utils.TAG_FROM_TAB_SWITCHER
|
||||
import org.kiwix.kiwixmobile.help.KiwixHelpFragment
|
||||
import org.kiwix.kiwixmobile.intro.IntroFragment
|
||||
import org.kiwix.kiwixmobile.language.LanguageFragment
|
||||
@ -58,24 +84,47 @@ fun KiwixNavGraph(
|
||||
startDestination = KiwixDestination.Reader.route,
|
||||
modifier = modifier
|
||||
) {
|
||||
composable(KiwixDestination.Reader.route) {
|
||||
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 = "" }
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val zimFileUri = backStackEntry.arguments?.getString(ZIM_FILE_URI_KEY).orEmpty()
|
||||
val findInPageSearchString =
|
||||
backStackEntry.arguments?.getString(FIND_IN_PAGE_SEARCH_STRING).orEmpty()
|
||||
val pageUrl = backStackEntry.arguments?.getString(PAGE_URL_KEY).orEmpty()
|
||||
val shouldOpenInNewTab = backStackEntry.arguments?.getBoolean(SHOULD_OPEN_IN_NEW_TAB) ?: false
|
||||
val searchItemTitle = backStackEntry.arguments?.getString(SEARCH_ITEM_TITLE_KEY).orEmpty()
|
||||
|
||||
FragmentContainer {
|
||||
KiwixReaderFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString("zimFileUri", "")
|
||||
putString("findInPageSearchString", "")
|
||||
putString("pageUrl", "")
|
||||
putBoolean("shouldOpenInNewTab", false)
|
||||
putString("searchItemTitle", "")
|
||||
putString(ZIM_FILE_URI_KEY, zimFileUri)
|
||||
putString(FIND_IN_PAGE_SEARCH_STRING, findInPageSearchString)
|
||||
putString(PAGE_URL_KEY, pageUrl)
|
||||
putBoolean(SHOULD_OPEN_IN_NEW_TAB, shouldOpenInNewTab)
|
||||
putString(SEARCH_ITEM_TITLE_KEY, searchItemTitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
composable(KiwixDestination.Library.route) {
|
||||
composable(
|
||||
route = KiwixDestination.Library.route,
|
||||
arguments = listOf(
|
||||
navArgument(ZIM_FILE_URI_KEY) { type = NavType.StringType; defaultValue = "" }
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val zimFileUri = backStackEntry.arguments?.getString(ZIM_FILE_URI_KEY).orEmpty()
|
||||
|
||||
FragmentContainer {
|
||||
LocalLibraryFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString("zimFileUri", "")
|
||||
putString(ZIM_FILE_URI_KEY, zimFileUri)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,16 +174,51 @@ fun KiwixNavGraph(
|
||||
KiwixSettingsFragment()
|
||||
}
|
||||
}
|
||||
composable(KiwixDestination.Search.route) {
|
||||
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 }
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val searchString = backStackEntry.arguments?.getString(NAV_ARG_SEARCH_STRING).orEmpty()
|
||||
val isOpenedFromTabSwitcher =
|
||||
backStackEntry.arguments?.getBoolean(TAG_FROM_TAB_SWITCHER) ?: false
|
||||
val isVoice = backStackEntry.arguments?.getBoolean(EXTRA_IS_WIDGET_VOICE) ?: false
|
||||
FragmentContainer {
|
||||
SearchFragment()
|
||||
SearchFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(NAV_ARG_SEARCH_STRING, searchString)
|
||||
putBoolean(TAG_FROM_TAB_SWITCHER, isOpenedFromTabSwitcher)
|
||||
putBoolean(EXTRA_IS_WIDGET_VOICE, isVoice)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
composable(KiwixDestination.LocalFileTransfer.route) {
|
||||
composable(
|
||||
route = KiwixDestination.LocalFileTransfer.route,
|
||||
arguments = listOf(
|
||||
navArgument("uris") {
|
||||
type = NavType.StringType
|
||||
nullable = true
|
||||
defaultValue = null
|
||||
}
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val urisParam = backStackEntry.arguments?.getString("uris")
|
||||
val uris: List<Uri>? =
|
||||
urisParam?.takeIf { it != "null" }?.split(",")?.map {
|
||||
Uri.decode(it).toUri()
|
||||
}
|
||||
|
||||
FragmentContainer {
|
||||
LocalFileTransferFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelableArray("uris", null)
|
||||
putParcelableArray(
|
||||
"uris",
|
||||
uris?.toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,6 +226,7 @@ fun KiwixNavGraph(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun FragmentContainer(
|
||||
fragmentProvider: () -> Fragment
|
||||
@ -170,17 +255,72 @@ fun FragmentContainer(
|
||||
}
|
||||
|
||||
sealed class KiwixDestination(val route: String) {
|
||||
object Reader : KiwixDestination("readerFragment")
|
||||
object Library : KiwixDestination("libraryFragment")
|
||||
object Downloads : KiwixDestination("downloadsFragment")
|
||||
object Bookmarks : KiwixDestination("bookmarksFragment")
|
||||
object Notes : KiwixDestination("notesFragment")
|
||||
object Intro : KiwixDestination("introFragment")
|
||||
object History : KiwixDestination("historyFragment")
|
||||
object Language : KiwixDestination("languageFragment")
|
||||
object ZimHost : KiwixDestination("zimHostFragment")
|
||||
object Help : KiwixDestination("helpFragment")
|
||||
object Settings : KiwixDestination("kiwixSettingsFragment")
|
||||
object Search : KiwixDestination("searchFragment")
|
||||
object LocalFileTransfer : KiwixDestination("localFileTransferFragment")
|
||||
object Reader : KiwixDestination(
|
||||
READER_FRAGMENT +
|
||||
"?$ZIM_FILE_URI_KEY={$ZIM_FILE_URI_KEY}" +
|
||||
"&$FIND_IN_PAGE_SEARCH_STRING={$FIND_IN_PAGE_SEARCH_STRING}" +
|
||||
"&$PAGE_URL_KEY={$PAGE_URL_KEY}" +
|
||||
"&$SHOULD_OPEN_IN_NEW_TAB={$SHOULD_OPEN_IN_NEW_TAB}" +
|
||||
"&$SEARCH_ITEM_TITLE_KEY={$SEARCH_ITEM_TITLE_KEY}"
|
||||
) {
|
||||
fun createRoute(
|
||||
zimFileUri: String = "",
|
||||
findInPageSearchString: String = "",
|
||||
pageUrl: String = "",
|
||||
shouldOpenInNewTab: Boolean = false,
|
||||
searchItemTitle: String = ""
|
||||
): String {
|
||||
return READER_FRAGMENT +
|
||||
"?$ZIM_FILE_URI_KEY=${Uri.encode(zimFileUri)}" +
|
||||
"&$FIND_IN_PAGE_SEARCH_STRING=${Uri.encode(findInPageSearchString)}" +
|
||||
"&$PAGE_URL_KEY=${Uri.encode(pageUrl)}" +
|
||||
"&$SHOULD_OPEN_IN_NEW_TAB=$shouldOpenInNewTab" +
|
||||
"&$SEARCH_ITEM_TITLE_KEY=${Uri.encode(searchItemTitle)}"
|
||||
}
|
||||
}
|
||||
|
||||
object Library :
|
||||
KiwixDestination("$LOCAL_LIBRARY_FRAGMENT?$ZIM_FILE_URI_KEY={$ZIM_FILE_URI_KEY}") {
|
||||
fun createRoute(zimFileUri: String = "") =
|
||||
"$LOCAL_LIBRARY_FRAGMENT?$ZIM_FILE_URI_KEY=${Uri.encode(zimFileUri)}"
|
||||
}
|
||||
|
||||
object Downloads : KiwixDestination(DOWNLOAD_FRAGMENT)
|
||||
object Bookmarks : KiwixDestination(BOOKMARK_FRAGMENT)
|
||||
object Notes : KiwixDestination(NOTES_FRAGMENT)
|
||||
object Intro : KiwixDestination(INTRO_FRAGMENT)
|
||||
object History : KiwixDestination(HISTORY_FRAGMENT)
|
||||
object Language : KiwixDestination(LANGUAGE_FRAGMENT)
|
||||
object ZimHost : KiwixDestination(ZIM_HOST_FRAGMENT)
|
||||
object Help : KiwixDestination(HELP_FRAGMENT)
|
||||
object Settings : KiwixDestination(SETTINGS_FRAGMENT)
|
||||
object Search : KiwixDestination(
|
||||
SEARCH_FRAGMENT +
|
||||
"?$NAV_ARG_SEARCH_STRING={$NAV_ARG_SEARCH_STRING}" +
|
||||
"&$TAG_FROM_TAB_SWITCHER={$TAG_FROM_TAB_SWITCHER}" +
|
||||
"&$EXTRA_IS_WIDGET_VOICE={$EXTRA_IS_WIDGET_VOICE}"
|
||||
) {
|
||||
fun createRoute(
|
||||
searchString: String = "",
|
||||
isOpenedFromTabView: Boolean = false,
|
||||
isVoice: Boolean = false
|
||||
): String {
|
||||
return SEARCH_FRAGMENT +
|
||||
"?$NAV_ARG_SEARCH_STRING=$searchString" +
|
||||
"&$TAG_FROM_TAB_SWITCHER=$isOpenedFromTabView" +
|
||||
"&$EXTRA_IS_WIDGET_VOICE=$isVoice"
|
||||
}
|
||||
}
|
||||
|
||||
object LocalFileTransfer : KiwixDestination("$LOCAL_FILE_TRANSFER_FRAGMENT?uris={uris}") {
|
||||
fun createRoute(uris: String? = null): String {
|
||||
return if (uris != null)
|
||||
"$LOCAL_FILE_TRANSFER_FRAGMENT?uris=${Uri.encode(uris)}"
|
||||
else
|
||||
"$LOCAL_FILE_TRANSFER_FRAGMENT?uris=null"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun List<Uri>.toUriParam(): String =
|
||||
joinToString(",") { Uri.encode(it.toString()) }
|
||||
|
@ -19,12 +19,17 @@
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.NavOptions
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
||||
import org.kiwix.kiwixmobile.nav.destination.library.local.LocalLibraryFragmentDirections
|
||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||
|
||||
object NavigateToDownloads : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
activity.navigate(LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationDownloads())
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Library.route, inclusive = true)
|
||||
.setRestoreState(true)
|
||||
.build()
|
||||
activity.navigate(KiwixDestination.Downloads.route, navOptions)
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavOptions
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -28,7 +29,7 @@ import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
import org.kiwix.kiwixmobile.nav.destination.library.local.LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationReader
|
||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||
|
||||
@Suppress("InjectDispatcher")
|
||||
data class OpenFileWithNavigation(private val bookOnDisk: BooksOnDiskListItem.BookOnDisk) :
|
||||
@ -45,10 +46,12 @@ data class OpenFileWithNavigation(private val bookOnDisk: BooksOnDiskListItem.Bo
|
||||
activity.getString(R.string.error_file_not_found, zimReaderSource.toDatabase())
|
||||
)
|
||||
} else {
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(KiwixDestination.Library.route, inclusive = false)
|
||||
.build()
|
||||
activity.navigate(
|
||||
actionNavigationLibraryToNavigationReader().apply {
|
||||
zimFileUri = zimReaderSource.toDatabase()
|
||||
}
|
||||
KiwixDestination.Reader.createRoute(zimFileUri = zimReaderSource.toDatabase()),
|
||||
navOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,11 @@
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.localFileTransfer.URIS_KEY
|
||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||
import org.kiwix.kiwixmobile.ui.toUriParam
|
||||
|
||||
data class ShareFiles(private val selectedBooks: List<BookOnDisk>) :
|
||||
SideEffect<Unit> {
|
||||
@ -34,8 +33,7 @@ data class ShareFiles(private val selectedBooks: List<BookOnDisk>) :
|
||||
it.zimReaderSource.getUri(activity)
|
||||
}
|
||||
activity.navigate(
|
||||
R.id.localFileTransferFragment,
|
||||
bundleOf(URIS_KEY to selectedFileContentURIs.toTypedArray())
|
||||
KiwixDestination.LocalFileTransfer.createRoute(uris = selectedFileContentURIs.toUriParam())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
@ -41,7 +40,7 @@ import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import androidx.navigation.NavDirections
|
||||
import androidx.navigation.NavOptions
|
||||
import org.kiwix.kiwixmobile.core.di.components.CoreActivityComponent
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.utils.REQUEST_POST_NOTIFICATION_PERMISSION
|
||||
@ -93,22 +92,14 @@ object ActivityExtensions {
|
||||
ViewModelProviders.of(this, viewModelFactory)
|
||||
.get(T::class.java)
|
||||
|
||||
fun Activity.navigate(action: NavDirections) {
|
||||
coreMainActivity.navigate(action)
|
||||
}
|
||||
|
||||
val Activity.cachedComponent: CoreActivityComponent
|
||||
get() = coreMainActivity.cachedComponent
|
||||
|
||||
fun Activity.setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) =
|
||||
coreMainActivity.setupDrawerToggle(shouldEnableRightDrawer)
|
||||
|
||||
fun Activity.navigate(route: String) {
|
||||
coreMainActivity.navigate(route)
|
||||
}
|
||||
|
||||
fun Activity.navigate(fragmentId: Int, bundle: Bundle) {
|
||||
coreMainActivity.navigate(fragmentId, bundle)
|
||||
fun Activity.navigate(route: String, navOptions: NavOptions? = null) {
|
||||
coreMainActivity.navigate(route, navOptions)
|
||||
}
|
||||
|
||||
fun Activity.popNavigationBackstack() {
|
||||
|
@ -27,7 +27,9 @@ import android.view.MenuItem
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.material3.BottomAppBarScrollBehavior
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.core.net.toUri
|
||||
@ -73,6 +75,21 @@ const val KIWIX_INTERNAL_ERROR = 10
|
||||
const val ACTION_NEW_TAB = "NEW_TAB"
|
||||
const val NEW_TAB_SHORTCUT_ID = "new_tab_shortcut"
|
||||
|
||||
// Fragments names for compose based navigation.
|
||||
const val READER_FRAGMENT = "readerFragment"
|
||||
const val LOCAL_LIBRARY_FRAGMENT = "localLibraryFragment"
|
||||
const val DOWNLOAD_FRAGMENT = "downloadsFragment"
|
||||
const val BOOKMARK_FRAGMENT = "bookmarkFragment"
|
||||
const val NOTES_FRAGMENT = "notesFragment"
|
||||
const val INTRO_FRAGMENT = "introFragment"
|
||||
const val HISTORY_FRAGMENT = "historyFragment"
|
||||
const val LANGUAGE_FRAGMENT = "languageFragment"
|
||||
const val ZIM_HOST_FRAGMENT = "zimHostFragment"
|
||||
const val HELP_FRAGMENT = "helpFragment"
|
||||
const val SETTINGS_FRAGMENT = "settingsFragment"
|
||||
const val SEARCH_FRAGMENT = "searchFragment"
|
||||
const val LOCAL_FILE_TRANSFER_FRAGMENT = "localFileTransferFragment"
|
||||
|
||||
abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||
abstract val searchFragmentRoute: String
|
||||
|
||||
@ -108,8 +125,17 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||
*/
|
||||
protected val leftDrawerMenu = mutableStateListOf<DrawerMenuGroup>()
|
||||
|
||||
/**
|
||||
* Manages the enabling/disabling the left drawer
|
||||
*/
|
||||
protected val enableLeftDrawer = mutableStateOf(true)
|
||||
|
||||
/**
|
||||
* For managing the the showing/hiding the bottomAppBar when scrolling.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
lateinit var bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior
|
||||
|
||||
// abstract val drawerContainerLayout: DrawerLayout
|
||||
// abstract val drawerNavView: NavigationView
|
||||
// abstract val readerTableOfContentsDrawer: NavigationView
|
||||
@ -319,6 +345,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||
}
|
||||
|
||||
open fun disableDrawer(disableRightDrawer: Boolean = true) {
|
||||
enableLeftDrawer.value = false
|
||||
// drawerToggle?.isDrawerIndicatorEnabled = false
|
||||
// drawerContainerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
// if (disableRightDrawer) {
|
||||
@ -424,8 +451,8 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||
}
|
||||
}
|
||||
|
||||
fun navigate(route: String) {
|
||||
navController.navigate(route)
|
||||
fun navigate(route: String, navOptions: NavOptions? = null) {
|
||||
navController.navigate(route, navOptions)
|
||||
}
|
||||
|
||||
fun navigate(fragmentId: Int, bundle: Bundle) {
|
||||
@ -446,29 +473,11 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||
navigate(historyFragmentRoute)
|
||||
}
|
||||
|
||||
fun openSearch(
|
||||
abstract fun openSearch(
|
||||
searchString: String = "",
|
||||
isOpenedFromTabView: Boolean = false,
|
||||
isVoice: Boolean = false
|
||||
) {
|
||||
// navigate(
|
||||
// searchFragmentRoute,
|
||||
// bundleOf(
|
||||
// NAV_ARG_SEARCH_STRING to searchString,
|
||||
// TAG_FROM_TAB_SWITCHER to isOpenedFromTabView,
|
||||
// EXTRA_IS_WIDGET_VOICE to isVoice
|
||||
// )
|
||||
// )
|
||||
}
|
||||
|
||||
fun openZimFromFilePath(path: String) {
|
||||
// navigate(
|
||||
// readerFragmentRoute,
|
||||
// bundleOf(
|
||||
// ZIM_FILE_URI_KEY to path,
|
||||
// )
|
||||
// )
|
||||
}
|
||||
)
|
||||
|
||||
fun openPage(
|
||||
pageUrl: String,
|
||||
@ -607,14 +616,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||
abstract val readerFragmentRoute: String
|
||||
abstract fun createApplicationShortcuts()
|
||||
abstract fun setDialogHostToActivity(alertDialogShower: AlertDialogShower)
|
||||
|
||||
/**
|
||||
* This is for showing and hiding the bottomNavigationView when user scroll the screen.
|
||||
* We are making this abstract so that it can be easily used from the reader screen.
|
||||
* Since we do not have the bottomNavigationView in custom apps. So doing this way both apps will
|
||||
* provide there own implementation.
|
||||
*
|
||||
* TODO we will remove this once we will migrate mainActivity to the compose.
|
||||
*/
|
||||
abstract fun toggleBottomNavigation(isVisible: Boolean)
|
||||
abstract fun hideBottomAppBar()
|
||||
abstract fun showBottomAppBar()
|
||||
}
|
||||
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.core.main
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import org.kiwix.kiwixmobile.core.utils.files.Log
|
||||
import android.view.GestureDetector
|
||||
import android.view.GestureDetector.SimpleOnGestureListener
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.OnTouchListener
|
||||
import kotlin.math.abs
|
||||
|
||||
open class OnSwipeTouchListener constructor(context: Context) : OnTouchListener {
|
||||
private val gestureDetector: GestureDetector
|
||||
|
||||
init {
|
||||
gestureDetector = GestureDetector(context, GestureListener())
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility") override fun onTouch(
|
||||
view: View,
|
||||
event: MotionEvent
|
||||
): Boolean = gestureDetector.onTouchEvent(event)
|
||||
|
||||
private inner class GestureListener : SimpleOnGestureListener() {
|
||||
private val tag = "GestureListener"
|
||||
private val swipeThreshold = 100
|
||||
private val swipeVelocityThreshold = 100
|
||||
|
||||
override fun onDown(event: MotionEvent): Boolean = true
|
||||
|
||||
override fun onSingleTapUp(event: MotionEvent): Boolean {
|
||||
onTap(event)
|
||||
return super.onSingleTapUp(event)
|
||||
}
|
||||
|
||||
// See:- https://stackoverflow.com/questions/73463685/gesturedetector-ongesturelistener-overridden-methods-are-not-working-in-android
|
||||
@Suppress("NOTHING_TO_OVERRIDE", "ACCIDENTAL_OVERRIDE", "NestedBlockDepth", "ReturnCount")
|
||||
override fun onFling(
|
||||
e1: MotionEvent,
|
||||
e2: MotionEvent,
|
||||
velocityX: Float,
|
||||
velocityY: Float
|
||||
): Boolean {
|
||||
try {
|
||||
val diffY = e2.y - e1.y
|
||||
val diffX = e2.x - e1.x
|
||||
if (abs(diffX) > abs(diffY)) {
|
||||
if (abs(diffX) > swipeThreshold && abs(velocityX) > swipeVelocityThreshold) {
|
||||
if (diffX > 0) {
|
||||
onSwipeRight()
|
||||
} else {
|
||||
onSwipeLeft()
|
||||
}
|
||||
return true
|
||||
}
|
||||
} else if (abs(diffY) > swipeThreshold && abs(velocityY) > swipeVelocityThreshold) {
|
||||
if (diffY > 0) {
|
||||
onSwipeBottom()
|
||||
}
|
||||
return true
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
Log.e(tag, "Exception in onFling", exception)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
open fun onSwipeRight() {}
|
||||
open fun onSwipeLeft() {}
|
||||
open fun onSwipeBottom() {}
|
||||
open fun onTap(e: MotionEvent?) {}
|
||||
}
|
@ -741,10 +741,10 @@ abstract class CoreReaderFragment :
|
||||
}
|
||||
|
||||
private fun showTabSwitcher() {
|
||||
(requireActivity() as CoreMainActivity).disableDrawer()
|
||||
// Set a negative top margin to the web views to remove
|
||||
// the unwanted blank space caused by the toolbar.
|
||||
// setTopMarginToWebViews(-requireActivity().getToolbarHeight())
|
||||
(requireActivity() as CoreMainActivity).apply {
|
||||
disableDrawer()
|
||||
hideBottomAppBar()
|
||||
}
|
||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
readerScreenState.update {
|
||||
copy(
|
||||
@ -787,6 +787,7 @@ abstract class CoreReaderFragment :
|
||||
*/
|
||||
protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) {
|
||||
setUpDrawerToggle()
|
||||
(requireActivity() as CoreMainActivity).showBottomAppBar()
|
||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
readerScreenState.update {
|
||||
copy(
|
||||
@ -1569,7 +1570,10 @@ abstract class CoreReaderFragment :
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
protected open fun openFullScreen() {
|
||||
(requireActivity() as CoreMainActivity).disableDrawer(false)
|
||||
(requireActivity() as CoreMainActivity).apply {
|
||||
disableDrawer(false)
|
||||
hideBottomAppBar()
|
||||
}
|
||||
readerScreenState.update {
|
||||
copy(
|
||||
shouldShowBottomAppBar = false,
|
||||
@ -1588,6 +1592,7 @@ abstract class CoreReaderFragment :
|
||||
@Suppress("MagicNumber")
|
||||
open fun closeFullScreen() {
|
||||
setUpDrawerToggle()
|
||||
(requireActivity() as CoreMainActivity).showBottomAppBar()
|
||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
sharedPreferenceUtil?.putPrefFullScreen(false)
|
||||
updateBottomToolbarVisibility()
|
||||
|
@ -226,7 +226,7 @@ class SearchFragment : BaseFragment() {
|
||||
|
||||
private fun goBack() {
|
||||
val readerFragmentRoute = (activity as CoreMainActivity).readerFragmentRoute
|
||||
findNavController().popBackStack(readerFragmentRoute, false)
|
||||
(requireActivity() as CoreMainActivity).navController.popBackStack(readerFragmentRoute, false)
|
||||
}
|
||||
|
||||
private fun getSearchListItemForQuery(query: String): SearchListItem? =
|
||||
|
@ -109,9 +109,6 @@ object ComposeDimens {
|
||||
// BookItem dimens
|
||||
val BOOK_ICON_SIZE = 48.dp
|
||||
|
||||
// LocalLibraryFragment dimens
|
||||
val FAB_ICON_BOTTOM_MARGIN = 50.dp
|
||||
|
||||
// HelpFragment dimens
|
||||
val HELP_SCREEN_DIVIDER_HEIGHT = 0.7.dp
|
||||
val HELP_SCREEN_ITEM_TITLE_TEXT_SIZE = 20.sp
|
||||
|
@ -285,8 +285,16 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
activityCustomMainBinding.root.addView(getDialogHostComposeView(alertDialogShower), 0)
|
||||
}
|
||||
|
||||
override fun toggleBottomNavigation(isVisible: Boolean) {
|
||||
// Do nothing as we do not have the bottomNavigationView in custom apps.
|
||||
override fun openSearch(searchString: String, isOpenedFromTabView: Boolean, isVoice: Boolean) {
|
||||
// TODO implement when refactoring the custom app UI.
|
||||
}
|
||||
|
||||
override fun hideBottomAppBar() {
|
||||
// Do nothing since custom apps does not have the bottomAppBar.
|
||||
}
|
||||
|
||||
override fun showBottomAppBar() {
|
||||
// Do nothing since custom apps does not have the bottomAppBar.
|
||||
}
|
||||
|
||||
// Outdated shortcut id(new_tab)
|
||||
|
@ -36,6 +36,7 @@ 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
|
||||
@ -272,7 +273,8 @@ class CustomReaderFragment : CoreReaderFragment() {
|
||||
},
|
||||
onNoFilesFound = {
|
||||
if (sharedPreferenceUtil?.prefIsTest == false) {
|
||||
findNavController().navigate(R.id.customDownloadFragment)
|
||||
// TODO refactor this when migrating the custom app in compose
|
||||
// (requireActivity() as CoreMainActivity).navigate(R.id.customDownloadFragment)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user