Added support to reflect locale changes: when the application language changes, all UI now updates automatically to the selected language in a Compose-friendly way. Introduced a Compose-based approach to enable or disable the left drawer, simplifying drawer state management.

This commit is contained in:
MohitMaliFtechiz 2025-07-22 03:32:52 +05:30
parent a3d6ea49f9
commit edae60fa52
10 changed files with 112 additions and 123 deletions

View File

@ -23,12 +23,15 @@ import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log
import android.view.MenuItem 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.DrawerValue
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.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
@ -36,7 +39,6 @@ import androidx.core.os.ConfigurationCompat
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import eu.mhutti1.utils.storage.StorageDevice import eu.mhutti1.utils.storage.StorageDevice
import eu.mhutti1.utils.storage.StorageDeviceUtils import eu.mhutti1.utils.storage.StorageDeviceUtils
@ -97,9 +99,12 @@ class KiwixMainActivity : CoreMainActivity() {
override val notesFragmentRoute: String = KiwixDestination.Notes.route override val notesFragmentRoute: String = KiwixDestination.Notes.route
override val readerFragmentRoute: String = KiwixDestination.Reader.route override val readerFragmentRoute: String = KiwixDestination.Reader.route
override val helpFragmentRoute: String = KiwixDestination.Help.route override val helpFragmentRoute: String = KiwixDestination.Help.route
override val topLevelDestinations = override val topLevelDestinationsRoute =
setOf(R.id.downloadsFragment, R.id.libraryFragment, R.id.readerFragment) setOf(
private val isBottomBarVisible = mutableStateOf(true) KiwixDestination.Downloads.route,
KiwixDestination.Library.route,
KiwixDestination.Reader.route
)
// private lateinit var activityKiwixMainBinding: ActivityKiwixMainBinding // private lateinit var activityKiwixMainBinding: ActivityKiwixMainBinding
@ -116,20 +121,18 @@ class KiwixMainActivity : CoreMainActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
navController = rememberNavController() navController = rememberNavController()
leftDrawerState = rememberDrawerState(DrawerValue.Closed)
uiCoroutineScope = rememberCoroutineScope()
KiwixMainActivityScreen( KiwixMainActivityScreen(
navController = navController, navController = navController,
isBottomBarVisible = isBottomBarVisible.value, leftDrawerContent = leftDrawerMenu,
leftDrawerContent = leftNavigationDrawerMenuItems, topLevelDestinationsRoute = topLevelDestinationsRoute,
rightDrawerContent = { } leftDrawerState = leftDrawerState,
uiCoroutineScope = uiCoroutineScope,
enableLeftDrawer = enableLeftDrawer.value
) )
LaunchedEffect(navController) { LaunchedEffect(navController) {
navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange) navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange)
navController.addOnDestinationChangedListener { _, destination, _ ->
isBottomBarVisible.value = destination.id in topLevelDestinations
if (destination.id !in topLevelDestinations) {
handleDrawerOnNavigation()
}
}
} }
} }
// activityKiwixMainBinding.drawerNavView.apply { // activityKiwixMainBinding.drawerNavView.apply {
@ -181,34 +184,9 @@ class KiwixMainActivity : CoreMainActivity() {
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
// if (::activityKiwixMainBinding.isInitialized) { Log.e("CONFIGURATION", "onConfigurationChanged: ")
// activityKiwixMainBinding.bottomNavView.menu.apply { leftDrawerMenu.clear()
// findItem(R.id.readerFragment)?.title = resources.getString(string.reader) leftDrawerMenu.addAll(leftNavigationDrawerMenuItems)
// findItem(R.id.libraryFragment)?.title = resources.getString(string.library)
// findItem(R.id.downloadsFragment)?.title = resources.getString(string.download)
// }
// activityKiwixMainBinding.drawerNavView.menu.apply {
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_bookmarks_list)?.title =
// resources.getString(string.bookmarks)
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_history)?.title =
// resources.getString(string.history)
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_notes)?.title =
// resources.getString(string.pref_notes)
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_host_books)?.title =
// resources.getString(string.menu_wifi_hotspot)
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_settings)?.title =
// resources.getString(string.menu_settings)
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_help)?.title =
// resources.getString(string.menu_help)
// findItem(org.kiwix.kiwixmobile.core.R.id.menu_support_kiwix)?.title =
// resources.getString(string.menu_support_kiwix)
// }
// }
}
override fun configureActivityBasedOn(destination: NavDestination) {
super.configureActivityBasedOn(destination)
isBottomBarVisible.value = destination.id in topLevelDestinations
} }
override fun onStart() { override fun onStart() {
@ -340,21 +318,21 @@ class KiwixMainActivity : CoreMainActivity() {
override val zimHostDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem( override val zimHostDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem(
title = CoreApp.instance.getString(string.menu_wifi_hotspot), title = CoreApp.instance.getString(string.menu_wifi_hotspot),
iconRes = drawable.ic_mobile_screen_share_24px, iconRes = drawable.ic_mobile_screen_share_24px,
true, visible = true,
onClick = { openZimHostFragment() } onClick = { openZimHostFragment() }
) )
override val helpDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem( override val helpDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem(
title = CoreApp.instance.getString(string.menu_help), title = CoreApp.instance.getString(string.menu_help),
iconRes = drawable.ic_help_24px, iconRes = drawable.ic_help_24px,
true, visible = true,
onClick = { openHelpFragment() } onClick = { openHelpFragment() }
) )
override val supportDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem( override val supportDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem(
title = CoreApp.instance.getString(string.menu_support_kiwix), title = CoreApp.instance.getString(string.menu_support_kiwix),
iconRes = drawable.ic_support_24px, iconRes = drawable.ic_support_24px,
true, visible = true,
onClick = { openSupportKiwixExternalLink() } onClick = { openSupportKiwixExternalLink() }
) )
@ -365,6 +343,7 @@ class KiwixMainActivity : CoreMainActivity() {
private fun openZimHostFragment() { private fun openZimHostFragment() {
disableDrawer() disableDrawer()
handleDrawerOnNavigation()
navigate(KiwixDestination.ZimHost.route) navigate(KiwixDestination.ZimHost.route)
} }

View File

@ -20,32 +20,28 @@ package org.kiwix.kiwixmobile.main
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.ColumnScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.BottomAppBar import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.BottomAppBarDefaults import androidx.compose.material3.BottomAppBarDefaults
import androidx.compose.material3.BottomAppBarScrollBehavior import androidx.compose.material3.BottomAppBarScrollBehavior
import androidx.compose.material3.DrawerValue import androidx.compose.material3.DrawerState
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.navigation.NavBackStackEntry
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.R.drawable import org.kiwix.kiwixmobile.R.drawable
import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.main.DrawerMenuGroup import org.kiwix.kiwixmobile.core.main.DrawerMenuGroup
@ -53,7 +49,6 @@ import org.kiwix.kiwixmobile.core.main.LeftDrawerMenu
import org.kiwix.kiwixmobile.core.ui.theme.Black 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.NAVIGATION_DRAWER_WIDTH
import org.kiwix.kiwixmobile.ui.KiwixDestination import org.kiwix.kiwixmobile.ui.KiwixDestination
import org.kiwix.kiwixmobile.ui.KiwixNavGraph import org.kiwix.kiwixmobile.ui.KiwixNavGraph
@ -62,29 +57,35 @@ import org.kiwix.kiwixmobile.ui.KiwixNavGraph
fun KiwixMainActivityScreen( fun KiwixMainActivityScreen(
navController: NavHostController, navController: NavHostController,
leftDrawerContent: List<DrawerMenuGroup>, leftDrawerContent: List<DrawerMenuGroup>,
rightDrawerContent: @Composable ColumnScope.() -> Unit, topLevelDestinationsRoute: Set<String>,
isBottomBarVisible: Boolean = true leftDrawerState: DrawerState,
uiCoroutineScope: CoroutineScope,
enableLeftDrawer: Boolean
) { ) {
val rightDrawerState = rememberDrawerState(DrawerValue.Closed) val navBackStackEntry by navController.currentBackStackEntryAsState()
val coroutineScope = rememberCoroutineScope()
val scrollingBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior() val scrollingBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
KiwixTheme { KiwixTheme {
ModalNavigationDrawer( ModalNavigationDrawer(
drawerState = leftDrawerState,
drawerContent = { drawerContent = {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
LeftDrawerMenu(leftDrawerContent) LeftDrawerMenu(leftDrawerContent)
} }
} },
gesturesEnabled = enableLeftDrawer && navBackStackEntry?.destination?.route in topLevelDestinationsRoute
) { ) {
Box { Box {
Scaffold( Scaffold(
bottomBar = { bottomBar = {
// if (isBottomBarVisible) { if (navBackStackEntry?.destination?.route in topLevelDestinationsRoute) {
BottomNavigationBar( BottomNavigationBar(
navController = navController, navController = navController,
scrollBehavior = scrollingBehavior scrollBehavior = scrollingBehavior,
) navBackStackEntry = navBackStackEntry,
// } leftDrawerState = leftDrawerState,
uiCoroutineScope = uiCoroutineScope
)
}
} }
) { paddingValues -> ) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) { Box(modifier = Modifier.padding(paddingValues)) {
@ -94,17 +95,6 @@ fun KiwixMainActivityScreen(
) )
} }
} }
// Right drawer overlay
ModalDrawerSheet(
drawerState = rightDrawerState,
modifier = Modifier
.fillMaxHeight()
.align(Alignment.CenterEnd)
.width(NAVIGATION_DRAWER_WIDTH)
) {
rightDrawerContent()
}
} }
} }
} }
@ -114,7 +104,10 @@ fun KiwixMainActivityScreen(
@Composable @Composable
fun BottomNavigationBar( fun BottomNavigationBar(
navController: NavHostController, navController: NavHostController,
scrollBehavior: BottomAppBarScrollBehavior scrollBehavior: BottomAppBarScrollBehavior,
navBackStackEntry: NavBackStackEntry?,
leftDrawerState: DrawerState,
uiCoroutineScope: CoroutineScope
) { ) {
val bottomNavItems = listOf( val bottomNavItems = listOf(
BottomNavItem( BottomNavItem(
@ -133,8 +126,6 @@ fun BottomNavigationBar(
iconRes = drawable.ic_download_navigation_white_24dp iconRes = drawable.ic_download_navigation_white_24dp
) )
) )
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestinationRoute = navBackStackEntry?.destination?.route val currentDestinationRoute = navBackStackEntry?.destination?.route
BottomAppBar( BottomAppBar(
containerColor = Black, containerColor = Black,
@ -144,7 +135,12 @@ fun BottomNavigationBar(
bottomNavItems.forEach { item -> bottomNavItems.forEach { item ->
NavigationBarItem( NavigationBarItem(
selected = currentDestinationRoute == item.route, selected = currentDestinationRoute == item.route,
onClick = { navController.navigate(item.route) }, onClick = {
uiCoroutineScope.launch {
leftDrawerState.close()
navController.navigate(item.route)
}
},
icon = { icon = {
Icon( Icon(
painter = painterResource(id = item.iconRes), painter = painterResource(id = item.iconRes),

View File

@ -51,7 +51,6 @@ 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 com.google.android.material.bottomnavigation.BottomNavigationView
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
@ -69,9 +68,7 @@ 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
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
import org.kiwix.kiwixmobile.core.extensions.coreMainActivity
import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.extensions.isFileExist
import org.kiwix.kiwixmobile.core.extensions.setBottomMarginToFragmentContainerView
import org.kiwix.kiwixmobile.core.extensions.snack import org.kiwix.kiwixmobile.core.extensions.snack
import org.kiwix.kiwixmobile.core.extensions.toast import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
@ -100,6 +97,7 @@ import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.BooksOnDiskListIte
import org.kiwix.kiwixmobile.main.KiwixMainActivity import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.nav.destination.library.CopyMoveFileHandler import org.kiwix.kiwixmobile.nav.destination.library.CopyMoveFileHandler
import org.kiwix.kiwixmobile.storage.StorageSelectDialog import org.kiwix.kiwixmobile.storage.StorageSelectDialog
import org.kiwix.kiwixmobile.ui.KiwixDestination
import org.kiwix.kiwixmobile.zimManager.MAX_PROGRESS import org.kiwix.kiwixmobile.zimManager.MAX_PROGRESS
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions
@ -649,7 +647,7 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
} }
private fun navigateToLocalFileTransferFragment() { private fun navigateToLocalFileTransferFragment() {
requireActivity().navigate(R.id.localFileTransferFragment) requireActivity().navigate(KiwixDestination.LocalFileTransfer.route)
} }
private fun shouldShowRationalePermission() = private fun shouldShowRationalePermission() =

View File

@ -65,9 +65,7 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.navigate
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.requestNotificationPermission import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.requestNotificationPermission
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
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.isKeyboardVisible import org.kiwix.kiwixmobile.core.extensions.isKeyboardVisible
import org.kiwix.kiwixmobile.core.extensions.setBottomMarginToFragmentContainerView
import org.kiwix.kiwixmobile.core.extensions.snack import org.kiwix.kiwixmobile.core.extensions.snack
import org.kiwix.kiwixmobile.core.extensions.toast import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.extensions.update import org.kiwix.kiwixmobile.core.extensions.update
@ -95,6 +93,7 @@ import org.kiwix.kiwixmobile.core.zim_manager.NetworkState
import org.kiwix.kiwixmobile.main.KiwixMainActivity import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.storage.STORAGE_SELECT_STORAGE_TITLE_TEXTVIEW_SIZE import org.kiwix.kiwixmobile.storage.STORAGE_SELECT_STORAGE_TITLE_TEXTVIEW_SIZE
import org.kiwix.kiwixmobile.storage.StorageSelectDialog import org.kiwix.kiwixmobile.storage.StorageSelectDialog
import org.kiwix.kiwixmobile.ui.KiwixDestination
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.OnlineLibraryRequest import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.OnlineLibraryRequest
import org.kiwix.kiwixmobile.zimManager.libraryView.AvailableSpaceCalculator import org.kiwix.kiwixmobile.zimManager.libraryView.AvailableSpaceCalculator
@ -394,7 +393,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
) )
private fun onLanguageMenuIconClick() { private fun onLanguageMenuIconClick() {
requireActivity().navigate(org.kiwix.kiwixmobile.R.id.languageFragment) requireActivity().navigate(KiwixDestination.Language.route)
closeKeyboard() closeKeyboard()
} }

View File

@ -24,15 +24,12 @@ import android.os.Looper
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.View import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.cachedComponent 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
@ -40,9 +37,7 @@ import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle
import org.kiwix.kiwixmobile.core.extensions.coreMainActivity
import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.extensions.isFileExist
import org.kiwix.kiwixmobile.core.extensions.setBottomMarginToFragmentContainerView
import org.kiwix.kiwixmobile.core.extensions.snack import org.kiwix.kiwixmobile.core.extensions.snack
import org.kiwix.kiwixmobile.core.extensions.toast import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.extensions.update import org.kiwix.kiwixmobile.core.extensions.update
@ -55,7 +50,6 @@ import org.kiwix.kiwixmobile.core.main.reader.RestoreOrigin.FromSearchScreen
import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue
import org.kiwix.kiwixmobile.core.utils.DimenUtils.getToolbarHeight
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE 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

View File

@ -103,8 +103,8 @@ object ActivityExtensions {
fun Activity.setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) = fun Activity.setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) =
coreMainActivity.setupDrawerToggle(shouldEnableRightDrawer) coreMainActivity.setupDrawerToggle(shouldEnableRightDrawer)
fun Activity.navigate(fragmentId: Int) { fun Activity.navigate(route: String) {
coreMainActivity.navigate(fragmentId) coreMainActivity.navigate(route)
} }
fun Activity.navigate(fragmentId: Int, bundle: Bundle) { fun Activity.navigate(fragmentId: Int, bundle: Bundle) {

View File

@ -27,8 +27,10 @@ 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.DrawerState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
@ -56,10 +58,7 @@ import org.kiwix.kiwixmobile.core.extensions.browserIntent
import org.kiwix.kiwixmobile.core.extensions.isServiceRunning import org.kiwix.kiwixmobile.core.extensions.isServiceRunning
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.search.NAV_ARG_SEARCH_STRING
import org.kiwix.kiwixmobile.core.utils.EXTRA_IS_WIDGET_VOICE
import org.kiwix.kiwixmobile.core.utils.ExternalLinkOpener import org.kiwix.kiwixmobile.core.utils.ExternalLinkOpener
import org.kiwix.kiwixmobile.core.utils.TAG_FROM_TAB_SWITCHER
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
import org.kiwix.kiwixmobile.core.utils.dialog.RateDialogHandler import org.kiwix.kiwixmobile.core.utils.dialog.RateDialogHandler
import javax.inject.Inject import javax.inject.Inject
@ -92,6 +91,25 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
*/ */
lateinit var navController: NavHostController lateinit var navController: NavHostController
/**
* For managing the leftDrawer.
*/
lateinit var leftDrawerState: DrawerState
/**
* The compose coroutine scope for calling the compose based UI elements in coroutine scope.
* Such as opening/closing leftDrawer.
*/
lateinit var uiCoroutineScope: CoroutineScope
/**
* Managing the leftDrawerMenu in compose way so that when app's language changed
* it will update the text in selected language.
*/
protected val leftDrawerMenu = mutableStateListOf<DrawerMenuGroup>()
protected val enableLeftDrawer = mutableStateOf(true)
// abstract val drawerContainerLayout: DrawerLayout // abstract val drawerContainerLayout: DrawerLayout
// abstract val drawerNavView: NavigationView // abstract val drawerNavView: NavigationView
// abstract val readerTableOfContentsDrawer: NavigationView // abstract val readerTableOfContentsDrawer: NavigationView
@ -101,7 +119,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
abstract val notesFragmentRoute: String abstract val notesFragmentRoute: String
abstract val helpFragmentRoute: String abstract val helpFragmentRoute: String
abstract val cachedComponent: CoreActivityComponent abstract val cachedComponent: CoreActivityComponent
abstract val topLevelDestinations: Set<Int> abstract val topLevelDestinationsRoute: Set<String>
// abstract val navHostContainer: FragmentContainerView // abstract val navHostContainer: FragmentContainerView
abstract val mainActivity: AppCompatActivity abstract val mainActivity: AppCompatActivity
@ -146,6 +164,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
createApplicationShortcuts() createApplicationShortcuts()
} }
handleBackPressed() handleBackPressed()
leftDrawerMenu.addAll(leftNavigationDrawerMenuItems)
} }
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@ -205,9 +224,9 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
} }
open fun configureActivityBasedOn(destination: NavDestination) { open fun configureActivityBasedOn(destination: NavDestination) {
if (destination.id !in topLevelDestinations) { // if (destination.id !in topLevelDestinations) {
handleDrawerOnNavigation() // handleDrawerOnNavigation()
} // }
// readerTableOfContentsDrawer.setLockMode( // readerTableOfContentsDrawer.setLockMode(
// if (destination.id == readerFragmentResId) { // if (destination.id == readerFragmentResId) {
// LOCK_MODE_UNLOCKED // LOCK_MODE_UNLOCKED
@ -271,6 +290,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
navController.navigateUp() || super.onSupportNavigateUp() navController.navigateUp() || super.onSupportNavigateUp()
open fun setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) { open fun setupDrawerToggle(shouldEnableRightDrawer: Boolean = false) {
enableLeftDrawer.value = true
// Set the initial contentDescription to the hamburger icon. // Set the initial contentDescription to the hamburger icon.
// This method is called from various locations after modifying the navigationIcon. // This method is called from various locations after modifying the navigationIcon.
// For example, we previously changed this icon/contentDescription to the "+" button // For example, we previously changed this icon/contentDescription to the "+" button
@ -328,18 +348,22 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
handleDrawerOnNavigation() handleDrawerOnNavigation()
} }
fun navigationDrawerIsOpen(): Boolean = false fun navigationDrawerIsOpen(): Boolean = leftDrawerState.isOpen
// drawerContainerLayout.isDrawerOpen(drawerNavView)
fun closeNavigationDrawer() { fun closeNavigationDrawer() {
// drawerContainerLayout.closeDrawer(drawerNavView) uiCoroutineScope.launch {
leftDrawerState.close()
}
} }
fun openNavigationDrawer() { fun openNavigationDrawer() {
// drawerContainerLayout.openDrawer(drawerNavView) uiCoroutineScope.launch {
leftDrawerState.open()
}
} }
fun openSupportKiwixExternalLink() { fun openSupportKiwixExternalLink() {
closeNavigationDrawer()
externalLinkOpener.openExternalUrl(KIWIX_SUPPORT_URL.toUri().browserIntent(), false) externalLinkOpener.openExternalUrl(KIWIX_SUPPORT_URL.toUri().browserIntent(), false)
} }
@ -418,6 +442,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
} }
private fun openHistory() { private fun openHistory() {
handleDrawerOnNavigation()
navigate(historyFragmentRoute) navigate(historyFragmentRoute)
} }
@ -470,11 +495,12 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
} }
private fun openBookmarks() { private fun openBookmarks() {
navigate(bookmarksFragmentRoute)
handleDrawerOnNavigation() handleDrawerOnNavigation()
navigate(bookmarksFragmentRoute)
} }
private fun openNotes() { private fun openNotes() {
handleDrawerOnNavigation()
navigate(notesFragmentRoute) navigate(notesFragmentRoute)
} }
@ -497,19 +523,19 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
DrawerMenuItem( DrawerMenuItem(
title = CoreApp.instance.getString(R.string.bookmarks), title = CoreApp.instance.getString(R.string.bookmarks),
iconRes = R.drawable.ic_bookmark_black_24dp, iconRes = R.drawable.ic_bookmark_black_24dp,
true, visible = true,
onClick = { openBookmarks() } onClick = { openBookmarks() }
), ),
DrawerMenuItem( DrawerMenuItem(
title = CoreApp.instance.getString(R.string.history), title = CoreApp.instance.getString(R.string.history),
iconRes = R.drawable.ic_history_24px, iconRes = R.drawable.ic_history_24px,
true, visible = true,
onClick = { openHistory() } onClick = { openHistory() }
), ),
DrawerMenuItem( DrawerMenuItem(
title = CoreApp.instance.getString(R.string.pref_notes), title = CoreApp.instance.getString(R.string.pref_notes),
iconRes = R.drawable.ic_add_note, iconRes = R.drawable.ic_add_note,
true, visible = true,
onClick = { openNotes() } onClick = { openNotes() }
), ),
zimHostDrawerMenuItem zimHostDrawerMenuItem
@ -523,7 +549,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
DrawerMenuItem( DrawerMenuItem(
title = CoreApp.instance.getString(R.string.menu_settings), title = CoreApp.instance.getString(R.string.menu_settings),
iconRes = R.drawable.ic_settings_24px, iconRes = R.drawable.ic_settings_24px,
true, visible = true,
onClick = { openSettings() } onClick = { openSettings() }
) )
) )
@ -569,7 +595,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
*/ */
abstract val aboutAppDrawerMenuItem: DrawerMenuItem? abstract val aboutAppDrawerMenuItem: DrawerMenuItem?
val leftNavigationDrawerMenuItems by lazy { protected val leftNavigationDrawerMenuItems by lazy {
listOf<DrawerMenuGroup>( listOf<DrawerMenuGroup>(
bookRelatedDrawerGroup, bookRelatedDrawerGroup,
settingDrawerGroup, settingDrawerGroup,

View File

@ -20,12 +20,10 @@ package org.kiwix.kiwixmobile.core.search.viewmodel.effects
import android.os.Parcelable import android.os.Parcelable
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setNavigationResultOnCurrent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setNavigationResultOnCurrent
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.reader.SEARCH_ITEM_TITLE_KEY
import org.kiwix.kiwixmobile.core.reader.addContentPrefix import org.kiwix.kiwixmobile.core.reader.addContentPrefix
import org.kiwix.kiwixmobile.core.search.SearchListItem import org.kiwix.kiwixmobile.core.search.SearchListItem
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED

View File

@ -18,11 +18,7 @@
package org.kiwix.kiwixmobile.core.ui.models package org.kiwix.kiwixmobile.core.ui.models
import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -36,6 +32,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.createBitmap import androidx.core.graphics.createBitmap
import org.kiwix.kiwixmobile.core.downloader.downloadManager.HUNDERED
sealed class IconItem { sealed class IconItem {
data class Vector(val imageVector: ImageVector) : IconItem() data class Vector(val imageVector: ImageVector) : IconItem()
@ -61,8 +58,8 @@ fun IconItem.toPainter(): Painter {
val context = LocalContext.current val context = LocalContext.current
val drawable = ContextCompat.getDrawable(context, mipmapResId) val drawable = ContextCompat.getDrawable(context, mipmapResId)
val imageBitmap = drawable?.let { val imageBitmap = drawable?.let {
val width = it.intrinsicWidth.takeIf { w -> w > 0 } ?: 100 val width = it.intrinsicWidth.takeIf { w -> w > 0 } ?: HUNDERED
val height = it.intrinsicHeight.takeIf { h -> h > 0 } ?: 100 val height = it.intrinsicHeight.takeIf { h -> h > 0 } ?: HUNDERED
val bitmap = createBitmap(width, height) val bitmap = createBitmap(width, height)
val canvas = Canvas(bitmap) val canvas = Canvas(bitmap)
it.setBounds(0, 0, canvas.width, canvas.height) it.setBounds(0, 0, canvas.width, canvas.height)

View File

@ -52,7 +52,7 @@ class CustomMainActivity : CoreMainActivity() {
supportFragmentManager.findFragmentById( supportFragmentManager.findFragmentById(
R.id.custom_nav_controller R.id.custom_nav_controller
) as NavHostFragment ) as NavHostFragment
) )
.navController .navController
} }
override val drawerContainerLayout: DrawerLayout by lazy { override val drawerContainerLayout: DrawerLayout by lazy {
@ -229,6 +229,7 @@ class CustomMainActivity : CoreMainActivity() {
iconRes = drawable.ic_support_24px, iconRes = drawable.ic_support_24px,
true, true,
onClick = { onClick = {
closeNavigationDrawer()
externalLinkOpener.openExternalUrl(BuildConfig.SUPPORT_URL.toUri().browserIntent(), false) externalLinkOpener.openExternalUrl(BuildConfig.SUPPORT_URL.toUri().browserIntent(), false)
} }
) )
@ -254,7 +255,8 @@ class CustomMainActivity : CoreMainActivity() {
iconRes = drawable.ic_baseline_info, iconRes = drawable.ic_baseline_info,
true, true,
onClick = { onClick = {
externalLinkOpener.openExternalUrl(BuildConfig.SUPPORT_URL.toUri().browserIntent(), false) closeNavigationDrawer()
externalLinkOpener.openExternalUrl(BuildConfig.ABOUT_APP_URL.toUri().browserIntent(), false)
} }
) )
} else { } else {