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.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.NavOptions
|
||||||
import org.kiwix.kiwixmobile.cachedComponent
|
import org.kiwix.kiwixmobile.cachedComponent
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||||
|
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||||
|
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtensions {
|
class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtensions {
|
||||||
@ -58,7 +60,10 @@ class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtens
|
|||||||
|
|
||||||
private fun navigateToLibrary() {
|
private fun navigateToLibrary() {
|
||||||
presenter.setIntroShown()
|
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() {
|
override fun onDestroyView() {
|
||||||
|
@ -28,18 +28,22 @@ import android.view.MenuItem
|
|||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
|
import androidx.compose.material3.BottomAppBarDefaults
|
||||||
import androidx.compose.material3.DrawerValue
|
import androidx.compose.material3.DrawerValue
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.rememberDrawerState
|
import androidx.compose.material3.rememberDrawerState
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import androidx.core.os.ConfigurationCompat
|
import androidx.core.os.ConfigurationCompat
|
||||||
import androidx.core.os.bundleOf
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavOptions
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import eu.mhutti1.utils.storage.StorageDevice
|
import eu.mhutti1.utils.storage.StorageDevice
|
||||||
import eu.mhutti1.utils.storage.StorageDeviceUtils
|
import eu.mhutti1.utils.storage.StorageDeviceUtils
|
||||||
import kotlinx.coroutines.delay
|
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.CoreMainActivity
|
||||||
import org.kiwix.kiwixmobile.core.main.DrawerMenuItem
|
import org.kiwix.kiwixmobile.core.main.DrawerMenuItem
|
||||||
import org.kiwix.kiwixmobile.core.main.NEW_TAB_SHORTCUT_ID
|
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.LanguageUtils.Companion.handleLocaleChange
|
||||||
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
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.kiwixActivityComponent
|
||||||
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -106,6 +110,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
KiwixDestination.Reader.route
|
KiwixDestination.Reader.route
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val shouldShowBottomAppBar = mutableStateOf(true)
|
||||||
// private lateinit var activityKiwixMainBinding: ActivityKiwixMainBinding
|
// private lateinit var activityKiwixMainBinding: ActivityKiwixMainBinding
|
||||||
|
|
||||||
private var isIntroScreenVisible: Boolean = false
|
private var isIntroScreenVisible: Boolean = false
|
||||||
@ -116,6 +121,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
}
|
}
|
||||||
private val storageDeviceList = arrayListOf<StorageDevice>()
|
private val storageDeviceList = arrayListOf<StorageDevice>()
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
cachedComponent.inject(this)
|
cachedComponent.inject(this)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -123,17 +129,27 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
navController = rememberNavController()
|
navController = rememberNavController()
|
||||||
leftDrawerState = rememberDrawerState(DrawerValue.Closed)
|
leftDrawerState = rememberDrawerState(DrawerValue.Closed)
|
||||||
uiCoroutineScope = rememberCoroutineScope()
|
uiCoroutineScope = rememberCoroutineScope()
|
||||||
|
bottomAppBarScrollBehaviour = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||||
KiwixMainActivityScreen(
|
KiwixMainActivityScreen(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
leftDrawerContent = leftDrawerMenu,
|
leftDrawerContent = leftDrawerMenu,
|
||||||
topLevelDestinationsRoute = topLevelDestinationsRoute,
|
topLevelDestinationsRoute = topLevelDestinationsRoute,
|
||||||
leftDrawerState = leftDrawerState,
|
leftDrawerState = leftDrawerState,
|
||||||
uiCoroutineScope = uiCoroutineScope,
|
uiCoroutineScope = uiCoroutineScope,
|
||||||
enableLeftDrawer = enableLeftDrawer.value
|
enableLeftDrawer = enableLeftDrawer.value,
|
||||||
|
shouldShowBottomAppBar = shouldShowBottomAppBar.value,
|
||||||
|
bottomAppBarScrollBehaviour = bottomAppBarScrollBehaviour
|
||||||
)
|
)
|
||||||
LaunchedEffect(navController) {
|
LaunchedEffect(navController) {
|
||||||
navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange)
|
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 {
|
// activityKiwixMainBinding.drawerNavView.apply {
|
||||||
// setupWithNavController(navController)
|
// setupWithNavController(navController)
|
||||||
@ -191,34 +207,12 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
|
||||||
// navigate(KiwixReaderFragmentDirections.actionReaderFragmentToIntroFragment())
|
|
||||||
}
|
|
||||||
if (!sharedPreferenceUtil.prefIsTest) {
|
if (!sharedPreferenceUtil.prefIsTest) {
|
||||||
sharedPreferenceUtil.setIsPlayStoreBuildType(BuildConfig.IS_PLAYSTORE)
|
sharedPreferenceUtil.setIsPlayStoreBuildType(BuildConfig.IS_PLAYSTORE)
|
||||||
}
|
}
|
||||||
setDefaultDeviceLanguage()
|
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() {
|
private fun setDefaultDeviceLanguage() {
|
||||||
if (sharedPreferenceUtil.prefDeviceDefaultLanguage.isEmpty()) {
|
if (sharedPreferenceUtil.prefDeviceDefaultLanguage.isEmpty()) {
|
||||||
ConfigurationCompat.getLocales(
|
ConfigurationCompat.getLocales(
|
||||||
@ -256,9 +250,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
|
|
||||||
private fun handleGetContentIntent(intent: Intent?) {
|
private fun handleGetContentIntent(intent: Intent?) {
|
||||||
if (intent?.action == ACTION_GET_CONTENT) {
|
if (intent?.action == ACTION_GET_CONTENT) {
|
||||||
// activityKiwixMainBinding.bottomNavView.menu.findItem(R.id.downloadsFragment)?.let {
|
navigate(KiwixDestination.Downloads.route)
|
||||||
// NavigationUI.onNavDestinationSelected(it, navController)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,12 +278,7 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun openLocalLibraryWithZimFilePath(path: String) {
|
private fun openLocalLibraryWithZimFilePath(path: String) {
|
||||||
navigate(
|
navigate(KiwixDestination.Library.createRoute(zimFileUri = path))
|
||||||
R.id.libraryFragment,
|
|
||||||
bundleOf(
|
|
||||||
ZIM_FILE_URI_KEY to path,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNotificationIntent(intent: Intent) {
|
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 {
|
override fun onNavigationItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
id.menu_host_books -> openZimHostFragment()
|
id.menu_host_books -> openZimHostFragment()
|
||||||
@ -359,6 +350,24 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
// activityKiwixMainBinding.root.addView(getDialogHostComposeView(alertDialogShower), 0)
|
// 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)
|
// Outdated shortcut ids(new_tab, get_content)
|
||||||
// Remove if the application has the outdated shortcuts.
|
// Remove if the application has the outdated shortcuts.
|
||||||
private fun removeOutdatedIdShortcuts() {
|
private fun removeOutdatedIdShortcuts() {
|
||||||
|
@ -60,10 +60,11 @@ fun KiwixMainActivityScreen(
|
|||||||
topLevelDestinationsRoute: Set<String>,
|
topLevelDestinationsRoute: Set<String>,
|
||||||
leftDrawerState: DrawerState,
|
leftDrawerState: DrawerState,
|
||||||
uiCoroutineScope: CoroutineScope,
|
uiCoroutineScope: CoroutineScope,
|
||||||
enableLeftDrawer: Boolean
|
enableLeftDrawer: Boolean,
|
||||||
|
shouldShowBottomAppBar: Boolean,
|
||||||
|
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior
|
||||||
) {
|
) {
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val scrollingBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
|
||||||
KiwixTheme {
|
KiwixTheme {
|
||||||
ModalNavigationDrawer(
|
ModalNavigationDrawer(
|
||||||
drawerState = leftDrawerState,
|
drawerState = leftDrawerState,
|
||||||
@ -77,16 +78,17 @@ fun KiwixMainActivityScreen(
|
|||||||
Box {
|
Box {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
if (navBackStackEntry?.destination?.route in topLevelDestinationsRoute) {
|
if (navBackStackEntry?.destination?.route in topLevelDestinationsRoute && shouldShowBottomAppBar) {
|
||||||
BottomNavigationBar(
|
BottomNavigationBar(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
scrollBehavior = scrollingBehavior,
|
bottomAppBarScrollBehaviour = bottomAppBarScrollBehaviour,
|
||||||
navBackStackEntry = navBackStackEntry,
|
navBackStackEntry = navBackStackEntry,
|
||||||
leftDrawerState = leftDrawerState,
|
leftDrawerState = leftDrawerState,
|
||||||
uiCoroutineScope = uiCoroutineScope
|
uiCoroutineScope = uiCoroutineScope
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Box(modifier = Modifier.padding(paddingValues)) {
|
Box(modifier = Modifier.padding(paddingValues)) {
|
||||||
KiwixNavGraph(
|
KiwixNavGraph(
|
||||||
@ -104,7 +106,7 @@ fun KiwixMainActivityScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationBar(
|
fun BottomNavigationBar(
|
||||||
navController: NavHostController,
|
navController: NavHostController,
|
||||||
scrollBehavior: BottomAppBarScrollBehavior,
|
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior,
|
||||||
navBackStackEntry: NavBackStackEntry?,
|
navBackStackEntry: NavBackStackEntry?,
|
||||||
leftDrawerState: DrawerState,
|
leftDrawerState: DrawerState,
|
||||||
uiCoroutineScope: CoroutineScope
|
uiCoroutineScope: CoroutineScope
|
||||||
@ -130,12 +132,14 @@ fun BottomNavigationBar(
|
|||||||
BottomAppBar(
|
BottomAppBar(
|
||||||
containerColor = Black,
|
containerColor = Black,
|
||||||
contentColor = White,
|
contentColor = White,
|
||||||
scrollBehavior = scrollBehavior
|
scrollBehavior = bottomAppBarScrollBehaviour
|
||||||
) {
|
) {
|
||||||
bottomNavItems.forEach { item ->
|
bottomNavItems.forEach { item ->
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
selected = currentDestinationRoute == item.route,
|
selected = currentDestinationRoute == item.route,
|
||||||
onClick = {
|
onClick = {
|
||||||
|
// Do not load again fragment that is already loaded.
|
||||||
|
if (item.route == currentDestinationRoute) return@NavigationBarItem
|
||||||
uiCoroutineScope.launch {
|
uiCoroutineScope.launch {
|
||||||
leftDrawerState.close()
|
leftDrawerState.close()
|
||||||
navController.navigate(item.route)
|
navController.navigate(item.route)
|
||||||
|
@ -39,6 +39,7 @@ import androidx.appcompat.view.ActionMode
|
|||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Menu
|
import androidx.compose.material.icons.filled.Menu
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -51,6 +52,7 @@ import androidx.fragment.app.FragmentActivity
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.NavOptions
|
||||||
import eu.mhutti1.utils.storage.Bytes
|
import eu.mhutti1.utils.storage.Bytes
|
||||||
import eu.mhutti1.utils.storage.StorageDevice
|
import eu.mhutti1.utils.storage.StorageDevice
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
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.ZimFileReader
|
||||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
|
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.rememberBottomNavigationVisibility
|
|
||||||
import org.kiwix.kiwixmobile.core.ui.models.ActionMenuItem
|
import org.kiwix.kiwixmobile.core.ui.models.ActionMenuItem
|
||||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||||
import org.kiwix.kiwixmobile.core.utils.EXTERNAL_SELECT_POSITION
|
import org.kiwix.kiwixmobile.core.utils.EXTERNAL_SELECT_POSITION
|
||||||
@ -173,6 +174,7 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
|||||||
baseActivity.cachedComponent.inject(this)
|
baseActivity.cachedComponent.inject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@ -183,10 +185,6 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
|||||||
return ComposeView(requireContext()).apply {
|
return ComposeView(requireContext()).apply {
|
||||||
setContent {
|
setContent {
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
val isBottomNavVisible = rememberBottomNavigationVisibility(lazyListState)
|
|
||||||
LaunchedEffect(isBottomNavVisible) {
|
|
||||||
(requireActivity() as KiwixMainActivity).toggleBottomNavigation(isBottomNavVisible)
|
|
||||||
}
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
updateLibraryScreenState(
|
updateLibraryScreenState(
|
||||||
bottomNavigationHeight = getBottomNavigationHeight(),
|
bottomNavigationHeight = getBottomNavigationHeight(),
|
||||||
@ -202,6 +200,7 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
|||||||
onMultiSelect = { offerAction(RequestSelect(it)) },
|
onMultiSelect = { offerAction(RequestSelect(it)) },
|
||||||
onRefresh = { onSwipeRefresh() },
|
onRefresh = { onSwipeRefresh() },
|
||||||
onDownloadButtonClick = { downloadBookButtonClick() },
|
onDownloadButtonClick = { downloadBookButtonClick() },
|
||||||
|
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour
|
||||||
) {
|
) {
|
||||||
NavigationIcon(
|
NavigationIcon(
|
||||||
iconItem = IconItem.Vector(Icons.Filled.Menu),
|
iconItem = IconItem.Vector(Icons.Filled.Menu),
|
||||||
@ -493,9 +492,12 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
|||||||
zimFileReader.dispose()
|
zimFileReader.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val navOptions = NavOptions.Builder()
|
||||||
|
.setPopUpTo(KiwixDestination.Reader.route, false)
|
||||||
|
.build()
|
||||||
activity?.navigate(
|
activity?.navigate(
|
||||||
LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationReader()
|
KiwixDestination.Reader.createRoute(zimFileUri = file.toUri().toString()),
|
||||||
.apply { 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.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.BottomAppBarScrollBehavior
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.Icon
|
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.R.string
|
||||||
import org.kiwix.kiwixmobile.core.R
|
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.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.ContentLoadingProgressBar
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar
|
import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixButton
|
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.KiwixTheme
|
||||||
import org.kiwix.kiwixmobile.core.ui.theme.White
|
import org.kiwix.kiwixmobile.core.ui.theme.White
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP
|
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.utils.ComposeDimens.FOUR_DP
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk
|
||||||
@ -85,10 +84,9 @@ fun LocalLibraryScreen(
|
|||||||
onClick: ((BookOnDisk) -> Unit)? = null,
|
onClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
||||||
|
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior,
|
||||||
navigationIcon: @Composable () -> Unit
|
navigationIcon: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val (bottomNavHeight, lazyListState) =
|
|
||||||
rememberScrollBehavior(state.bottomNavigationHeight, listState)
|
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
KiwixTheme {
|
KiwixTheme {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
@ -105,7 +103,7 @@ fun LocalLibraryScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.systemBarsPadding()
|
.systemBarsPadding()
|
||||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.padding(bottom = bottomNavHeight.value)
|
.nestedScroll(bottomAppBarScrollBehaviour.nestedScrollConnection)
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
SwipeRefreshLayout(
|
SwipeRefreshLayout(
|
||||||
isRefreshing = state.swipeRefreshItem.first,
|
isRefreshing = state.swipeRefreshItem.first,
|
||||||
@ -130,7 +128,7 @@ fun LocalLibraryScreen(
|
|||||||
onClick,
|
onClick,
|
||||||
onLongClick,
|
onLongClick,
|
||||||
onMultiSelect,
|
onMultiSelect,
|
||||||
lazyListState
|
listState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +176,6 @@ private fun SelectFileButton(fabButtonClick: () -> Unit) {
|
|||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
onClick = fabButtonClick,
|
onClick = fabButtonClick,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(bottom = FAB_ICON_BOTTOM_MARGIN)
|
|
||||||
.testTag(SELECT_FILE_BUTTON_TESTING_TAG),
|
.testTag(SELECT_FILE_BUTTON_TESTING_TAG),
|
||||||
containerColor = Black,
|
containerColor = Black,
|
||||||
shape = MaterialTheme.shapes.extraLarge
|
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.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Menu
|
import androidx.compose.material.icons.filled.Menu
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
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.page.SEARCH_ICON_TESTING_TAG
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
import org.kiwix.kiwixmobile.core.ui.components.NavigationIcon
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.ONE
|
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.ActionMenuItem
|
||||||
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
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?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
composeView?.setContent {
|
composeView?.setContent {
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
val isBottomNavVisible = rememberBottomNavigationVisibility(lazyListState)
|
|
||||||
LaunchedEffect(isBottomNavVisible) {
|
|
||||||
(requireActivity() as KiwixMainActivity).toggleBottomNavigation(isBottomNavVisible)
|
|
||||||
}
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
onlineLibraryScreenState.value.update {
|
onlineLibraryScreenState.value.update {
|
||||||
copy(
|
copy(
|
||||||
@ -273,7 +270,8 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
|||||||
contentDescription = string.open_drawer,
|
contentDescription = string.open_drawer,
|
||||||
onClick = { navigationIconClick(onlineLibraryScreenState.value.value.isSearchActive) }
|
onClick = { navigationIconClick(onlineLibraryScreenState.value.value.isSearchActive) }
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
|
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour
|
||||||
)
|
)
|
||||||
DialogHost(alertDialogShower)
|
DialogHost(alertDialogShower)
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import androidx.compose.foundation.lazy.LazyListState
|
|||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.BottomAppBarScrollBehavior
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
@ -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.FIVE
|
||||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
||||||
import org.kiwix.kiwixmobile.core.extensions.hideKeyboardOnLazyColumnScroll
|
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.ContentLoadingProgressBar
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar
|
import org.kiwix.kiwixmobile.core.ui.components.KiwixAppBar
|
||||||
import org.kiwix.kiwixmobile.core.ui.components.KiwixSearchView
|
import org.kiwix.kiwixmobile.core.ui.components.KiwixSearchView
|
||||||
@ -98,10 +98,9 @@ fun OnlineLibraryScreen(
|
|||||||
state: OnlineLibraryScreenState,
|
state: OnlineLibraryScreenState,
|
||||||
actionMenuItems: List<ActionMenuItem>,
|
actionMenuItems: List<ActionMenuItem>,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
|
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior,
|
||||||
navigationIcon: @Composable () -> Unit,
|
navigationIcon: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
val (bottomNavHeight, lazyListState) =
|
|
||||||
rememberScrollBehavior(state.bottomNavigationHeight, listState)
|
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
|
|
||||||
KiwixTheme {
|
KiwixTheme {
|
||||||
@ -118,7 +117,7 @@ fun OnlineLibraryScreen(
|
|||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.padding(bottom = bottomNavHeight.value)
|
.nestedScroll(bottomAppBarScrollBehaviour.nestedScrollConnection)
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
SwipeRefreshLayout(
|
SwipeRefreshLayout(
|
||||||
isRefreshing = state.isRefreshing && !state.scanningProgressItem.first,
|
isRefreshing = state.isRefreshing && !state.scanningProgressItem.first,
|
||||||
@ -132,7 +131,7 @@ fun OnlineLibraryScreen(
|
|||||||
end = paddingValues.calculateEndPadding(LocalLayoutDirection.current),
|
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.core.net.toUri
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.NavOptions
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.kiwix.kiwixmobile.cachedComponent
|
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.TAG_KIWIX
|
||||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||||
import org.kiwix.kiwixmobile.core.utils.files.Log
|
import org.kiwix.kiwixmobile.core.utils.files.Log
|
||||||
|
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class KiwixReaderFragment : CoreReaderFragment() {
|
class KiwixReaderFragment : CoreReaderFragment() {
|
||||||
@ -70,9 +72,10 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
|||||||
val activity = activity as CoreMainActivity
|
val activity = activity as CoreMainActivity
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(onOpenLibraryButtonClicked = {
|
copy(onOpenLibraryButtonClicked = {
|
||||||
activity.navigate(
|
val navOptions = NavOptions.Builder()
|
||||||
KiwixReaderFragmentDirections.actionNavigationReaderToNavigationLibrary()
|
.setPopUpTo(KiwixDestination.Reader.route, inclusive = true)
|
||||||
)
|
.build()
|
||||||
|
activity.navigate(KiwixDestination.Library.route, navOptions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
@ -18,26 +18,52 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.ui
|
package org.kiwix.kiwixmobile.ui
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.doOnAttach
|
import androidx.core.view.doOnAttach
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentContainerView
|
import androidx.fragment.app.FragmentContainerView
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.NavType
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
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.bookmark.BookmarksFragment
|
||||||
import org.kiwix.kiwixmobile.core.page.history.HistoryFragment
|
import org.kiwix.kiwixmobile.core.page.history.HistoryFragment
|
||||||
import org.kiwix.kiwixmobile.core.page.notes.NotesFragment
|
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.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.help.KiwixHelpFragment
|
||||||
import org.kiwix.kiwixmobile.intro.IntroFragment
|
import org.kiwix.kiwixmobile.intro.IntroFragment
|
||||||
import org.kiwix.kiwixmobile.language.LanguageFragment
|
import org.kiwix.kiwixmobile.language.LanguageFragment
|
||||||
@ -58,24 +84,47 @@ fun KiwixNavGraph(
|
|||||||
startDestination = KiwixDestination.Reader.route,
|
startDestination = KiwixDestination.Reader.route,
|
||||||
modifier = modifier
|
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 {
|
FragmentContainer {
|
||||||
KiwixReaderFragment().apply {
|
KiwixReaderFragment().apply {
|
||||||
arguments = Bundle().apply {
|
arguments = Bundle().apply {
|
||||||
putString("zimFileUri", "")
|
putString(ZIM_FILE_URI_KEY, zimFileUri)
|
||||||
putString("findInPageSearchString", "")
|
putString(FIND_IN_PAGE_SEARCH_STRING, findInPageSearchString)
|
||||||
putString("pageUrl", "")
|
putString(PAGE_URL_KEY, pageUrl)
|
||||||
putBoolean("shouldOpenInNewTab", false)
|
putBoolean(SHOULD_OPEN_IN_NEW_TAB, shouldOpenInNewTab)
|
||||||
putString("searchItemTitle", "")
|
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 {
|
FragmentContainer {
|
||||||
LocalLibraryFragment().apply {
|
LocalLibraryFragment().apply {
|
||||||
arguments = Bundle().apply {
|
arguments = Bundle().apply {
|
||||||
putString("zimFileUri", "")
|
putString(ZIM_FILE_URI_KEY, zimFileUri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,16 +174,51 @@ fun KiwixNavGraph(
|
|||||||
KiwixSettingsFragment()
|
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 {
|
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 {
|
FragmentContainer {
|
||||||
LocalFileTransferFragment().apply {
|
LocalFileTransferFragment().apply {
|
||||||
arguments = Bundle().apply {
|
arguments = Bundle().apply {
|
||||||
putParcelableArray("uris", null)
|
putParcelableArray(
|
||||||
|
"uris",
|
||||||
|
uris?.toTypedArray()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,6 +226,7 @@ fun KiwixNavGraph(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun FragmentContainer(
|
fun FragmentContainer(
|
||||||
fragmentProvider: () -> Fragment
|
fragmentProvider: () -> Fragment
|
||||||
@ -170,17 +255,72 @@ fun FragmentContainer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class KiwixDestination(val route: String) {
|
sealed class KiwixDestination(val route: String) {
|
||||||
object Reader : KiwixDestination("readerFragment")
|
object Reader : KiwixDestination(
|
||||||
object Library : KiwixDestination("libraryFragment")
|
READER_FRAGMENT +
|
||||||
object Downloads : KiwixDestination("downloadsFragment")
|
"?$ZIM_FILE_URI_KEY={$ZIM_FILE_URI_KEY}" +
|
||||||
object Bookmarks : KiwixDestination("bookmarksFragment")
|
"&$FIND_IN_PAGE_SEARCH_STRING={$FIND_IN_PAGE_SEARCH_STRING}" +
|
||||||
object Notes : KiwixDestination("notesFragment")
|
"&$PAGE_URL_KEY={$PAGE_URL_KEY}" +
|
||||||
object Intro : KiwixDestination("introFragment")
|
"&$SHOULD_OPEN_IN_NEW_TAB={$SHOULD_OPEN_IN_NEW_TAB}" +
|
||||||
object History : KiwixDestination("historyFragment")
|
"&$SEARCH_ITEM_TITLE_KEY={$SEARCH_ITEM_TITLE_KEY}"
|
||||||
object Language : KiwixDestination("languageFragment")
|
) {
|
||||||
object ZimHost : KiwixDestination("zimHostFragment")
|
fun createRoute(
|
||||||
object Help : KiwixDestination("helpFragment")
|
zimFileUri: String = "",
|
||||||
object Settings : KiwixDestination("kiwixSettingsFragment")
|
findInPageSearchString: String = "",
|
||||||
object Search : KiwixDestination("searchFragment")
|
pageUrl: String = "",
|
||||||
object LocalFileTransfer : KiwixDestination("localFileTransferFragment")
|
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
|
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.navigation.NavOptions
|
||||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
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> {
|
object NavigateToDownloads : SideEffect<Unit> {
|
||||||
override fun invokeWith(activity: AppCompatActivity) {
|
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.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.NavOptions
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
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.extensions.toast
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem
|
||||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||||
import org.kiwix.kiwixmobile.nav.destination.library.local.LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationReader
|
import org.kiwix.kiwixmobile.ui.KiwixDestination
|
||||||
|
|
||||||
@Suppress("InjectDispatcher")
|
@Suppress("InjectDispatcher")
|
||||||
data class OpenFileWithNavigation(private val bookOnDisk: BooksOnDiskListItem.BookOnDisk) :
|
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())
|
activity.getString(R.string.error_file_not_found, zimReaderSource.toDatabase())
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
val navOptions = NavOptions.Builder()
|
||||||
|
.setPopUpTo(KiwixDestination.Library.route, inclusive = false)
|
||||||
|
.build()
|
||||||
activity.navigate(
|
activity.navigate(
|
||||||
actionNavigationLibraryToNavigationReader().apply {
|
KiwixDestination.Reader.createRoute(zimFileUri = zimReaderSource.toDatabase()),
|
||||||
zimFileUri = zimReaderSource.toDatabase()
|
navOptions
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,11 @@
|
|||||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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.base.SideEffect
|
||||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListItem.BookOnDisk
|
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>) :
|
data class ShareFiles(private val selectedBooks: List<BookOnDisk>) :
|
||||||
SideEffect<Unit> {
|
SideEffect<Unit> {
|
||||||
@ -34,8 +33,7 @@ data class ShareFiles(private val selectedBooks: List<BookOnDisk>) :
|
|||||||
it.zimReaderSource.getUri(activity)
|
it.zimReaderSource.getUri(activity)
|
||||||
}
|
}
|
||||||
activity.navigate(
|
activity.navigate(
|
||||||
R.id.localFileTransferFragment,
|
KiwixDestination.LocalFileTransfer.createRoute(uris = selectedFileContentURIs.toUriParam())
|
||||||
bundleOf(URIS_KEY to selectedFileContentURIs.toTypedArray())
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import android.content.pm.PackageManager
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@ -41,7 +40,7 @@ import androidx.lifecycle.Observer
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.ViewModelProviders
|
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.di.components.CoreActivityComponent
|
||||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||||
import org.kiwix.kiwixmobile.core.utils.REQUEST_POST_NOTIFICATION_PERMISSION
|
import org.kiwix.kiwixmobile.core.utils.REQUEST_POST_NOTIFICATION_PERMISSION
|
||||||
@ -93,22 +92,14 @@ object ActivityExtensions {
|
|||||||
ViewModelProviders.of(this, viewModelFactory)
|
ViewModelProviders.of(this, viewModelFactory)
|
||||||
.get(T::class.java)
|
.get(T::class.java)
|
||||||
|
|
||||||
fun Activity.navigate(action: NavDirections) {
|
|
||||||
coreMainActivity.navigate(action)
|
|
||||||
}
|
|
||||||
|
|
||||||
val Activity.cachedComponent: CoreActivityComponent
|
val Activity.cachedComponent: CoreActivityComponent
|
||||||
get() = coreMainActivity.cachedComponent
|
get() = coreMainActivity.cachedComponent
|
||||||
|
|
||||||
fun Activity.setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) =
|
fun Activity.setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) =
|
||||||
coreMainActivity.setupDrawerToggle(shouldEnableRightDrawer)
|
coreMainActivity.setupDrawerToggle(shouldEnableRightDrawer)
|
||||||
|
|
||||||
fun Activity.navigate(route: String) {
|
fun Activity.navigate(route: String, navOptions: NavOptions? = null) {
|
||||||
coreMainActivity.navigate(route)
|
coreMainActivity.navigate(route, navOptions)
|
||||||
}
|
|
||||||
|
|
||||||
fun Activity.navigate(fragmentId: Int, bundle: Bundle) {
|
|
||||||
coreMainActivity.navigate(fragmentId, bundle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.popNavigationBackstack() {
|
fun Activity.popNavigationBackstack() {
|
||||||
|
@ -27,7 +27,9 @@ import android.view.MenuItem
|
|||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.material3.BottomAppBarScrollBehavior
|
||||||
import androidx.compose.material3.DrawerState
|
import androidx.compose.material3.DrawerState
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
@ -73,6 +75,21 @@ const val KIWIX_INTERNAL_ERROR = 10
|
|||||||
const val ACTION_NEW_TAB = "NEW_TAB"
|
const val ACTION_NEW_TAB = "NEW_TAB"
|
||||||
const val NEW_TAB_SHORTCUT_ID = "new_tab_shortcut"
|
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 class CoreMainActivity : BaseActivity(), WebViewProvider {
|
||||||
abstract val searchFragmentRoute: String
|
abstract val searchFragmentRoute: String
|
||||||
|
|
||||||
@ -108,8 +125,17 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
*/
|
*/
|
||||||
protected val leftDrawerMenu = mutableStateListOf<DrawerMenuGroup>()
|
protected val leftDrawerMenu = mutableStateListOf<DrawerMenuGroup>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the enabling/disabling the left drawer
|
||||||
|
*/
|
||||||
protected val enableLeftDrawer = mutableStateOf(true)
|
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 drawerContainerLayout: DrawerLayout
|
||||||
// abstract val drawerNavView: NavigationView
|
// abstract val drawerNavView: NavigationView
|
||||||
// abstract val readerTableOfContentsDrawer: NavigationView
|
// abstract val readerTableOfContentsDrawer: NavigationView
|
||||||
@ -319,6 +345,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun disableDrawer(disableRightDrawer: Boolean = true) {
|
open fun disableDrawer(disableRightDrawer: Boolean = true) {
|
||||||
|
enableLeftDrawer.value = false
|
||||||
// drawerToggle?.isDrawerIndicatorEnabled = false
|
// drawerToggle?.isDrawerIndicatorEnabled = false
|
||||||
// drawerContainerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
// drawerContainerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||||
// if (disableRightDrawer) {
|
// if (disableRightDrawer) {
|
||||||
@ -424,8 +451,8 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun navigate(route: String) {
|
fun navigate(route: String, navOptions: NavOptions? = null) {
|
||||||
navController.navigate(route)
|
navController.navigate(route, navOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun navigate(fragmentId: Int, bundle: Bundle) {
|
fun navigate(fragmentId: Int, bundle: Bundle) {
|
||||||
@ -446,29 +473,11 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
navigate(historyFragmentRoute)
|
navigate(historyFragmentRoute)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openSearch(
|
abstract fun openSearch(
|
||||||
searchString: String = "",
|
searchString: String = "",
|
||||||
isOpenedFromTabView: Boolean = false,
|
isOpenedFromTabView: Boolean = false,
|
||||||
isVoice: 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(
|
fun openPage(
|
||||||
pageUrl: String,
|
pageUrl: String,
|
||||||
@ -607,14 +616,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
abstract val readerFragmentRoute: String
|
abstract val readerFragmentRoute: String
|
||||||
abstract fun createApplicationShortcuts()
|
abstract fun createApplicationShortcuts()
|
||||||
abstract fun setDialogHostToActivity(alertDialogShower: AlertDialogShower)
|
abstract fun setDialogHostToActivity(alertDialogShower: AlertDialogShower)
|
||||||
|
abstract fun hideBottomAppBar()
|
||||||
/**
|
abstract fun showBottomAppBar()
|
||||||
* 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)
|
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
private fun showTabSwitcher() {
|
||||||
(requireActivity() as CoreMainActivity).disableDrawer()
|
(requireActivity() as CoreMainActivity).apply {
|
||||||
// Set a negative top margin to the web views to remove
|
disableDrawer()
|
||||||
// the unwanted blank space caused by the toolbar.
|
hideBottomAppBar()
|
||||||
// setTopMarginToWebViews(-requireActivity().getToolbarHeight())
|
}
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(
|
copy(
|
||||||
@ -787,6 +787,7 @@ abstract class CoreReaderFragment :
|
|||||||
*/
|
*/
|
||||||
protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) {
|
protected open fun hideTabSwitcher(shouldCloseZimBook: Boolean = true) {
|
||||||
setUpDrawerToggle()
|
setUpDrawerToggle()
|
||||||
|
(requireActivity() as CoreMainActivity).showBottomAppBar()
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(
|
copy(
|
||||||
@ -1569,7 +1570,10 @@ abstract class CoreReaderFragment :
|
|||||||
|
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
protected open fun openFullScreen() {
|
protected open fun openFullScreen() {
|
||||||
(requireActivity() as CoreMainActivity).disableDrawer(false)
|
(requireActivity() as CoreMainActivity).apply {
|
||||||
|
disableDrawer(false)
|
||||||
|
hideBottomAppBar()
|
||||||
|
}
|
||||||
readerScreenState.update {
|
readerScreenState.update {
|
||||||
copy(
|
copy(
|
||||||
shouldShowBottomAppBar = false,
|
shouldShowBottomAppBar = false,
|
||||||
@ -1588,6 +1592,7 @@ abstract class CoreReaderFragment :
|
|||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
open fun closeFullScreen() {
|
open fun closeFullScreen() {
|
||||||
setUpDrawerToggle()
|
setUpDrawerToggle()
|
||||||
|
(requireActivity() as CoreMainActivity).showBottomAppBar()
|
||||||
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
sharedPreferenceUtil?.putPrefFullScreen(false)
|
sharedPreferenceUtil?.putPrefFullScreen(false)
|
||||||
updateBottomToolbarVisibility()
|
updateBottomToolbarVisibility()
|
||||||
|
@ -226,7 +226,7 @@ class SearchFragment : BaseFragment() {
|
|||||||
|
|
||||||
private fun goBack() {
|
private fun goBack() {
|
||||||
val readerFragmentRoute = (activity as CoreMainActivity).readerFragmentRoute
|
val readerFragmentRoute = (activity as CoreMainActivity).readerFragmentRoute
|
||||||
findNavController().popBackStack(readerFragmentRoute, false)
|
(requireActivity() as CoreMainActivity).navController.popBackStack(readerFragmentRoute, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSearchListItemForQuery(query: String): SearchListItem? =
|
private fun getSearchListItemForQuery(query: String): SearchListItem? =
|
||||||
|
@ -109,9 +109,6 @@ object ComposeDimens {
|
|||||||
// BookItem dimens
|
// BookItem dimens
|
||||||
val BOOK_ICON_SIZE = 48.dp
|
val BOOK_ICON_SIZE = 48.dp
|
||||||
|
|
||||||
// LocalLibraryFragment dimens
|
|
||||||
val FAB_ICON_BOTTOM_MARGIN = 50.dp
|
|
||||||
|
|
||||||
// HelpFragment dimens
|
// HelpFragment dimens
|
||||||
val HELP_SCREEN_DIVIDER_HEIGHT = 0.7.dp
|
val HELP_SCREEN_DIVIDER_HEIGHT = 0.7.dp
|
||||||
val HELP_SCREEN_ITEM_TITLE_TEXT_SIZE = 20.sp
|
val HELP_SCREEN_ITEM_TITLE_TEXT_SIZE = 20.sp
|
||||||
|
@ -285,8 +285,16 @@ class CustomMainActivity : CoreMainActivity() {
|
|||||||
activityCustomMainBinding.root.addView(getDialogHostComposeView(alertDialogShower), 0)
|
activityCustomMainBinding.root.addView(getDialogHostComposeView(alertDialogShower), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toggleBottomNavigation(isVisible: Boolean) {
|
override fun openSearch(searchString: String, isOpenedFromTabView: Boolean, isVoice: Boolean) {
|
||||||
// Do nothing as we do not have the bottomNavigationView in custom apps.
|
// 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)
|
// 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.browserIntent
|
||||||
import org.kiwix.kiwixmobile.core.extensions.isFileExist
|
import org.kiwix.kiwixmobile.core.extensions.isFileExist
|
||||||
import org.kiwix.kiwixmobile.core.extensions.update
|
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.CoreReaderFragment
|
||||||
import org.kiwix.kiwixmobile.core.main.reader.ReaderMenuState
|
import org.kiwix.kiwixmobile.core.main.reader.ReaderMenuState
|
||||||
import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin
|
import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin
|
||||||
@ -272,7 +273,8 @@ class CustomReaderFragment : CoreReaderFragment() {
|
|||||||
},
|
},
|
||||||
onNoFilesFound = {
|
onNoFilesFound = {
|
||||||
if (sharedPreferenceUtil?.prefIsTest == false) {
|
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