Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

579 - ODS-Module - About initialization #584

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7d4e3d9
[#634] Fix background color of components in dark mode
florentmaitre Sep 22, 2023
cc23e4a
Merge pull request #640 from Orange-OpenSource/634-bug-exposed-dropdo…
paulinea Sep 22, 2023
ee9b626
[#635] Fix a bug where the modifier was not taken into account in Ods…
florentmaitre Sep 21, 2023
94ae6a4
Merge pull request #637 from Orange-OpenSource/635-bug-odstextfield-p…
paulinea Sep 22, 2023
273340b
[#623] Remove Kotlin reflect dependency
florentmaitre Sep 25, 2023
b695f1c
[#623] Use FlowRow from Androidx and remove Accompanist Flow Layout d…
florentmaitre Sep 27, 2023
a024d98
[#623] Review: Update changelog
florentmaitre Sep 27, 2023
a98f1b3
Merge pull request #644 from Orange-OpenSource/623-reduce-library-size
paulinea Sep 28, 2023
b52b0dc
Prepare 0.15.1 release
paulinea Sep 28, 2023
87c6d06
Merge pull request #645 from Orange-OpenSource/prepare-release
florentmaitre Sep 28, 2023
5680a2b
[#579] Add about module to the modules screen
paulinea Jul 18, 2023
c2d9c2c
[#579] Add about module to project
paulinea Jul 21, 2023
8e821a5
[#579] Draft: Try to integrate About module in demo app (ugly transit…
paulinea Jul 21, 2023
8804373
[#579] Rebase on develop: Adapt code
paulinea Aug 8, 2023
cfafc18
[#579] Allow to display about module with or without new scaffold
paulinea Aug 8, 2023
11e94e7
[#579] Provide configuration through navgraph to customize about modu…
paulinea Aug 9, 2023
16b0a8f
[#579] Add share and feedback buttons
paulinea Aug 10, 2023
6f1f905
[#579] Adapt code after rebase
paulinea Sep 12, 2023
701bed9
[#579] Add about module entry point and allow to customize it
paulinea Sep 21, 2023
9043137
[#579] Use new API of OdsVerticalImageFirstCard
paulinea Sep 22, 2023
bbbebac
[#579] Reorganize code
paulinea Sep 22, 2023
0ac7995
[#579] Remove parcelization of about module config
paulinea Sep 25, 2023
bc9c97a
[#579] Reorganize files
paulinea Sep 25, 2023
02763a2
[#579] Review: Remove Gson dependency
paulinea Sep 28, 2023
ba95064
[#579] Review: Remove useless routes
paulinea Sep 28, 2023
0223c4c
[#579] Review: Add ColumnScope to content parameter
paulinea Sep 28, 2023
2e46bc4
[#579] Review: Simplify expression
paulinea Sep 28, 2023
8104987
[#579] Review: Use a common image background color for all images
paulinea Sep 28, 2023
1695698
[#579] Review: Use FlowRow from androidx.compose.foundation.layout
paulinea Sep 28, 2023
a973c0c
[#579] Review: Move "view demo" button in ModuleDetailColumn
paulinea Sep 28, 2023
f198492
[#579] Review: Remove useless BundleCompat
paulinea Sep 28, 2023
6ec6dad
[#579] Review: Fix typo
paulinea Sep 28, 2023
9ee15d7
[#579] Review: Use library plugin and remove coreKtx dependency
paulinea Sep 28, 2023
a225cde
[#579] Review: Set configuration to non nullable
paulinea Sep 28, 2023
1a91f22
[#579] Review: Rename property
paulinea Sep 28, 2023
a1d9696
[#579] Review: Simplify expression
paulinea Sep 28, 2023
82c31da
[#579] Review: Set launchUrl Context extension to internal
paulinea Sep 28, 2023
eab821a
[#579] Review: Set WebView.injectLightDarkModeCss() internal
paulinea Sep 28, 2023
2bc2ade
[#579] Review: Set OdsAboutFileScreen internal
paulinea Sep 28, 2023
73da481
[#579] Review: Rename strings
paulinea Sep 28, 2023
b77e3c6
[#579] Review: Add a NavHostController subclass to manage navigation …
paulinea Sep 29, 2023
142c05f
[#579] Review: Convert objects to data objects
paulinea Sep 29, 2023
fe05cab
[#579] Review: Add preview for OdsAboutMainScreen
paulinea Sep 29, 2023
da17b14
[#579] Review: Provide a version helper to help users generating a di…
paulinea Sep 29, 2023
863286e
[#579] Review: Add il_about.png in mdpi directory
paulinea Sep 29, 2023
ff586bf
[#579] Review: Add contentScale parameter to DetailScreenHeader and c…
paulinea Sep 29, 2023
d1ff017
[#579] Review: Use NavController extensions instead of a subclass of …
paulinea Oct 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repositories {

```groovy
dependencies {
implementation 'com.orange.ods.android:ods-lib:0.15.0'
implementation 'com.orange.ods.android:ods-lib:0.15.1'
}
```

Expand Down
5 changes: 2 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ android {
minSdk = Versions.minSdk
targetSdk = Versions.targetSdk
val versionCodeProperty = project.findTypedProperty<String>("versionCode")
versionCode = versionCodeProperty?.toInt() ?: 6
versionCode = versionCodeProperty?.toInt() ?: 7
versionName = version.toString()
val versionNameSuffixProperty = project.findTypedProperty<String>("versionNameSuffix")
versionNameSuffix = versionNameSuffixProperty
Expand Down Expand Up @@ -127,12 +127,11 @@ dependencies {
implementation(project(":lib"))
implementation(project(":lib-xml"))
implementation(project(":theme-innovation-cup"))
implementation(project(":module-about"))

implementation(Dependencies.accompanistFlowLayout)
implementation(Dependencies.accompanistSystemUiController)
implementation(Dependencies.activityCompose)
implementation(Dependencies.appCompat)
implementation(Dependencies.browser)
implementation(Dependencies.coil)
implementation(Dependencies.coilCompose)
implementation(platform(Dependencies.composeBom))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import android.content.Context
import com.orange.ods.app.R
import com.orange.ods.app.domain.recipes.Recipe
import com.orange.ods.app.domain.recipes.RecipesRepository
import com.orange.ods.app.ui.utilities.extension.contentAsString
import com.orange.ods.extension.contentAsString
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import timber.log.Timber
Expand Down
60 changes: 60 additions & 0 deletions app/src/main/java/com/orange/ods/app/ui/AppNavigationController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
*
* Copyright 2021 Orange
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* /
*/

package com.orange.ods.app.ui

import androidx.lifecycle.Lifecycle
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.NavGraph

fun NavController.navigateToElement(route: String, elementId: Long?, from: NavBackStackEntry) {
// In order to discard duplicated navigation events, we check the Lifecycle
if (from.lifecycleIsResumed()) {
val fullRoute = if (elementId != null) "$route/$elementId" else route
navigate(fullRoute)
}
}

fun NavController.navigateToBottomBarRoute(route: String) {
navigate(route) {
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
// Pop up backstack to the first destination and save state. This makes going back
// to the start destination when pressing back in any other bottom tab.
popUpTo(findStartDestination(graph).id) {
saveState = true
}
}
}

/**
* If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event.
*
* This is used to de-duplicate navigation events.
*/
private fun NavBackStackEntry.lifecycleIsResumed() =
this.getLifecycle().currentState == Lifecycle.State.RESUMED

private val NavGraph.startDestination: NavDestination?
get() = findNode(startDestinationId)

/**
* Copied from similar function in NavigationUI.kt
*
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.kt
*/
private tailrec fun findStartDestination(graph: NavDestination): NavDestination {
return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph
}
49 changes: 14 additions & 35 deletions app/src/main/java/com/orange/ods/app/ui/MainBottomNavigation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,19 @@ package com.orange.ods.app.ui
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.orange.ods.app.R
import com.orange.ods.app.ui.about.AboutScreen
import com.orange.ods.app.ui.about.UrlAboutItem
import com.orange.ods.app.ui.about.aboutItems
import com.orange.ods.app.ui.about.id
import com.orange.ods.app.ui.components.ComponentsScreen
import com.orange.ods.app.ui.guidelines.GuidelinesScreen
import com.orange.ods.app.ui.modules.ModulesScreen
import com.orange.ods.app.ui.utilities.launchUrl
import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigation
import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigationItem
import com.orange.ods.compose.component.bottomnavigation.OdsBottomNavigationItemIcon
import com.orange.ods.module.about.navigation.OdsAboutRoute

@Composable
fun MainBottomNavigation(items: Array<BottomNavigationSections>, currentRoute: String, navigateToRoute: (String) -> Unit) {
Expand All @@ -40,42 +35,26 @@ fun MainBottomNavigation(items: Array<BottomNavigationSections>, currentRoute: S
icon = OdsBottomNavigationItemIcon(painter = painterResource(id = item.iconRes), contentDescription = ""),
label = stringResource(id = item.titleRes),
selected = currentRoute == item.route,
onClick = { navigateToRoute(item.route) }
onClick = {
navigateToRoute(item.route)
}
)
}
)
}

fun NavGraphBuilder.addBottomNavigationGraph(navigateToElement: (String, Long?, NavBackStackEntry) -> Unit) {
fun NavGraphBuilder.addBottomNavigationGraph(navController: NavController) {
composable(BottomNavigationSections.Guidelines.route) { from ->
val topAppBarConfiguration = MainTopAppBarState.DefaultConfiguration.newBuilder()
.prependAction(TopAppBarConfiguration.Action.Search)
.build()
LocalMainTopAppBarManager.current.updateTopAppBar(topAppBarConfiguration)
GuidelinesScreen(onGuidelineClick = { route -> navigateToElement(route, null, from) })
LocalMainTopAppBarManager.current.updateTopAppBar(MainTopAppBarState.DefaultWithSearchActionConfiguration)
GuidelinesScreen(onGuidelineClick = { route -> navController.navigateToElement(route, null, from) })
}
composable(BottomNavigationSections.Components.route) { from ->
val topAppBarConfiguration = MainTopAppBarState.DefaultConfiguration.newBuilder()
.prependAction(TopAppBarConfiguration.Action.Search)
.build()
LocalMainTopAppBarManager.current.updateTopAppBar(topAppBarConfiguration)
ComponentsScreen(onComponentClick = { id -> navigateToElement(MainDestinations.ComponentDetailRoute, id, from) })
LocalMainTopAppBarManager.current.updateTopAppBar(MainTopAppBarState.DefaultWithSearchActionConfiguration)
ComponentsScreen(onComponentClick = { id -> navController.navigateToElement(MainDestinations.ComponentDetailRoute, id, from) })
}
composable(BottomNavigationSections.Modules.route) {
LocalMainTopAppBarManager.current.updateTopAppBar(MainTopAppBarState.DefaultConfiguration)
ModulesScreen()
}
composable(BottomNavigationSections.About.route) { from ->
val context = LocalContext.current
LocalMainTopAppBarManager.current.updateTopAppBar(MainTopAppBarState.DefaultConfiguration)
AboutScreen(onAboutItemClick = { id ->
val aboutItem = aboutItems.firstOrNull { it.id == id }
if (aboutItem is UrlAboutItem) {
context.launchUrl(aboutItem.url)
} else {
navigateToElement(MainDestinations.AboutItemDetailRoute, id, from)
}
})
composable(BottomNavigationSections.Modules.route) { from ->
LocalMainTopAppBarManager.current.updateTopAppBar(MainTopAppBarState.DefaultWithSearchActionConfiguration)
ModulesScreen(onModuleClick = { route -> navController.navigateToElement(route, null, from) })
}
}

Expand All @@ -87,5 +66,5 @@ enum class BottomNavigationSections(
Guidelines(R.string.navigation_item_guidelines, R.drawable.ic_guideline_dna, "main/guidelines"),
Components(R.string.navigation_item_components, R.drawable.ic_component_atom, "main/components"),
Modules(R.string.navigation_item_modules, R.drawable.ic_module_molecule, "main/modules"),
About(R.string.navigation_item_about, R.drawable.ic_info, "main/about");
About(R.string.navigation_item_about, R.drawable.ic_info, OdsAboutRoute);
}
22 changes: 12 additions & 10 deletions app/src/main/java/com/orange/ods/app/ui/MainScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand All @@ -41,16 +41,18 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.orange.ods.app.R
import com.orange.ods.app.domain.recipes.LocalCategories
import com.orange.ods.app.domain.recipes.LocalRecipes
import com.orange.ods.app.ui.about.addAboutGraph
import com.orange.ods.app.ui.about.aboutConfiguration
import com.orange.ods.app.ui.components.addComponentsGraph
import com.orange.ods.app.ui.components.tabs.FixedTabRow
import com.orange.ods.app.ui.components.tabs.ScrollableTabRow
import com.orange.ods.app.ui.guidelines.addGuidelinesGraph
import com.orange.ods.app.ui.modules.addModulesGraph
import com.orange.ods.app.ui.search.SearchScreen
import com.orange.ods.app.ui.utilities.extension.isDarkModeEnabled
import com.orange.ods.app.ui.utilities.extension.isOrange
import com.orange.ods.compose.theme.OdsTheme
import com.orange.ods.extension.orElse
import com.orange.ods.module.about.configuration.LocalOdsAboutModuleConfiguration
import com.orange.ods.theme.OdsThemeConfigurationContract
import com.orange.ods.xml.theme.OdsXml
import com.orange.ods.xml.utilities.extension.xml
Expand Down Expand Up @@ -90,7 +92,8 @@ fun MainScreen(themeConfigurations: Set<OdsThemeConfigurationContract>, mainView
LocalOdsGuideline provides mainState.themeState.currentThemeConfiguration.guideline,
LocalRecipes provides mainViewModel.recipes,
LocalCategories provides mainViewModel.categories,
LocalUiFramework provides mainState.uiFramework
LocalUiFramework provides mainState.uiFramework,
LocalOdsAboutModuleConfiguration provides aboutConfiguration()
) {
OdsTheme(
themeConfiguration = mainState.themeState.currentThemeConfiguration,
Expand All @@ -117,7 +120,6 @@ fun MainScreen(themeConfigurations: Set<OdsThemeConfigurationContract>, mainView

Scaffold(
modifier = modifier,
backgroundColor = OdsTheme.colors.background,
topBar = {
Surface(elevation = if (isSystemInDarkTheme()) 0.dp else AppBarDefaults.TopAppBarElevation) {
Column {
Expand Down Expand Up @@ -155,7 +157,7 @@ fun MainScreen(themeConfigurations: Set<OdsThemeConfigurationContract>, mainView
navController = mainState.navController, startDestination = MainDestinations.HomeRoute, modifier = Modifier.padding(innerPadding)
) {
mainNavGraph(
navigateToElement = mainState::navigateToElement,
navController = mainState.navController,
upPress = mainState::upPress,
searchedText = mainState.topAppBarState.searchedText
)
Expand Down Expand Up @@ -211,28 +213,28 @@ private fun MainTabs(mainTabsState: MainTabsState) {
}

private fun NavGraphBuilder.mainNavGraph(
navigateToElement: (String, Long?, NavBackStackEntry) -> Unit,
navController: NavController,
upPress: () -> Unit,
searchedText: MutableState<TextFieldValue>
) {
navigation(
route = MainDestinations.HomeRoute,
startDestination = BottomNavigationSections.Guidelines.route
) {
addBottomNavigationGraph(navigateToElement)
addBottomNavigationGraph(navController)
}

addGuidelinesGraph()
addComponentsGraph(navigateToElement, upPress)
addAboutGraph()
addComponentsGraph(navController, upPress)
addModulesGraph(navController)

composable(
route = MainDestinations.SearchRoute
) { from ->
LocalMainTopAppBarManager.current.updateTopAppBarTitle(R.string.navigation_item_search)
SearchScreen(
searchedText,
onResultItemClick = { route, id -> navigateToElement(route, id, from) }
onResultItemClick = { route, id -> navController.navigateToElement(route, id, from) }
)
}
}
48 changes: 1 addition & 47 deletions app/src/main/java/com/orange/ods/app/ui/MainState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.lifecycle.Lifecycle
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination
import androidx.navigation.NavGraph
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
Expand All @@ -39,9 +35,6 @@ object MainDestinations {
const val ComponentVariantIdKey = "componentVariantId"
const val ComponentDemoRoute = "component/demo"

const val AboutItemDetailRoute = "aboutItem"
const val AboutItemIdKey = "aboutItemId"

const val SearchRoute = "search"
}

Expand Down Expand Up @@ -93,46 +86,7 @@ class MainState(

fun navigateToBottomBarRoute(route: String) {
if (route != currentRoute) {
navController.navigate(route) {
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
// Pop up backstack to the first destination and save state. This makes going back
// to the start destination when pressing back in any other bottom tab.
popUpTo(findStartDestination(navController.graph).id) {
saveState = true
}
}
}
}

fun navigateToElement(route: String, elementId: Long?, from: NavBackStackEntry) {
// In order to discard duplicated navigation events, we check the Lifecycle
if (from.lifecycleIsResumed()) {
val fullRoute = if (elementId != null) "$route/$elementId" else route
navController.navigate(fullRoute)
navController.navigateToBottomBarRoute(route)
}
}
}

/**
* If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event.
*
* This is used to de-duplicate navigation events.
*/
private fun NavBackStackEntry.lifecycleIsResumed() =
this.getLifecycle().currentState == Lifecycle.State.RESUMED

private val NavGraph.startDestination: NavDestination?
get() = findNode(startDestinationId)

/**
* Copied from similar function in NavigationUI.kt
*
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.kt
*/
private tailrec fun findStartDestination(graph: NavDestination): NavDestination {
return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/orange/ods/app/ui/MainTopAppBarState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ class MainTopAppBarState(
isNavigationIconEnabled = true,
actions = listOf(TopAppBarConfiguration.Action.Theme, TopAppBarConfiguration.Action.Mode)
)

val DefaultWithSearchActionConfiguration = DefaultConfiguration.newBuilder()
.prependAction(TopAppBarConfiguration.Action.Search)
.build()
}

// ----------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
*
* Copyright 2021 Orange
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* /
*/

package com.orange.ods.app.ui.about

import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.orange.ods.app.R
import com.orange.ods.module.about.configuration.OdsAboutModuleConfiguration
import com.orange.ods.module.about.utilities.VersionHelper

@Composable
fun aboutConfiguration() = OdsAboutModuleConfiguration(
appName = stringResource(id = R.string.about_app_name),
appVersion = VersionHelper.getFromPackageInfo(context = LocalContext.current),
appDescription = stringResource(id = R.string.about_description)
)
Loading