Skip to content

Commit 1e6746d

Browse files
committed
chore(designsystem): Implement functionality of the designsystem module
feat(navigation): Implement top-level navigation in the app
1 parent e846a94 commit 1e6746d

File tree

34 files changed

+1957
-69
lines changed

34 files changed

+1957
-69
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,6 @@ android {
3737
}
3838
}
3939

40-
buildTypes {
41-
release {
42-
isMinifyEnabled = false
43-
proguardFiles(
44-
getDefaultProguardFile("proguard-android-optimize.txt"),
45-
"proguard-rules.pro"
46-
)
47-
}
48-
}
49-
5040
buildTypes {
5141
debug {
5242
applicationIdSuffix = PqBuildType.DEBUG.applicationIdSuffix
@@ -76,9 +66,10 @@ android {
7666
}
7767

7868
dependencies {
69+
implementation(project(":feature:home"))
70+
7971
// TODO Wei
8072
// implementation(project(":feature:login"))
81-
// implementation(project(":feature:home"))
8273
// implementation(project(":feature:contactme"))
8374

8475
implementation(project(":core:designsystem"))
Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,106 @@
11
package com.wei.picquest
22

3+
import android.graphics.Color
34
import android.os.Bundle
45
import androidx.activity.ComponentActivity
6+
import androidx.activity.SystemBarStyle
57
import androidx.activity.compose.setContent
6-
import androidx.compose.foundation.layout.fillMaxSize
7-
import androidx.compose.material3.MaterialTheme
8-
import androidx.compose.material3.Surface
9-
import androidx.compose.material3.Text
8+
import androidx.activity.enableEdgeToEdge
9+
import androidx.compose.foundation.isSystemInDarkTheme
10+
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
11+
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
1012
import androidx.compose.runtime.Composable
11-
import androidx.compose.ui.Modifier
12-
import androidx.compose.ui.tooling.preview.Preview
13+
import androidx.compose.runtime.CompositionLocalProvider
14+
import androidx.compose.runtime.DisposableEffect
15+
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
16+
import androidx.lifecycle.lifecycleScope
17+
import com.google.accompanist.adaptive.calculateDisplayFeatures
18+
import com.wei.picquest.core.data.utils.NetworkMonitor
1319
import com.wei.picquest.core.designsystem.theme.PqTheme
20+
import com.wei.picquest.core.manager.SnackbarManager
21+
import com.wei.picquest.ui.PqApp
22+
import dagger.hilt.android.AndroidEntryPoint
23+
import kotlinx.coroutines.delay
24+
import kotlinx.coroutines.launch
25+
import javax.inject.Inject
1426

27+
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
28+
@AndroidEntryPoint
1529
class MainActivity : ComponentActivity() {
30+
31+
@Inject
32+
lateinit var snackbarManager: SnackbarManager
33+
34+
@Inject
35+
lateinit var networkMonitor: NetworkMonitor
36+
1637
override fun onCreate(savedInstanceState: Bundle?) {
1738
super.onCreate(savedInstanceState)
39+
val splashScreen = installSplashScreen()
40+
41+
splashScreen.setKeepOnScreenCondition { true }
42+
43+
// Turn off the decor fitting system windows, which allows us to handle insets,
44+
// including IME animations, and go edge-to-edge
45+
// This also sets up the initial system bar style based on the platform theme
46+
enableEdgeToEdge()
47+
1848
setContent {
19-
PqTheme {
20-
// A surface container using the 'background' color from the theme
21-
Surface(
22-
modifier = Modifier.fillMaxSize(),
23-
color = MaterialTheme.colorScheme.background,
24-
) {
25-
Greeting("PicQuest")
49+
val darkTheme = shouldUseDarkTheme()
50+
51+
// Update the edge to edge configuration to match the theme
52+
// This is the same parameters as the default enableEdgeToEdge call, but we manually
53+
// resolve whether or not to show dark theme using uiState, since it can be different
54+
// than the configuration's dark theme value based on the user preference.
55+
DisposableEffect(darkTheme) {
56+
enableEdgeToEdge(
57+
statusBarStyle = SystemBarStyle.auto(
58+
Color.TRANSPARENT,
59+
Color.TRANSPARENT,
60+
) { darkTheme },
61+
navigationBarStyle = SystemBarStyle.auto(
62+
lightScrim,
63+
darkScrim,
64+
) { darkTheme },
65+
)
66+
onDispose {}
67+
}
68+
69+
CompositionLocalProvider() {
70+
PqTheme(darkTheme = darkTheme) {
71+
PqApp(
72+
networkMonitor = networkMonitor,
73+
windowSizeClass = calculateWindowSizeClass(this@MainActivity),
74+
displayFeatures = calculateDisplayFeatures(this@MainActivity),
75+
snackbarManager = snackbarManager,
76+
)
2677
}
2778
}
2879
}
80+
81+
lifecycleScope.launch {
82+
// TODO Wei Loading user data
83+
delay(2_000)
84+
splashScreen.setKeepOnScreenCondition { false }
85+
}
2986
}
3087
}
3188

89+
/**
90+
* Returns `true` if dark theme should be used, as a function of the [uiState] and the
91+
* current system context.
92+
*/
3293
@Composable
33-
fun Greeting(name: String, modifier: Modifier = Modifier) {
34-
Text(
35-
text = "Hello $name!",
36-
modifier = modifier,
37-
)
38-
}
94+
private fun shouldUseDarkTheme(): Boolean = isSystemInDarkTheme()
3995

40-
@Preview(showBackground = true)
41-
@Composable
42-
fun GreetingPreview() {
43-
PqTheme {
44-
Greeting("PicQuest")
45-
}
46-
}
96+
/**
97+
* The default light scrim, as defined by androidx and the platform:
98+
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt;l=35-38;drc=27e7d52e8604a080133e8b842db10c89b4482598
99+
*/
100+
private val lightScrim = android.graphics.Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
101+
102+
/**
103+
* The default dark scrim, as defined by androidx and the platform:
104+
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt;l=40-44;drc=27e7d52e8604a080133e8b842db10c89b4482598
105+
*/
106+
private val darkScrim = android.graphics.Color.argb(0x80, 0x1b, 0x1b, 0x1b)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.wei.picquest.navigation
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.ui.Modifier
5+
import androidx.navigation.compose.NavHost
6+
import androidx.window.layout.DisplayFeature
7+
import com.wei.picquest.core.designsystem.ui.DeviceOrientation
8+
import com.wei.picquest.feature.home.home.navigation.homeGraph
9+
import com.wei.picquest.feature.home.home.navigation.homeRoute
10+
import com.wei.picquest.ui.PqAppState
11+
12+
/**
13+
* Top-level navigation graph. Navigation is organized as explained at
14+
* https://d.android.com/jetpack/compose/nav-adaptive
15+
*
16+
* The navigation graph defined in this file defines the different top level routes. Navigation
17+
* within each route is handled using state and Back Handlers.
18+
*/
19+
@Composable
20+
fun PqNavHost(
21+
modifier: Modifier = Modifier,
22+
appState: PqAppState,
23+
displayFeatures: List<DisplayFeature>,
24+
startDestination: String = homeRoute,
25+
) {
26+
val navController = appState.navController
27+
val navigationType = appState.navigationType
28+
val isPortrait = appState.currentDeviceOrientation == DeviceOrientation.PORTRAIT
29+
val contentType = appState.contentType
30+
31+
NavHost(
32+
navController = navController,
33+
startDestination = startDestination,
34+
modifier = modifier,
35+
) {
36+
homeGraph(
37+
navController = navController,
38+
)
39+
}
40+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.wei.picquest.navigation
2+
3+
import androidx.compose.ui.graphics.vector.ImageVector
4+
import com.wei.picquest.R
5+
import com.wei.picquest.core.designsystem.icon.PqIcons
6+
7+
/**
8+
* Type for the top level destinations in the application. Each of these destinations
9+
* can contain one or more screens (based on the window size). Navigation from one screen to the
10+
* next within a single destination will be handled directly in composables.
11+
*/
12+
enum class TopLevelDestination(
13+
val selectedIcon: ImageVector,
14+
val unselectedIcon: ImageVector,
15+
val iconTextId: Int,
16+
val titleTextId: Int,
17+
) {
18+
HOME(
19+
selectedIcon = PqIcons.Home,
20+
unselectedIcon = PqIcons.HomeBorder,
21+
iconTextId = R.string.home,
22+
titleTextId = R.string.home,
23+
),
24+
PHOTO_LIBRARY(
25+
selectedIcon = PqIcons.PhotoLibrary,
26+
unselectedIcon = PqIcons.PhotoLibraryBorder,
27+
iconTextId = R.string.photo_library,
28+
titleTextId = R.string.photo_library,
29+
),
30+
CONTACT_ME(
31+
selectedIcon = PqIcons.ContactMe,
32+
unselectedIcon = PqIcons.ContactMeBorder,
33+
iconTextId = R.string.contact_me,
34+
titleTextId = R.string.contact_me,
35+
),
36+
}

0 commit comments

Comments
 (0)