mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
Refactored left drawer to support Kiwix and custom apps dynamically; improved right drawer UI.
This commit is contained in:
parent
4e56c2c781
commit
86d9b1266f
@ -27,6 +27,7 @@ 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.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
@ -36,13 +37,14 @@ 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.NavDestination
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
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
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.kiwix.kiwixmobile.BuildConfig
|
import org.kiwix.kiwixmobile.BuildConfig
|
||||||
import org.kiwix.kiwixmobile.R
|
import org.kiwix.kiwixmobile.R
|
||||||
|
import org.kiwix.kiwixmobile.core.CoreApp
|
||||||
import org.kiwix.kiwixmobile.core.R.drawable
|
import org.kiwix.kiwixmobile.core.R.drawable
|
||||||
import org.kiwix.kiwixmobile.core.R.id
|
import org.kiwix.kiwixmobile.core.R.id
|
||||||
import org.kiwix.kiwixmobile.core.R.mipmap
|
import org.kiwix.kiwixmobile.core.R.mipmap
|
||||||
@ -53,6 +55,7 @@ import org.kiwix.kiwixmobile.core.downloader.downloadManager.DOWNLOAD_NOTIFICATI
|
|||||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||||
import org.kiwix.kiwixmobile.core.main.ACTION_NEW_TAB
|
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.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.main.ZIM_FILE_URI_KEY
|
||||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange
|
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange
|
||||||
@ -82,12 +85,6 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
// activityKiwixMainBinding.readerDrawerNavView
|
// activityKiwixMainBinding.readerDrawerNavView
|
||||||
// }
|
// }
|
||||||
|
|
||||||
override val navController: NavController by lazy {
|
|
||||||
val fragment = supportFragmentManager.findFragmentById(id.nav_host_fragment)
|
|
||||||
val navHostFragment = requireNotNull(fragment) as NavHostFragment
|
|
||||||
return@lazy navHostFragment.navController
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject lateinit var libkiwixBookOnDisk: LibkiwixBookOnDisk
|
@Inject lateinit var libkiwixBookOnDisk: LibkiwixBookOnDisk
|
||||||
|
|
||||||
override val mainActivity: AppCompatActivity by lazy { this }
|
override val mainActivity: AppCompatActivity by lazy { this }
|
||||||
@ -117,15 +114,24 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
cachedComponent.inject(this)
|
cachedComponent.inject(this)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContent {
|
setContent {
|
||||||
|
navController = rememberNavController()
|
||||||
KiwixMainActivityScreen(
|
KiwixMainActivityScreen(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
topLevelDestinations = topLevelDestinations.toList(),
|
topLevelDestinations = topLevelDestinations.toList(),
|
||||||
isBottomBarVisible = isBottomBarVisible.value,
|
isBottomBarVisible = isBottomBarVisible.value,
|
||||||
leftDrawerContent = { },
|
leftDrawerContent = rightNavigationDrawerMenuItems,
|
||||||
rightDrawerContent = { }
|
rightDrawerContent = { }
|
||||||
)
|
)
|
||||||
|
LaunchedEffect(navController) {
|
||||||
|
navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange)
|
||||||
|
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||||
|
isBottomBarVisible.value = destination.id in topLevelDestinations
|
||||||
|
if (destination.id !in topLevelDestinations) {
|
||||||
|
handleDrawerOnNavigation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
navController.addOnDestinationChangedListener(finishActionModeOnDestinationChange)
|
|
||||||
// activityKiwixMainBinding.drawerNavView.apply {
|
// activityKiwixMainBinding.drawerNavView.apply {
|
||||||
// setupWithNavController(navController)
|
// setupWithNavController(navController)
|
||||||
// setNavigationItemSelectedListener { item ->
|
// setNavigationItemSelectedListener { item ->
|
||||||
@ -207,12 +213,6 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
// navController.addOnDestinationChangedListener { _, destination, _ ->
|
|
||||||
// isBottomBarVisible.value = destination.id in topLevelDestinations
|
|
||||||
// if (destination.id !in topLevelDestinations) {
|
|
||||||
// handleDrawerOnNavigation()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
||||||
// navigate(KiwixReaderFragmentDirections.actionReaderFragmentToIntroFragment())
|
// navigate(KiwixReaderFragmentDirections.actionReaderFragmentToIntroFragment())
|
||||||
}
|
}
|
||||||
@ -337,6 +337,32 @@ class KiwixMainActivity : CoreMainActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val zimHostDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(string.menu_wifi_hotspot),
|
||||||
|
iconRes = drawable.ic_mobile_screen_share_24px,
|
||||||
|
true,
|
||||||
|
onClick = { openZimHostFragment() }
|
||||||
|
)
|
||||||
|
|
||||||
|
override val helpDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(string.menu_help),
|
||||||
|
iconRes = drawable.ic_help_24px,
|
||||||
|
true,
|
||||||
|
onClick = { openHelpFragment() }
|
||||||
|
)
|
||||||
|
|
||||||
|
override val supportDrawerMenuItem: DrawerMenuItem? = DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(string.menu_support_kiwix),
|
||||||
|
iconRes = drawable.ic_support_24px,
|
||||||
|
true,
|
||||||
|
onClick = { openSupportKiwixExternalLink() }
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In kiwix app we are not showing the "About app" item so returning null.
|
||||||
|
*/
|
||||||
|
override val aboutAppDrawerMenuItem: DrawerMenuItem? = null
|
||||||
|
|
||||||
private fun openZimHostFragment() {
|
private fun openZimHostFragment() {
|
||||||
disableDrawer()
|
disableDrawer()
|
||||||
navigate(R.id.zimHostFragment)
|
navigate(R.id.zimHostFragment)
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.main
|
package org.kiwix.kiwixmobile.main
|
||||||
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
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.ColumnScope
|
||||||
@ -44,35 +42,31 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
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.compose.ui.viewinterop.AndroidView
|
import androidx.navigation.NavHostController
|
||||||
import androidx.fragment.app.FragmentContainerView
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
|
||||||
import org.kiwix.kiwixmobile.R.drawable
|
import org.kiwix.kiwixmobile.R.drawable
|
||||||
import org.kiwix.kiwixmobile.R.id
|
import org.kiwix.kiwixmobile.R.id
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
import org.kiwix.kiwixmobile.R.navigation
|
import org.kiwix.kiwixmobile.core.main.DrawerMenuGroup
|
||||||
|
import org.kiwix.kiwixmobile.core.main.LeftDrawerMenu
|
||||||
import org.kiwix.kiwixmobile.core.ui.theme.KiwixTheme
|
import org.kiwix.kiwixmobile.core.ui.theme.KiwixTheme
|
||||||
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.NAVIGATION_DRAWER_WIDTH
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.NAVIGATION_DRAWER_WIDTH
|
||||||
|
import org.kiwix.kiwixmobile.ui.KiwixNavGraph
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun KiwixMainActivityScreen(
|
fun KiwixMainActivityScreen(
|
||||||
navController: NavController,
|
navController: NavHostController,
|
||||||
topLevelDestinations: List<Int>,
|
topLevelDestinations: List<Int>,
|
||||||
leftDrawerContent: @Composable ColumnScope.() -> Unit,
|
leftDrawerContent: List<DrawerMenuGroup>,
|
||||||
rightDrawerContent: @Composable ColumnScope.() -> Unit,
|
rightDrawerContent: @Composable ColumnScope.() -> Unit,
|
||||||
isBottomBarVisible: Boolean = true
|
isBottomBarVisible: Boolean = true
|
||||||
) {
|
) {
|
||||||
val rightDrawerState = rememberDrawerState(DrawerValue.Closed)
|
val rightDrawerState = rememberDrawerState(DrawerValue.Closed)
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val scrollingBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
val scrollingBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
|
||||||
val context = LocalContext.current
|
|
||||||
val fragmentManager = (context as AppCompatActivity).supportFragmentManager
|
|
||||||
KiwixTheme {
|
KiwixTheme {
|
||||||
ModalNavigationDrawer(
|
ModalNavigationDrawer(
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
@ -81,7 +75,7 @@ fun KiwixMainActivityScreen(
|
|||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.width(NAVIGATION_DRAWER_WIDTH)
|
.width(NAVIGATION_DRAWER_WIDTH)
|
||||||
) {
|
) {
|
||||||
leftDrawerContent()
|
LeftDrawerMenu(leftDrawerContent)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
gesturesEnabled = true
|
gesturesEnabled = true
|
||||||
@ -99,21 +93,9 @@ fun KiwixMainActivityScreen(
|
|||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Box(modifier = Modifier.padding(paddingValues)) {
|
Box(modifier = Modifier.padding(paddingValues)) {
|
||||||
// AndroidView to host your FragmentContainerView with nav graph
|
KiwixNavGraph(
|
||||||
AndroidView(
|
navController = navController,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize()
|
||||||
factory = { ctx ->
|
|
||||||
FragmentContainerView(ctx).apply {
|
|
||||||
id = R.id.nav_host_fragment
|
|
||||||
if (fragmentManager.findFragmentById(id) == null) {
|
|
||||||
val navHostFragment = NavHostFragment.create(navigation.kiwix_nav_graph)
|
|
||||||
fragmentManager.beginTransaction()
|
|
||||||
.replace(id, navHostFragment)
|
|
||||||
.setPrimaryNavigationFragment(navHostFragment)
|
|
||||||
.commitNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +118,7 @@ fun KiwixMainActivityScreen(
|
|||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationBar(
|
fun BottomNavigationBar(
|
||||||
navController: NavController,
|
navController: NavHostController,
|
||||||
scrollBehavior: BottomAppBarScrollBehavior,
|
scrollBehavior: BottomAppBarScrollBehavior,
|
||||||
topLevelDestinations: List<Int>
|
topLevelDestinations: List<Int>
|
||||||
) {
|
) {
|
||||||
|
@ -29,16 +29,11 @@ import androidx.appcompat.app.ActionBarDrawerToggle
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.core.view.GravityCompat
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_UNLOCKED
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentContainerView
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.NavDestination
|
import androidx.navigation.NavDestination
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -90,7 +85,12 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
private var drawerToggle: ActionBarDrawerToggle? = null
|
private var drawerToggle: ActionBarDrawerToggle? = null
|
||||||
|
|
||||||
@Inject lateinit var zimReaderContainer: ZimReaderContainer
|
@Inject lateinit var zimReaderContainer: ZimReaderContainer
|
||||||
abstract val navController: NavController
|
|
||||||
|
/**
|
||||||
|
* We have migrated the UI in compose, so providing the compose based navigation to activity
|
||||||
|
* is responsibility of child activities such as KiwixMainActivity, and CustomMainActivity.
|
||||||
|
*/
|
||||||
|
lateinit var navController: NavHostController
|
||||||
|
|
||||||
// abstract val drawerContainerLayout: DrawerLayout
|
// abstract val drawerContainerLayout: DrawerLayout
|
||||||
// abstract val drawerNavView: NavigationView
|
// abstract val drawerNavView: NavigationView
|
||||||
@ -102,6 +102,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
abstract val helpFragmentResId: Int
|
abstract val helpFragmentResId: Int
|
||||||
abstract val cachedComponent: CoreActivityComponent
|
abstract val cachedComponent: CoreActivityComponent
|
||||||
abstract val topLevelDestinations: Set<Int>
|
abstract val topLevelDestinations: Set<Int>
|
||||||
|
|
||||||
// abstract val navHostContainer: FragmentContainerView
|
// abstract val navHostContainer: FragmentContainerView
|
||||||
abstract val mainActivity: AppCompatActivity
|
abstract val mainActivity: AppCompatActivity
|
||||||
abstract val appName: String
|
abstract val appName: String
|
||||||
@ -115,7 +116,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
|
|
||||||
@Suppress("InjectDispatcher")
|
@Suppress("InjectDispatcher")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
// setTheme(R.style.KiwixTheme)
|
setTheme(R.style.KiwixTheme)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (!BuildConfig.DEBUG) {
|
if (!BuildConfig.DEBUG) {
|
||||||
val appContext = applicationContext
|
val appContext = applicationContext
|
||||||
@ -322,7 +323,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openHelpFragment() {
|
protected fun openHelpFragment() {
|
||||||
navigate(helpFragmentResId)
|
navigate(helpFragmentResId)
|
||||||
handleDrawerOnNavigation()
|
handleDrawerOnNavigation()
|
||||||
}
|
}
|
||||||
@ -490,6 +491,84 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
|
|||||||
navigate(readerFragmentResId, bundleOf(FIND_IN_PAGE_SEARCH_STRING to searchString))
|
navigate(readerFragmentResId, bundleOf(FIND_IN_PAGE_SEARCH_STRING to searchString))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val bookRelatedDrawerGroup = DrawerMenuGroup(
|
||||||
|
listOfNotNull(
|
||||||
|
DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(R.string.bookmarks),
|
||||||
|
iconRes = R.drawable.ic_bookmark_black_24dp,
|
||||||
|
true,
|
||||||
|
onClick = { openBookmarks() }
|
||||||
|
),
|
||||||
|
DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(R.string.history),
|
||||||
|
iconRes = R.drawable.ic_history_24px,
|
||||||
|
true,
|
||||||
|
onClick = { openHistory() }
|
||||||
|
),
|
||||||
|
DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(R.string.pref_notes),
|
||||||
|
iconRes = R.drawable.ic_add_note,
|
||||||
|
true,
|
||||||
|
onClick = { openNotes() }
|
||||||
|
),
|
||||||
|
zimHostDrawerMenuItem
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private val settingDrawerGroup = DrawerMenuGroup(
|
||||||
|
listOf(
|
||||||
|
DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(R.string.menu_settings),
|
||||||
|
iconRes = R.drawable.ic_settings_24px,
|
||||||
|
true,
|
||||||
|
onClick = { openSettings() }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
open val helpAndSupportDrawerGroup = DrawerMenuGroup(
|
||||||
|
listOfNotNull(
|
||||||
|
helpDrawerMenuItem,
|
||||||
|
supportDrawerMenuItem,
|
||||||
|
aboutAppDrawerMenuItem
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the "Wi-Fi Hotspot" menu item in the left drawer.
|
||||||
|
* Currently, this feature is only included in the main Kiwix app.
|
||||||
|
* Custom apps do not include this item.
|
||||||
|
*/
|
||||||
|
abstract val zimHostDrawerMenuItem: DrawerMenuItem?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the "Help" menu item in the left drawer.
|
||||||
|
* In custom apps, this item is hidden.
|
||||||
|
* Each app (main Kiwix or custom) provides its own implementation.
|
||||||
|
*/
|
||||||
|
abstract val helpDrawerMenuItem: DrawerMenuItem?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the "Support" menu item in the left drawer.
|
||||||
|
* In custom apps, this item displays the application name dynamically.
|
||||||
|
* Child activities are responsible for defining this drawer item.
|
||||||
|
*/
|
||||||
|
abstract val supportDrawerMenuItem: DrawerMenuItem?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the "About App" menu item in the left drawer.
|
||||||
|
* For custom apps, this item is shown if configured.
|
||||||
|
* It is not included in the main Kiwix app.
|
||||||
|
* Child activities are responsible for defining this drawer item.
|
||||||
|
*/
|
||||||
|
abstract val aboutAppDrawerMenuItem: DrawerMenuItem?
|
||||||
|
|
||||||
|
val rightNavigationDrawerMenuItems = listOf<DrawerMenuGroup>(
|
||||||
|
bookRelatedDrawerGroup,
|
||||||
|
settingDrawerGroup,
|
||||||
|
helpAndSupportDrawerGroup
|
||||||
|
)
|
||||||
|
|
||||||
protected abstract fun getIconResId(): Int
|
protected abstract fun getIconResId(): Int
|
||||||
abstract val readerFragmentResId: Int
|
abstract val readerFragmentResId: Int
|
||||||
abstract fun createApplicationShortcuts()
|
abstract fun createApplicationShortcuts()
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.core.main
|
package org.kiwix.kiwixmobile.core.main
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
|
||||||
data class DrawerMenuItem(
|
data class DrawerMenuItem(
|
||||||
val id: Int,
|
|
||||||
val title: String,
|
val title: String,
|
||||||
val iconRes: Int,
|
@DrawableRes val iconRes: Int,
|
||||||
val visible: Boolean = true,
|
val visible: Boolean = true,
|
||||||
val onClick: () -> Unit
|
val onClick: () -> Unit
|
||||||
)
|
)
|
||||||
|
@ -28,16 +28,18 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import org.kiwix.kiwixmobile.core.R
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import org.kiwix.kiwixmobile.core.R
|
||||||
|
import org.kiwix.kiwixmobile.core.ui.models.IconItem
|
||||||
|
import org.kiwix.kiwixmobile.core.ui.models.toPainter
|
||||||
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.NAVIGATION_DRAWER_WIDTH
|
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.NAVIGATION_DRAWER_WIDTH
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainDrawerMenu(drawerMenuGroupList: List<DrawerMenuGroup>) {
|
fun LeftDrawerMenu(drawerMenuGroupList: List<DrawerMenuGroup>) {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(NAVIGATION_DRAWER_WIDTH)
|
.width(NAVIGATION_DRAWER_WIDTH)
|
||||||
@ -47,7 +49,7 @@ fun MainDrawerMenu(drawerMenuGroupList: List<DrawerMenuGroup>) {
|
|||||||
Column {
|
Column {
|
||||||
// Banner image at the top
|
// Banner image at the top
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.ic_home_kiwix_banner),
|
painter = IconItem.MipmapImage(R.drawable.ic_home_kiwix_banner).toPainter(),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.FillWidth,
|
contentScale = ContentScale.FillWidth,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
@ -60,7 +62,7 @@ fun MainDrawerMenu(drawerMenuGroupList: List<DrawerMenuGroup>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerGroup(items: List<DrawerMenuItem>) {
|
private fun DrawerGroup(items: List<DrawerMenuItem>) {
|
||||||
Column {
|
Column {
|
||||||
items.filter { it.visible }.forEach { item ->
|
items.filter { it.visible }.forEach { item ->
|
||||||
DrawerMenuItemView(item)
|
DrawerMenuItemView(item)
|
||||||
@ -69,7 +71,7 @@ fun DrawerGroup(items: List<DrawerMenuItem>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerMenuItemView(item: DrawerMenuItem) {
|
private fun DrawerMenuItemView(item: DrawerMenuItem) {
|
||||||
ListItem(
|
ListItem(
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -18,6 +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.AdaptiveIconDrawable
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
@ -57,20 +58,19 @@ fun IconItem.toPainter(): Painter {
|
|||||||
is IconItem.Drawable -> painterResource(drawableRes)
|
is IconItem.Drawable -> painterResource(drawableRes)
|
||||||
is IconItem.ImageBitmap -> remember { BitmapPainter(bitmap) }
|
is IconItem.ImageBitmap -> remember { BitmapPainter(bitmap) }
|
||||||
is IconItem.MipmapImage -> {
|
is IconItem.MipmapImage -> {
|
||||||
val drawable = ContextCompat.getDrawable(LocalContext.current, mipmapResId)
|
val context = LocalContext.current
|
||||||
val imageBitmap = when {
|
val drawable = ContextCompat.getDrawable(context, mipmapResId)
|
||||||
drawable is BitmapDrawable -> drawable.bitmap.asImageBitmap()
|
val imageBitmap = drawable?.let {
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && drawable is AdaptiveIconDrawable -> {
|
val width = it.intrinsicWidth.takeIf { w -> w > 0 } ?: 100
|
||||||
val bitmap = createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight)
|
val height = it.intrinsicHeight.takeIf { h -> h > 0 } ?: 100
|
||||||
val canvas = Canvas(bitmap)
|
val bitmap = createBitmap(width, height)
|
||||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
val canvas = Canvas(bitmap)
|
||||||
drawable.draw(canvas)
|
it.setBounds(0, 0, canvas.width, canvas.height)
|
||||||
bitmap.asImageBitmap()
|
it.draw(canvas)
|
||||||
}
|
bitmap.asImageBitmap()
|
||||||
|
} ?: run {
|
||||||
else -> {
|
// fallback empty bitmap if drawable is null
|
||||||
createBitmap(0, 0).asImageBitmap()
|
createBitmap(1, 1).asImageBitmap()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return remember { BitmapPainter(imageBitmap) }
|
return remember { BitmapPainter(imageBitmap) }
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import androidx.drawerlayout.widget.DrawerLayout
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
|
import org.kiwix.kiwixmobile.core.CoreApp
|
||||||
import org.kiwix.kiwixmobile.core.R.drawable
|
import org.kiwix.kiwixmobile.core.R.drawable
|
||||||
import org.kiwix.kiwixmobile.core.R.string
|
import org.kiwix.kiwixmobile.core.R.string
|
||||||
import org.kiwix.kiwixmobile.core.extensions.applyEdgeToEdgeInsets
|
import org.kiwix.kiwixmobile.core.extensions.applyEdgeToEdgeInsets
|
||||||
@ -37,6 +38,7 @@ import org.kiwix.kiwixmobile.core.extensions.browserIntent
|
|||||||
import org.kiwix.kiwixmobile.core.extensions.getDialogHostComposeView
|
import org.kiwix.kiwixmobile.core.extensions.getDialogHostComposeView
|
||||||
import org.kiwix.kiwixmobile.core.main.ACTION_NEW_TAB
|
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.NEW_TAB_SHORTCUT_ID
|
import org.kiwix.kiwixmobile.core.main.NEW_TAB_SHORTCUT_ID
|
||||||
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
||||||
import org.kiwix.kiwixmobile.custom.BuildConfig
|
import org.kiwix.kiwixmobile.custom.BuildConfig
|
||||||
@ -50,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 {
|
||||||
@ -192,6 +194,73 @@ class CustomMainActivity : CoreMainActivity() {
|
|||||||
|
|
||||||
override fun getIconResId() = R.mipmap.ic_launcher
|
override fun getIconResId() = R.mipmap.ic_launcher
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the 'ZimHostFragment' option from the navigation menu
|
||||||
|
* because we are now using fd (FileDescriptor)
|
||||||
|
* to read the zim file from the asset folder. Currently,
|
||||||
|
* 'KiwixServer' is unable to host zim files via fd.
|
||||||
|
* This feature is temporarily removed for custom apps.
|
||||||
|
* We will re-enable it for custom apps once the issue is resolved.
|
||||||
|
* For more info see https://github.com/kiwix/kiwix-android/pull/3516,
|
||||||
|
* https://github.com/kiwix/kiwix-android/issues/4026
|
||||||
|
*/
|
||||||
|
override val zimHostDrawerMenuItem: DrawerMenuItem? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the `HelpFragment` from custom apps.
|
||||||
|
* We have not removed the relevant code for `HelpFragment` from custom apps.
|
||||||
|
* If, in the future, we need to display this for all/some custom apps,
|
||||||
|
* we can either remove the line below or configure it according to the requirements.
|
||||||
|
* For more information, see https://github.com/kiwix/kiwix-android/issues/3584
|
||||||
|
*/
|
||||||
|
override val helpDrawerMenuItem: DrawerMenuItem? = null
|
||||||
|
|
||||||
|
override val supportDrawerMenuItem: DrawerMenuItem? =
|
||||||
|
/**
|
||||||
|
* If custom app is configured to show the "Support app_name" in navigation
|
||||||
|
* then show it navigation. "app_name" will be replaced with custom app name.
|
||||||
|
*/
|
||||||
|
if (BuildConfig.SUPPORT_URL.isNotEmpty()) {
|
||||||
|
DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(
|
||||||
|
string.menu_support_kiwix_for_custom_apps,
|
||||||
|
CoreApp.instance.getString(R.string.app_name)
|
||||||
|
),
|
||||||
|
iconRes = drawable.ic_support_24px,
|
||||||
|
true,
|
||||||
|
onClick = {
|
||||||
|
externalLinkOpener.openExternalUrl(BuildConfig.SUPPORT_URL.toUri().browserIntent(), false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* If custom app is not configured to show the "Support app_name" in navigation
|
||||||
|
* then remove it from navigation.
|
||||||
|
*/
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If custom app is configured to show the "About app_name app" in navigation
|
||||||
|
* then show it navigation. "app_name" will be replaced with custom app name.
|
||||||
|
*/
|
||||||
|
override val aboutAppDrawerMenuItem: DrawerMenuItem? =
|
||||||
|
if (BuildConfig.ABOUT_APP_URL.isNotEmpty()) {
|
||||||
|
DrawerMenuItem(
|
||||||
|
title = CoreApp.instance.getString(
|
||||||
|
string.menu_about_app,
|
||||||
|
CoreApp.instance.getString(R.string.app_name)
|
||||||
|
),
|
||||||
|
iconRes = drawable.ic_baseline_info,
|
||||||
|
true,
|
||||||
|
onClick = {
|
||||||
|
externalLinkOpener.openExternalUrl(BuildConfig.SUPPORT_URL.toUri().browserIntent(), false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
override fun createApplicationShortcuts() {
|
override fun createApplicationShortcuts() {
|
||||||
// Remove previously added dynamic shortcuts for old ids if any found.
|
// Remove previously added dynamic shortcuts for old ids if any found.
|
||||||
removeOutdatedIdShortcuts()
|
removeOutdatedIdShortcuts()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user