Skip to content

Commit 9b6fb24

Browse files
committed
splash screen api and icons
1 parent 77f66f3 commit 9b6fb24

File tree

25 files changed

+201
-45
lines changed

25 files changed

+201
-45
lines changed
25.8 KB
Loading

app/src/main/kotlin/com/espressodev/gptmap/GmApp.kt

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,25 @@ import androidx.compose.ui.platform.LocalConfiguration
1919
import androidx.compose.ui.platform.LocalContext
2020
import androidx.navigation.NavHostController
2121
import androidx.navigation.compose.rememberNavController
22+
import com.espressodev.gptmap.core.common.network_monitor.NetworkMonitor
2223
import com.espressodev.gptmap.core.common.snackbar.SnackbarManager
2324
import com.espressodev.gptmap.core.designsystem.Constants.MEDIUM_PADDING
25+
import com.espressodev.gptmap.feature.login.LOGIN_ROUTE
26+
import com.espressodev.gptmap.feature.map.MAP_ROUTE
2427
import kotlinx.coroutines.CoroutineScope
2528

2629
@Composable
27-
fun GmApp() {
30+
fun GmApp(
31+
networkMonitor: NetworkMonitor,
32+
accountState: AccountState,
33+
appState: GmAppState = rememberAppState(networkMonitor = networkMonitor)
34+
) {
35+
val startDestination = when (accountState) {
36+
AccountState.UserAlreadySignIn -> "$MAP_ROUTE/{favouriteId}"
37+
else -> LOGIN_ROUTE
38+
}
39+
2840
Surface(color = MaterialTheme.colorScheme.background, modifier = Modifier.fillMaxSize()) {
29-
val appState = rememberAppState()
3041
Scaffold(
3142
snackbarHost = {
3243
SnackbarHost(
@@ -37,7 +48,11 @@ fun GmApp() {
3748
},
3849
contentWindowInsets = WindowInsets(0, 0, 0, 0)
3950
) {
40-
GmNavHost(appState = appState, modifier = Modifier.padding(it))
51+
GmNavHost(
52+
appState = appState,
53+
modifier = Modifier.padding(it),
54+
startDestination = startDestination
55+
)
4156
}
4257
}
4358
}
@@ -51,13 +66,15 @@ fun resources(): Resources {
5166

5267
@Composable
5368
fun rememberAppState(
69+
networkMonitor: NetworkMonitor,
5470
navController: NavHostController = rememberNavController(),
5571
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
5672
snackbarManager: SnackbarManager = SnackbarManager,
5773
resources: Resources = resources(),
5874
coroutineScope: CoroutineScope = rememberCoroutineScope()
5975
) = remember(navController, snackbarHostState, coroutineScope) {
6076
GmAppState(
77+
networkMonitor,
6178
navController,
6279
snackbarHostState,
6380
snackbarManager,

app/src/main/kotlin/com/espressodev/gptmap/GmAppState.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
package com.espressodev.gptmap
22

33
import android.content.res.Resources
4+
import android.util.Log
45
import androidx.compose.material3.SnackbarHostState
56
import androidx.compose.runtime.Stable
67
import androidx.navigation.NavHostController
8+
import com.espressodev.gptmap.core.common.network_monitor.NetworkMonitor
79
import com.espressodev.gptmap.core.common.snackbar.SnackbarManager
810
import com.espressodev.gptmap.core.common.snackbar.SnackbarMessage.Companion.toMessage
11+
import com.espressodev.gptmap.core.common.splash_navigation.AfterSplashState
12+
import com.espressodev.gptmap.core.common.splash_navigation.SplashNavigationManager
13+
import com.espressodev.gptmap.feature.map.navigateToMap
914
import kotlinx.coroutines.CoroutineScope
1015
import kotlinx.coroutines.flow.filterNotNull
1116
import kotlinx.coroutines.launch
17+
import org.junit.After
1218

1319
@Stable
1420
class GmAppState(
21+
networkMonitor: NetworkMonitor,
1522
val navController: NavHostController,
1623
val snackbarHostState: SnackbarHostState,
1724
private val snackbarManager: SnackbarManager,

app/src/main/kotlin/com/espressodev/gptmap/GmNavHost.kt

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ package com.espressodev.gptmap
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.LaunchedEffect
5+
import androidx.compose.runtime.getValue
56
import androidx.compose.ui.Modifier
7+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
68
import androidx.navigation.NavHostController
79
import androidx.navigation.compose.NavHost
10+
import com.espressodev.gptmap.core.common.splash_navigation.AfterSplashState
11+
import com.espressodev.gptmap.core.common.splash_navigation.SplashNavigationManager
812
import com.espressodev.gptmap.feature.favourite.favouriteScreen
913
import com.espressodev.gptmap.feature.favourite.navigateToFavourite
1014
import com.espressodev.gptmap.feature.forgot_password.forgotPasswordScreen
@@ -33,7 +37,7 @@ fun GmNavHost(
3337
) {
3438
val navController = appState.navController
3539

36-
NavigationListener(navController)
40+
navController.NavigationListener()
3741

3842
NavHost(
3943
modifier = modifier,
@@ -58,20 +62,39 @@ fun GmNavHost(
5862
)
5963
forgotPasswordScreen(navigateToLogin = navController::navigateToLogin)
6064
streetViewScreen()
61-
favouriteScreen(popUp = navController::popBackStack, navigateToMap = navController::navigateToMap)
62-
screenshotScreen(popUp = navController::popBackStack, navigateToMap = navController::navigateToMap)
65+
favouriteScreen(
66+
popUp = navController::popBackStack,
67+
navigateToMap = navController::navigateToMap
68+
)
69+
screenshotScreen(
70+
popUp = navController::popBackStack,
71+
navigateToMap = navController::navigateToMap
72+
)
6373
screenshotGalleryScreen(popUp = navController::popBackStack)
64-
profileScreen(popUp = navController::popBackStack, navigateToLogin = navController::navigateToLogin)
74+
profileScreen(
75+
popUp = navController::popBackStack,
76+
navigateToLogin = navController::navigateToLogin
77+
)
6578
}
79+
80+
navController.SplashNavigationListener()
6681
}
6782

6883
@Composable
69-
private fun NavigationListener(navController: NavHostController) {
70-
LaunchedEffect(navController) {
71-
navController.addOnDestinationChangedListener { controller, destination, arguments ->
84+
private fun NavHostController.NavigationListener() {
85+
LaunchedEffect(this) {
86+
this@NavigationListener.addOnDestinationChangedListener { controller, destination, arguments ->
7287
println("Current back stack: $destination")
7388
println("Parent back stack: ${controller.previousBackStackEntry?.destination}")
7489
println("Arguments: $arguments")
7590
}
7691
}
7792
}
93+
94+
@Composable
95+
private fun NavHostController.SplashNavigationListener() {
96+
val splashNavState by SplashNavigationManager.splashNavigationState.collectAsStateWithLifecycle()
97+
if (splashNavState == AfterSplashState.Map) {
98+
navigateToMap()
99+
}
100+
}

app/src/main/kotlin/com/espressodev/gptmap/MainActivity.kt

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,66 @@ import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
66
import androidx.activity.enableEdgeToEdge
7+
import androidx.activity.viewModels
8+
import androidx.compose.runtime.getValue
9+
import androidx.compose.runtime.mutableStateOf
10+
import androidx.compose.runtime.remember
11+
import androidx.compose.runtime.setValue
12+
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
13+
import androidx.lifecycle.Lifecycle
14+
import androidx.lifecycle.lifecycleScope
15+
import androidx.lifecycle.repeatOnLifecycle
16+
import com.espressodev.gptmap.core.common.network_monitor.NetworkMonitor
717
import com.espressodev.gptmap.core.designsystem.theme.GptmapTheme
818
import dagger.hilt.android.AndroidEntryPoint
19+
import kotlinx.coroutines.CoroutineScope
20+
import kotlinx.coroutines.launch
21+
import javax.inject.Inject
22+
923
@AndroidEntryPoint
1024
class MainActivity : ComponentActivity() {
25+
26+
@Inject
27+
lateinit var networkMonitor: NetworkMonitor
28+
29+
private val viewModel: MainActivityViewModel by viewModels()
30+
1131
override fun onCreate(savedInstanceState: Bundle?) {
32+
installSplashScreen()
1233
super.onCreate(savedInstanceState)
34+
35+
var isEmailVerified by mutableStateOf(AccountState.Idle)
36+
37+
scopeWithLifecycle {
38+
viewModel.accountService.collect {
39+
isEmailVerified = when (it) {
40+
AccountState.Idle -> {
41+
AccountState.Idle
42+
}
43+
44+
AccountState.UserAlreadySignIn -> {
45+
AccountState.UserAlreadySignIn
46+
}
47+
48+
AccountState.UserNotSignIn -> {
49+
AccountState.UserNotSignIn
50+
}
51+
}
52+
}
53+
}
54+
1355
enableEdgeToEdge()
1456
setContent {
15-
GptmapTheme { GmApp() }
57+
GptmapTheme {
58+
if (isEmailVerified != AccountState.Idle)
59+
GmApp(networkMonitor, isEmailVerified)
60+
}
61+
}
62+
}
63+
64+
private fun scopeWithLifecycle(block: suspend CoroutineScope.() -> Unit) {
65+
lifecycleScope.launch {
66+
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED, block = block)
1667
}
1768
}
1869
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.espressodev.gptmap
2+
3+
import androidx.lifecycle.ViewModel
4+
import androidx.lifecycle.viewModelScope
5+
import com.espressodev.gptmap.core.data.AccountService
6+
import com.espressodev.gptmap.core.mongodb.RealmAccountService
7+
import dagger.hilt.android.lifecycle.HiltViewModel
8+
import kotlinx.coroutines.flow.MutableStateFlow
9+
import kotlinx.coroutines.flow.asStateFlow
10+
import kotlinx.coroutines.flow.update
11+
import kotlinx.coroutines.launch
12+
import kotlinx.coroutines.tasks.await
13+
import javax.inject.Inject
14+
15+
enum class AccountState {
16+
Idle,
17+
UserAlreadySignIn,
18+
UserNotSignIn,
19+
}
20+
21+
@HiltViewModel
22+
class MainActivityViewModel @Inject constructor(
23+
accountService: AccountService,
24+
realmAccountService: RealmAccountService,
25+
) : ViewModel() {
26+
private val _accountState = MutableStateFlow(AccountState.Idle)
27+
val accountService = _accountState.asStateFlow()
28+
init {
29+
viewModelScope.launch {
30+
if (accountService.isEmailVerified) {
31+
accountService.firebaseUser?.getIdToken(true)?.await()?.token?.let {
32+
realmAccountService.loginWithEmail(it).getOrElse {
33+
_accountState.update { AccountState.UserNotSignIn }
34+
}.run {
35+
_accountState.update { AccountState.UserAlreadySignIn }
36+
}
37+
}
38+
} else {
39+
_accountState.update { AccountState.UserNotSignIn }
40+
}
41+
}
42+
}
43+
}
Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2-
xmlns:aapt="http://schemas.android.com/aapt"
32
android:width="108dp"
43
android:height="108dp"
5-
android:viewportWidth="108"
6-
android:viewportHeight="108">
7-
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
8-
<aapt:attr name="android:fillColor">
9-
<gradient
10-
android:endX="85.84757"
11-
android:endY="92.4963"
12-
android:startX="42.9492"
13-
android:startY="49.59793"
14-
android:type="linear">
15-
<item
16-
android:color="#44000000"
17-
android:offset="0.0" />
18-
<item
19-
android:color="#00000000"
20-
android:offset="1.0" />
21-
</gradient>
22-
</aapt:attr>
23-
</path>
4+
android:viewportWidth="500"
5+
android:viewportHeight="500">
6+
<group android:scaleX="0.5"
7+
android:scaleY="0.5"
8+
android:translateX="125"
9+
android:translateY="125">
2410
<path
25-
android:fillColor="#FFFFFF"
26-
android:fillType="nonZero"
27-
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
28-
android:strokeWidth="1"
29-
android:strokeColor="#00000000" />
30-
</vector>
11+
android:pathData="M250,250m-240,0a240,240 0,1 1,480 0a240,240 0,1 1,-480 0"
12+
android:strokeWidth="20"
13+
android:fillColor="#00000000"
14+
android:strokeColor="#000000"/>
15+
<path
16+
android:pathData="M250,99C319.04,99 375,154.96 375,224C375,275.15 320.64,331.13 271.55,381.7C265.93,387.48 260.39,393.19 255,398.82C253,401.73 247,401.73 245,398.82C237.08,390.59 229.18,382.57 221.42,374.7C170.93,323.46 126.73,278.61 125,224C125,154.96 180.96,99 250,99ZM187,224H312C311.73,189.71 283.85,162 249.5,162C215.15,162 187.27,189.71 187,224ZM249.5,286C283.85,286 311.73,258.29 312,224H187C187.27,258.29 215.15,286 249.5,286Z"
17+
android:fillColor="#000000"
18+
android:fillType="evenOdd"/>
19+
</group>
20+
</vector>
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3-
<background android:drawable="@drawable/ic_launcher_background" />
4-
<foreground android:drawable="@drawable/ic_launcher_foreground" />
5-
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
3+
<background android:drawable="@color/ic_launcher_background"/>
4+
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
65
</adaptive-icon>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3-
<background android:drawable="@drawable/ic_launcher_background" />
4-
<foreground android:drawable="@drawable/ic_launcher_foreground" />
5-
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
3+
<background android:drawable="@color/ic_launcher_background"/>
4+
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
65
</adaptive-icon>
-122 Bytes
Loading

0 commit comments

Comments
 (0)