mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-08 06:42:21 -04:00
Fixed: Pressing the back button no longer reopens the Search fragment when you’re on the Reader fragment and navigated there from Search (which was happening before).
* Fixed: Pressing the back button now correctly closes the left drawer when it’s open on the Local Library or Online fragments. * Introduced: A common mechanism to support back press handling across all fragments and the activity, and added support for "Periodic back navigation".
This commit is contained in:
parent
51bd9e7908
commit
8112632c80
@ -51,11 +51,9 @@ import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
|||||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange
|
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange
|
||||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||||
import org.kiwix.kiwixmobile.core.utils.TestingUtils.COMPOSE_TEST_RULE_ORDER
|
import org.kiwix.kiwixmobile.core.utils.TestingUtils.COMPOSE_TEST_RULE_ORDER
|
||||||
import org.kiwix.kiwixmobile.core.utils.TestingUtils.RETRY_RULE_ORDER
|
|
||||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||||
import org.kiwix.kiwixmobile.main.topLevel
|
import org.kiwix.kiwixmobile.main.topLevel
|
||||||
import org.kiwix.kiwixmobile.nav.destination.library.library
|
import org.kiwix.kiwixmobile.nav.destination.library.library
|
||||||
import org.kiwix.kiwixmobile.testutils.RetryRule
|
|
||||||
import org.kiwix.kiwixmobile.testutils.TestUtils
|
import org.kiwix.kiwixmobile.testutils.TestUtils
|
||||||
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
|
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
|
||||||
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
|
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
|
||||||
@ -65,9 +63,9 @@ import java.util.concurrent.TimeUnit
|
|||||||
|
|
||||||
@LargeTest
|
@LargeTest
|
||||||
class DownloadTest : BaseActivityTest() {
|
class DownloadTest : BaseActivityTest() {
|
||||||
@Rule(order = RETRY_RULE_ORDER)
|
// @Rule(order = RETRY_RULE_ORDER)
|
||||||
@JvmField
|
// @JvmField
|
||||||
val retryRule = RetryRule()
|
// val retryRule = RetryRule()
|
||||||
|
|
||||||
@get:Rule(order = COMPOSE_TEST_RULE_ORDER)
|
@get:Rule(order = COMPOSE_TEST_RULE_ORDER)
|
||||||
val composeTestRule = createComposeRule()
|
val composeTestRule = createComposeRule()
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.main
|
package org.kiwix.kiwixmobile.main
|
||||||
|
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
|
import androidx.activity.compose.LocalActivity
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@ -75,6 +77,7 @@ fun KiwixMainActivityScreen(
|
|||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val currentRoute = navBackStackEntry?.destination?.route
|
val currentRoute = navBackStackEntry?.destination?.route
|
||||||
val shouldShowBottomBar = currentRoute in topLevelDestinationsRoute && shouldShowBottomAppBar
|
val shouldShowBottomBar = currentRoute in topLevelDestinationsRoute && shouldShowBottomAppBar
|
||||||
|
OnUserBackPressed(leftDrawerState, uiCoroutineScope, currentRoute, navController)
|
||||||
KiwixTheme {
|
KiwixTheme {
|
||||||
ModalNavigationDrawer(
|
ModalNavigationDrawer(
|
||||||
drawerState = leftDrawerState,
|
drawerState = leftDrawerState,
|
||||||
@ -119,6 +122,33 @@ fun KiwixMainActivityScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun OnUserBackPressed(
|
||||||
|
leftDrawerState: DrawerState,
|
||||||
|
uiCoroutineScope: CoroutineScope,
|
||||||
|
currentRoute: String?,
|
||||||
|
navController: NavHostController
|
||||||
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
BackHandler(enabled = true) {
|
||||||
|
when {
|
||||||
|
leftDrawerState.isOpen -> uiCoroutineScope.launch { leftDrawerState.close() }
|
||||||
|
|
||||||
|
currentRoute == KiwixDestination.Reader.route &&
|
||||||
|
navController.previousBackStackEntry?.destination?.route != KiwixDestination.Search.route -> {
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val popped = navController.popBackStack()
|
||||||
|
if (!popped) {
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationBar(
|
fun BottomNavigationBar(
|
||||||
|
@ -66,6 +66,7 @@ import org.kiwix.kiwixmobile.cachedComponent
|
|||||||
import org.kiwix.kiwixmobile.core.R.string
|
import org.kiwix.kiwixmobile.core.R.string
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||||
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
||||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isManageExternalStoragePermissionGranted
|
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isManageExternalStoragePermissionGranted
|
||||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
|
||||||
@ -200,7 +201,9 @@ 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
|
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour,
|
||||||
|
navHostController = (requireActivity() as CoreMainActivity).navController,
|
||||||
|
onUserBackPressed = { onUserBackPressed() }
|
||||||
) {
|
) {
|
||||||
NavigationIcon(
|
NavigationIcon(
|
||||||
iconItem = IconItem.Vector(Icons.Filled.Menu),
|
iconItem = IconItem.Vector(Icons.Filled.Menu),
|
||||||
@ -213,12 +216,16 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onUserBackPressed(): FragmentActivityExtensions.Super {
|
||||||
|
val coreMainActivity = (activity as? CoreMainActivity)
|
||||||
|
if (coreMainActivity?.navigationDrawerIsOpen() == true) {
|
||||||
|
coreMainActivity.closeNavigationDrawer()
|
||||||
|
return FragmentActivityExtensions.Super.ShouldNotCall
|
||||||
|
}
|
||||||
|
return FragmentActivityExtensions.Super.ShouldCall
|
||||||
|
}
|
||||||
|
|
||||||
private fun navigationIconClick() {
|
private fun navigationIconClick() {
|
||||||
// Manually handle the navigation open/close.
|
|
||||||
// Since currently we are using the view based navigation drawer in other screens.
|
|
||||||
// Once we fully migrate to jetpack compose we will refactor this code to use the
|
|
||||||
// compose navigation.
|
|
||||||
// TODO Replace with compose based navigation when migration is done.
|
|
||||||
val activity = activity as CoreMainActivity
|
val activity = activity as CoreMainActivity
|
||||||
if (activity.navigationDrawerIsOpen()) {
|
if (activity.navigationDrawerIsOpen()) {
|
||||||
activity.closeNavigationDrawer()
|
activity.closeNavigationDrawer()
|
||||||
|
@ -47,9 +47,12 @@ import androidx.compose.ui.res.painterResource
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
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.base.FragmentActivityExtensions
|
||||||
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.OnBackPressed
|
||||||
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
|
||||||
@ -73,7 +76,7 @@ const val BOOK_LIST_TESTING_TAG = "bookListTestingTag"
|
|||||||
const val SELECT_FILE_BUTTON_TESTING_TAG = "selectFileButtonTestingTag"
|
const val SELECT_FILE_BUTTON_TESTING_TAG = "selectFileButtonTestingTag"
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Suppress("ComposableLambdaParameterNaming")
|
@Suppress("ComposableLambdaParameterNaming", "LongParameterList")
|
||||||
@Composable
|
@Composable
|
||||||
fun LocalLibraryScreen(
|
fun LocalLibraryScreen(
|
||||||
state: LocalLibraryScreenState,
|
state: LocalLibraryScreenState,
|
||||||
@ -85,6 +88,8 @@ fun LocalLibraryScreen(
|
|||||||
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
onMultiSelect: ((BookOnDisk) -> Unit)? = null,
|
||||||
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
||||||
|
onUserBackPressed: () -> FragmentActivityExtensions.Super,
|
||||||
|
navHostController: NavHostController,
|
||||||
navigationIcon: @Composable () -> Unit
|
navigationIcon: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
@ -117,6 +122,7 @@ fun LocalLibraryScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(contentPadding)
|
.padding(contentPadding)
|
||||||
) {
|
) {
|
||||||
|
OnBackPressed(onUserBackPressed, navHostController)
|
||||||
if (state.scanningProgressItem.first) {
|
if (state.scanningProgressItem.first) {
|
||||||
ContentLoadingProgressBar(
|
ContentLoadingProgressBar(
|
||||||
modifier = Modifier.testTag(CONTENT_LOADING_PROGRESSBAR_TESTING_TAG),
|
modifier = Modifier.testTag(CONTENT_LOADING_PROGRESSBAR_TESTING_TAG),
|
||||||
|
@ -29,7 +29,6 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
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.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
@ -271,7 +270,9 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
|||||||
onClick = { navigationIconClick(onlineLibraryScreenState.value.value.isSearchActive) }
|
onClick = { navigationIconClick(onlineLibraryScreenState.value.value.isSearchActive) }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour
|
bottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour,
|
||||||
|
navHostController = (requireActivity() as CoreMainActivity).navController,
|
||||||
|
onUserBackPressed = { onUserBackPressed() }
|
||||||
)
|
)
|
||||||
DialogHost(alertDialogShower)
|
DialogHost(alertDialogShower)
|
||||||
}
|
}
|
||||||
@ -460,8 +461,13 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
|||||||
composeView = null
|
composeView = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed(activity: AppCompatActivity): FragmentActivityExtensions.Super {
|
@Suppress("ReturnCount")
|
||||||
if (isKeyboardVisible() || onlineLibraryScreenState.value.value.isSearchActive) {
|
private fun onUserBackPressed(): FragmentActivityExtensions.Super {
|
||||||
|
val coreMainActivity = (activity as? CoreMainActivity)
|
||||||
|
if (coreMainActivity?.navigationDrawerIsOpen() == true) {
|
||||||
|
coreMainActivity.closeNavigationDrawer()
|
||||||
|
return FragmentActivityExtensions.Super.ShouldNotCall
|
||||||
|
} else if (isKeyboardVisible() || onlineLibraryScreenState.value.value.isSearchActive) {
|
||||||
closeKeyboard()
|
closeKeyboard()
|
||||||
closeSearch()
|
closeSearch()
|
||||||
return FragmentActivityExtensions.Super.ShouldNotCall
|
return FragmentActivityExtensions.Super.ShouldNotCall
|
||||||
|
@ -56,12 +56,15 @@ import androidx.compose.ui.semantics.semantics
|
|||||||
import androidx.compose.ui.semantics.testTag
|
import androidx.compose.ui.semantics.testTag
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import org.kiwix.kiwixmobile.core.R.string
|
import org.kiwix.kiwixmobile.core.R.string
|
||||||
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||||
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.OnBackPressed
|
||||||
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
|
||||||
@ -99,6 +102,8 @@ fun OnlineLibraryScreen(
|
|||||||
actionMenuItems: List<ActionMenuItem>,
|
actionMenuItems: List<ActionMenuItem>,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
bottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
||||||
|
onUserBackPressed: () -> FragmentActivityExtensions.Super,
|
||||||
|
navHostController: NavHostController,
|
||||||
navigationIcon: @Composable () -> Unit,
|
navigationIcon: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
@ -135,6 +140,7 @@ fun OnlineLibraryScreen(
|
|||||||
end = paddingValues.calculateEndPadding(LocalLayoutDirection.current),
|
end = paddingValues.calculateEndPadding(LocalLayoutDirection.current),
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
OnBackPressed(onUserBackPressed, navHostController)
|
||||||
OnlineLibraryScreenContent(state, listState)
|
OnlineLibraryScreenContent(state, listState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:enableOnBackInvokedCallback="false"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:hasFragileUserData="true"
|
android:hasFragileUserData="true"
|
||||||
|
@ -24,7 +24,6 @@ import android.os.Process
|
|||||||
import android.view.ActionMode
|
import android.view.ActionMode
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
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.BottomAppBarScrollBehavior
|
||||||
@ -38,7 +37,6 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import com.google.android.material.navigation.NavigationView
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -47,7 +45,6 @@ import org.kiwix.kiwixmobile.core.CoreApp
|
|||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall
|
|
||||||
import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToLibkiwixMigrator
|
import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToLibkiwixMigrator
|
||||||
import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToRoomMigrator
|
import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToRoomMigrator
|
||||||
import org.kiwix.kiwixmobile.core.di.components.CoreActivityComponent
|
import org.kiwix.kiwixmobile.core.di.components.CoreActivityComponent
|
||||||
@ -144,6 +141,11 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
*/
|
*/
|
||||||
val enableLeftDrawer = mutableStateOf(true)
|
val enableLeftDrawer = mutableStateOf(true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For managing the back press of fragments.
|
||||||
|
*/
|
||||||
|
val customBackHandler = mutableStateOf<(() -> FragmentActivityExtensions.Super)?>(null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For managing the the showing/hiding the bottomAppBar when scrolling.
|
* For managing the the showing/hiding the bottomAppBar when scrolling.
|
||||||
*/
|
*/
|
||||||
@ -197,7 +199,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
createApplicationShortcuts()
|
createApplicationShortcuts()
|
||||||
}
|
}
|
||||||
handleBackPressed()
|
|
||||||
leftDrawerMenu.addAll(leftNavigationDrawerMenuItems)
|
leftDrawerMenu.addAll(leftNavigationDrawerMenuItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,11 +232,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
onBackPressedCallBack.remove()
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
startMonitoringDownloads()
|
startMonitoringDownloads()
|
||||||
downloadMonitor.stopListeningDownloads()
|
downloadMonitor.stopListeningDownloads()
|
||||||
@ -253,11 +249,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UnusedParameter")
|
|
||||||
private fun NavigationView.setLockMode(lockMode: Int) {
|
|
||||||
// drawerContainerLayout.setDrawerLockMode(lockMode, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(
|
||||||
requestCode: Int,
|
requestCode: Int,
|
||||||
@ -339,41 +330,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
externalLinkOpener.openExternalUrl(KIWIX_SUPPORT_URL.toUri().browserIntent(), false)
|
externalLinkOpener.openExternalUrl(KIWIX_SUPPORT_URL.toUri().browserIntent(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBackPressed() {
|
|
||||||
onBackPressedDispatcher.addCallback(this, onBackPressedCallBack)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val onBackPressedCallBack =
|
|
||||||
object : OnBackPressedCallback(true) {
|
|
||||||
override fun handleOnBackPressed() {
|
|
||||||
if (navigationDrawerIsOpen()) {
|
|
||||||
closeNavigationDrawer()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (activeFragments().filterIsInstance<FragmentActivityExtensions>().isEmpty()) {
|
|
||||||
isEnabled = false
|
|
||||||
return onBackPressedDispatcher.onBackPressed().also {
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
activeFragments().filterIsInstance<FragmentActivityExtensions>().forEach {
|
|
||||||
if (it.onBackPressed(this@CoreMainActivity) == ShouldCall) {
|
|
||||||
if (navController.currentDestination?.route?.equals(readerFragmentRoute) == true &&
|
|
||||||
navController.previousBackStackEntry?.destination
|
|
||||||
?.route?.equals(searchFragmentRoute) == false
|
|
||||||
) {
|
|
||||||
drawerToggle = null
|
|
||||||
finish()
|
|
||||||
} else {
|
|
||||||
isEnabled = false
|
|
||||||
onBackPressedDispatcher.onBackPressed()
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
if (activeFragments().filterIsInstance<FragmentActivityExtensions>().isEmpty()) {
|
if (activeFragments().filterIsInstance<FragmentActivityExtensions>().isEmpty()) {
|
||||||
return super.onCreateOptionsMenu(menu)
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Kiwix Android
|
|
||||||
* Copyright (c) 2020 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.graphics.Typeface
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.RecyclerView.Adapter
|
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
|
||||||
import org.kiwix.kiwixmobile.core.R
|
|
||||||
import org.kiwix.kiwixmobile.core.base.adapter.BaseViewHolder
|
|
||||||
import org.kiwix.kiwixmobile.core.databinding.SectionListBinding
|
|
||||||
|
|
||||||
class TableDrawerAdapter constructor(
|
|
||||||
private val listener: TableClickListener
|
|
||||||
) : Adapter<ViewHolder>() {
|
|
||||||
private var title: String = ""
|
|
||||||
private val sections: MutableList<DocumentSection> = mutableListOf()
|
|
||||||
|
|
||||||
fun setSections(sections: List<DocumentSection>) {
|
|
||||||
this.sections.clear()
|
|
||||||
this.sections.addAll(sections)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(title: String) {
|
|
||||||
this.title = title
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
|
||||||
return if (position == 0) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(
|
|
||||||
parent: ViewGroup,
|
|
||||||
viewType: Int
|
|
||||||
): ViewHolder {
|
|
||||||
val binding = SectionListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
|
||||||
return if (viewType == 0) {
|
|
||||||
HeaderTableDrawerViewHolder(binding)
|
|
||||||
} else {
|
|
||||||
SectionTableDrawerViewHolder(binding)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int = sections.size + 1
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
when (holder) {
|
|
||||||
is HeaderTableDrawerViewHolder -> {
|
|
||||||
holder.bind(title)
|
|
||||||
holder.itemView.setOnClickListener(listener::onHeaderClick)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SectionTableDrawerViewHolder -> {
|
|
||||||
val titleAdjustedPosition = position - 1
|
|
||||||
holder.bind(sections[titleAdjustedPosition])
|
|
||||||
holder.itemView.setOnClickListener {
|
|
||||||
listener.onSectionClick(it, titleAdjustedPosition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
throw IllegalStateException("Unknown ViewHolder $holder found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TableClickListener {
|
|
||||||
fun onHeaderClick(view: View?)
|
|
||||||
fun onSectionClick(view: View?, position: Int)
|
|
||||||
}
|
|
||||||
|
|
||||||
class HeaderTableDrawerViewHolder(private val sectionListBinding: SectionListBinding) :
|
|
||||||
BaseViewHolder<String>(sectionListBinding.root) {
|
|
||||||
override fun bind(item: String) {
|
|
||||||
val context = itemView.context
|
|
||||||
sectionListBinding.titleText.typeface = Typeface.DEFAULT_BOLD
|
|
||||||
sectionListBinding.titleText.text =
|
|
||||||
when {
|
|
||||||
item.isNotEmpty() -> item
|
|
||||||
context is WebViewProvider ->
|
|
||||||
context.getCurrentWebView()?.title
|
|
||||||
?: context.getString(R.string.no_section_info)
|
|
||||||
|
|
||||||
else -> context.getString(R.string.no_section_info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SectionTableDrawerViewHolder(private val sectionListBinding: SectionListBinding) :
|
|
||||||
BaseViewHolder<TableDrawerAdapter.DocumentSection>(sectionListBinding.root) {
|
|
||||||
override fun bind(
|
|
||||||
item: TableDrawerAdapter.DocumentSection
|
|
||||||
) {
|
|
||||||
val context = itemView.context
|
|
||||||
val padding =
|
|
||||||
((item.level - 1) * context.resources.getDimension(R.dimen.title_text_padding)).toInt()
|
|
||||||
sectionListBinding.titleText.setPadding(padding, 0, 0, 0)
|
|
||||||
sectionListBinding.titleText.text = item.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class DocumentSection(var title: String, var id: String, var level: Int)
|
|
||||||
}
|
|
@ -474,7 +474,9 @@ abstract class CoreReaderFragment :
|
|||||||
},
|
},
|
||||||
mainActivityBottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour,
|
mainActivityBottomAppBarScrollBehaviour = (requireActivity() as CoreMainActivity).bottomAppBarScrollBehaviour,
|
||||||
documentSections = documentSections,
|
documentSections = documentSections,
|
||||||
showTableOfContentDrawer = shouldTableOfContentDrawer
|
showTableOfContentDrawer = shouldTableOfContentDrawer,
|
||||||
|
onUserBackPressed = { onUserBackPressed(requireActivity() as CoreMainActivity) },
|
||||||
|
navHostController = (requireActivity() as CoreMainActivity).navController
|
||||||
)
|
)
|
||||||
DialogHost(alertDialogShower as AlertDialogShower)
|
DialogHost(alertDialogShower as AlertDialogShower)
|
||||||
}
|
}
|
||||||
@ -842,9 +844,16 @@ abstract class CoreReaderFragment :
|
|||||||
shouldTableOfContentDrawer.update { true }
|
shouldTableOfContentDrawer.update { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ReturnCount", "NestedBlockDepth")
|
@Suppress("ReturnCount", "NestedBlockDepth", "LongMethod", "CyclomaticComplexMethod")
|
||||||
override fun onBackPressed(activity: AppCompatActivity): FragmentActivityExtensions.Super {
|
private fun onUserBackPressed(coreMainActivity: CoreMainActivity): FragmentActivityExtensions.Super {
|
||||||
when {
|
when {
|
||||||
|
coreMainActivity.leftDrawerState.isOpen -> {
|
||||||
|
coreMainActivity.uiCoroutineScope.launch {
|
||||||
|
coreMainActivity.leftDrawerState.close()
|
||||||
|
}
|
||||||
|
return FragmentActivityExtensions.Super.ShouldNotCall
|
||||||
|
}
|
||||||
|
|
||||||
readerScreenState.value.showTabSwitcher -> {
|
readerScreenState.value.showTabSwitcher -> {
|
||||||
selectTab(
|
selectTab(
|
||||||
if (currentWebViewIndex < webViewList.size) {
|
if (currentWebViewIndex < webViewList.size) {
|
||||||
@ -893,7 +902,12 @@ abstract class CoreReaderFragment :
|
|||||||
isHomePageOfServiceWorkerZimFiles(url, webViewBackWordHistoryList)
|
isHomePageOfServiceWorkerZimFiles(url, webViewBackWordHistoryList)
|
||||||
) {
|
) {
|
||||||
// If it is the last page that is showing to the user, then exit the application.
|
// If it is the last page that is showing to the user, then exit the application.
|
||||||
return@onBackPressed FragmentActivityExtensions.Super.ShouldCall
|
if (coreMainActivity.navController.previousBackStackEntry?.destination?.route !=
|
||||||
|
coreMainActivity.searchFragmentRoute
|
||||||
|
) {
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
return FragmentActivityExtensions.Super.ShouldCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise, go to the previous page.
|
// Otherwise, go to the previous page.
|
||||||
|
@ -22,6 +22,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
@ -114,9 +115,11 @@ import androidx.compose.ui.unit.Dp
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED
|
import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED
|
||||||
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
||||||
import org.kiwix.kiwixmobile.core.extensions.update
|
import org.kiwix.kiwixmobile.core.extensions.update
|
||||||
@ -177,13 +180,15 @@ const val READER_BOTTOM_BAR_TABLE_CONTENT_BUTTON_TESTING_TAG =
|
|||||||
"readerBottomBarTableContentButtonTestingTag"
|
"readerBottomBarTableContentButtonTestingTag"
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Suppress("ComposableLambdaParameterNaming", "LongMethod")
|
@Suppress("ComposableLambdaParameterNaming", "LongMethod", "LongParameterList")
|
||||||
@Composable
|
@Composable
|
||||||
fun ReaderScreen(
|
fun ReaderScreen(
|
||||||
state: ReaderScreenState,
|
state: ReaderScreenState,
|
||||||
actionMenuItems: List<ActionMenuItem>,
|
actionMenuItems: List<ActionMenuItem>,
|
||||||
showTableOfContentDrawer: MutableState<Boolean>,
|
showTableOfContentDrawer: MutableState<Boolean>,
|
||||||
documentSections: MutableList<DocumentSection>?,
|
documentSections: MutableList<DocumentSection>?,
|
||||||
|
onUserBackPressed: () -> FragmentActivityExtensions.Super,
|
||||||
|
navHostController: NavHostController,
|
||||||
mainActivityBottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
mainActivityBottomAppBarScrollBehaviour: BottomAppBarScrollBehavior?,
|
||||||
navigationIcon: @Composable () -> Unit
|
navigationIcon: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
@ -215,6 +220,7 @@ fun ReaderScreen(
|
|||||||
}
|
}
|
||||||
.semantics { testTag = READER_SCREEN_TESTING_TAG }
|
.semantics { testTag = READER_SCREEN_TESTING_TAG }
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
OnBackPressed(onUserBackPressed, navHostController)
|
||||||
ReaderContentLayout(
|
ReaderContentLayout(
|
||||||
state,
|
state,
|
||||||
Modifier.padding(paddingValues),
|
Modifier.padding(paddingValues),
|
||||||
@ -251,6 +257,19 @@ fun ReaderScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OnBackPressed(
|
||||||
|
onUserBackPressed: () -> FragmentActivityExtensions.Super,
|
||||||
|
navHostController: NavHostController
|
||||||
|
) {
|
||||||
|
BackHandler(enabled = true) {
|
||||||
|
val result = onUserBackPressed()
|
||||||
|
if (result == FragmentActivityExtensions.Super.ShouldCall) {
|
||||||
|
navHostController.popBackStack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Suppress("ComposableLambdaParameterNaming")
|
@Suppress("ComposableLambdaParameterNaming")
|
||||||
@Composable
|
@Composable
|
||||||
@ -731,7 +750,8 @@ private fun BottomAppBarButtonIcon(
|
|||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
enabled = shouldEnable
|
enabled = shouldEnable
|
||||||
).testTag(testingTag),
|
)
|
||||||
|
.testTag(testingTag),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -22,7 +22,7 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
@ -39,6 +39,7 @@ import kotlinx.coroutines.withContext
|
|||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
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.extensions.ActivityExtensions.cachedComponent
|
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
|
||||||
import org.kiwix.kiwixmobile.core.extensions.closeKeyboard
|
import org.kiwix.kiwixmobile.core.extensions.closeKeyboard
|
||||||
import org.kiwix.kiwixmobile.core.extensions.coreMainActivity
|
import org.kiwix.kiwixmobile.core.extensions.coreMainActivity
|
||||||
@ -123,6 +124,12 @@ class SearchFragment : BaseFragment() {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
composeView?.apply {
|
composeView?.apply {
|
||||||
setContent {
|
setContent {
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
(activity as CoreMainActivity).customBackHandler.value = { handleBackPress() }
|
||||||
|
onDispose {
|
||||||
|
(activity as CoreMainActivity).customBackHandler.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
SearchScreen(
|
SearchScreen(
|
||||||
searchScreenState.value,
|
searchScreenState.value,
|
||||||
actionMenuItems(),
|
actionMenuItems(),
|
||||||
@ -134,7 +141,6 @@ class SearchFragment : BaseFragment() {
|
|||||||
searchViewModel.setAlertDialogShower(dialogShower as AlertDialogShower)
|
searchViewModel.setAlertDialogShower(dialogShower as AlertDialogShower)
|
||||||
observeViewModelData()
|
observeViewModelData()
|
||||||
handleSearchArgument()
|
handleSearchArgument()
|
||||||
handleBackPress()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSearchArgument() {
|
private fun handleSearchArgument() {
|
||||||
@ -203,15 +209,9 @@ class SearchFragment : BaseFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBackPress() {
|
private fun handleBackPress(): FragmentActivityExtensions.Super {
|
||||||
activity?.onBackPressedDispatcher?.addCallback(
|
goBack()
|
||||||
viewLifecycleOwner,
|
return FragmentActivityExtensions.Super.ShouldCall
|
||||||
object : OnBackPressedCallback(true) {
|
|
||||||
override fun handleOnBackPressed() {
|
|
||||||
goBack()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -71,7 +71,9 @@ class CustomMainActivity : CoreMainActivity() {
|
|||||||
leftDrawerContent = leftDrawerMenu,
|
leftDrawerContent = leftDrawerMenu,
|
||||||
topLevelDestinationsRoute = topLevelDestinationsRoute,
|
topLevelDestinationsRoute = topLevelDestinationsRoute,
|
||||||
leftDrawerState = leftDrawerState,
|
leftDrawerState = leftDrawerState,
|
||||||
enableLeftDrawer = enableLeftDrawer.value
|
enableLeftDrawer = enableLeftDrawer.value,
|
||||||
|
uiCoroutineScope = uiCoroutineScope,
|
||||||
|
customBackHandler = customBackHandler
|
||||||
)
|
)
|
||||||
DialogHost(alertDialogShower)
|
DialogHost(alertDialogShower)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.custom.main
|
package org.kiwix.kiwixmobile.custom.main
|
||||||
|
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
|
import androidx.activity.compose.LocalActivity
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@ -27,10 +29,14 @@ import androidx.compose.material3.DrawerState
|
|||||||
import androidx.compose.material3.ModalNavigationDrawer
|
import androidx.compose.material3.ModalNavigationDrawer
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||||
import org.kiwix.kiwixmobile.core.main.DrawerMenuGroup
|
import org.kiwix.kiwixmobile.core.main.DrawerMenuGroup
|
||||||
import org.kiwix.kiwixmobile.core.main.LeftDrawerMenu
|
import org.kiwix.kiwixmobile.core.main.LeftDrawerMenu
|
||||||
import org.kiwix.kiwixmobile.core.ui.theme.KiwixTheme
|
import org.kiwix.kiwixmobile.core.ui.theme.KiwixTheme
|
||||||
@ -42,9 +48,18 @@ fun CustomMainActivityScreen(
|
|||||||
topLevelDestinationsRoute: Set<String>,
|
topLevelDestinationsRoute: Set<String>,
|
||||||
leftDrawerState: DrawerState,
|
leftDrawerState: DrawerState,
|
||||||
enableLeftDrawer: Boolean,
|
enableLeftDrawer: Boolean,
|
||||||
|
customBackHandler: MutableState<(() -> FragmentActivityExtensions.Super)?>,
|
||||||
|
uiCoroutineScope: CoroutineScope
|
||||||
) {
|
) {
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val currentRoute = navBackStackEntry?.destination?.route
|
val currentRoute = navBackStackEntry?.destination?.route
|
||||||
|
OnUserBackPressed(
|
||||||
|
leftDrawerState,
|
||||||
|
uiCoroutineScope,
|
||||||
|
currentRoute,
|
||||||
|
navController,
|
||||||
|
customBackHandler
|
||||||
|
)
|
||||||
KiwixTheme {
|
KiwixTheme {
|
||||||
ModalNavigationDrawer(
|
ModalNavigationDrawer(
|
||||||
drawerState = leftDrawerState,
|
drawerState = leftDrawerState,
|
||||||
@ -76,3 +91,34 @@ fun CustomMainActivityScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun OnUserBackPressed(
|
||||||
|
leftDrawerState: DrawerState,
|
||||||
|
uiCoroutineScope: CoroutineScope,
|
||||||
|
currentRoute: String?,
|
||||||
|
navController: NavHostController,
|
||||||
|
customBackHandler: MutableState<(() -> FragmentActivityExtensions.Super)?>,
|
||||||
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
BackHandler(enabled = true) {
|
||||||
|
when {
|
||||||
|
leftDrawerState.isOpen -> uiCoroutineScope.launch { leftDrawerState.close() }
|
||||||
|
customBackHandler.value?.invoke() == FragmentActivityExtensions.Super.ShouldNotCall -> {
|
||||||
|
// do nothing since fragment handles the back press.
|
||||||
|
}
|
||||||
|
|
||||||
|
currentRoute == CustomDestination.Reader.route &&
|
||||||
|
navController.previousBackStackEntry?.destination?.route != CustomDestination.Search.route -> {
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val popped = navController.popBackStack()
|
||||||
|
if (!popped) {
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user