Skip to content

Commit 4925831

Browse files
authored
🔀 :: (#808) 로그인 화면 개발
🔀 :: (#808) 로그인 화면 개발
2 parents 7e039f8 + 4b02c3c commit 4925831

File tree

370 files changed

+2517
-3829
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

370 files changed

+2517
-3829
lines changed

app/src/dev/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@
99
<activity
1010
android:name=".android.app.MainActivity"
1111
android:exported="true"
12+
android:icon="@mipmap/ic_launcher"
13+
android:label="@string/app_name"
14+
android:roundIcon="@mipmap/ic_launcher_round"
1215
android:screenOrientation="portrait"
16+
android:theme="@style/Theme.DMS"
1317
tools:node="replace">
18+
19+
<meta-data
20+
android:name="android.app.lib_name"
21+
android:value="" />
1422
<intent-filter>
1523
<action android:name="android.intent.action.MAIN" />
1624
<category android:name="android.intent.category.LAUNCHER" />
Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
package team.aliens.dms.android.app
22

3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.fillMaxWidth
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.layout.statusBarsPadding
37
import androidx.compose.foundation.layout.systemBarsPadding
8+
import androidx.compose.material3.SnackbarHost
49
import androidx.compose.material3.Text
510
import androidx.compose.material3.windowsizeclass.WindowSizeClass
611
import androidx.compose.runtime.Composable
712
import androidx.compose.runtime.LaunchedEffect
813
import androidx.compose.runtime.collectAsState
914
import androidx.compose.runtime.getValue
15+
import androidx.compose.ui.Alignment
1016
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.unit.dp
18+
import androidx.compose.ui.zIndex
1119
import androidx.navigation3.runtime.NavKey
1220
import androidx.navigation3.runtime.entryProvider
1321
import androidx.navigation3.runtime.rememberNavBackStack
1422
import androidx.navigation3.ui.NavDisplay
1523
import kotlinx.coroutines.flow.StateFlow
1624
import kotlinx.serialization.Serializable
1725
import team.aliens.dms.android.core.designsystem.DmsTheme
26+
import team.aliens.dms.android.core.designsystem.snackbar.DmsSnackBar
27+
import team.aliens.dms.android.core.designsystem.snackbar.DmsSnackBarVisuals
1828
import team.aliens.dms.android.feature.onboarding.navigation.OnboardingRoute
1929
import team.aliens.dms.android.feature.signin.navigation.SignInRoute
2030

@@ -32,6 +42,7 @@ fun DmsApp(
3242
windowSizeClass: WindowSizeClass,
3343
isJwtAvailable: StateFlow<Boolean>,
3444
mainViewModel: MainActivityViewModel,
45+
appState: DmsAppState = rememberDmsAppState(),
3546
) {
3647
val isOnboardingCompleted by mainViewModel.isOnboardingCompleted.collectAsState()
3748
val isJwtAvailableState by isJwtAvailable.collectAsState()
@@ -51,28 +62,53 @@ fun DmsApp(
5162
}
5263
}
5364

54-
NavDisplay(
55-
modifier = Modifier.systemBarsPadding(),
56-
backStack = backStack,
57-
onBack = { backStack.removeLastOrNull() },
58-
entryProvider = entryProvider {
59-
entry<OnboardingScreenNav> {
60-
OnboardingRoute(
61-
navigateToSignIn = {
62-
backStack.clear()
63-
backStack.add(SignInScreenNav)
64-
},
65+
Box(
66+
modifier = Modifier.fillMaxWidth(),
67+
) {
68+
NavDisplay(
69+
modifier = Modifier.systemBarsPadding(),
70+
backStack = backStack,
71+
onBack = { backStack.removeLastOrNull() },
72+
entryProvider = entryProvider {
73+
entry<OnboardingScreenNav> {
74+
OnboardingRoute(
75+
navigateToSignIn = {
76+
backStack.clear()
77+
backStack.add(SignInScreenNav)
78+
},
79+
)
80+
}
81+
entry<SignInScreenNav> {
82+
SignInRoute(
83+
navigateToMain = { backStack.add(MainScreenNav) },
84+
navigateToSignUp = {},
85+
onShowSnackBar = { snackBarType, message ->
86+
appState.showSnackBar(snackBarType, message)
87+
},
88+
)
89+
}
90+
entry<MainScreenNav> {
91+
Text(
92+
text = "Main Screen (TODO)",
93+
color = DmsTheme.colorScheme.onSurface,
94+
)
95+
}
96+
},
97+
)
98+
SnackbarHost(
99+
modifier = Modifier
100+
.align(Alignment.TopCenter)
101+
.statusBarsPadding()
102+
.padding(top = 16.dp)
103+
.zIndex(2f),
104+
hostState = appState.snackBarHostState,
105+
snackbar = {
106+
val visuals = it.visuals as? DmsSnackBarVisuals ?: return@SnackbarHost
107+
DmsSnackBar(
108+
snackBarType = visuals.snackBarType,
109+
message = visuals.message,
65110
)
66-
}
67-
entry<SignInScreenNav> {
68-
SignInRoute()
69-
}
70-
entry<MainScreenNav> {
71-
Text(
72-
text = "Main Screen (TODO)",
73-
color = DmsTheme.colorScheme.onSurface,
74-
)
75-
}
76-
},
77-
)
111+
},
112+
)
113+
}
78114
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package team.aliens.dms.android.app
2+
3+
import androidx.compose.material3.SnackbarHostState
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.Stable
6+
import androidx.compose.runtime.remember
7+
import androidx.compose.runtime.rememberCoroutineScope
8+
import androidx.navigation.NavHostController
9+
import androidx.navigation.compose.rememberNavController
10+
import kotlinx.coroutines.CoroutineScope
11+
import kotlinx.coroutines.delay
12+
import kotlinx.coroutines.launch
13+
import kotlinx.coroutines.withTimeoutOrNull
14+
import team.aliens.dms.android.core.designsystem.snackbar.DmsSnackBarType
15+
import team.aliens.dms.android.core.designsystem.snackbar.DmsSnackBarVisuals
16+
import kotlin.time.Duration
17+
import kotlin.time.Duration.Companion.seconds
18+
19+
@Composable
20+
fun rememberDmsAppState(
21+
coroutineScope: CoroutineScope = rememberCoroutineScope(),
22+
snackBarHostState: SnackbarHostState = remember { SnackbarHostState() },
23+
): DmsAppState {
24+
return remember(
25+
coroutineScope,
26+
snackBarHostState,
27+
) {
28+
DmsAppState(
29+
coroutineScope = coroutineScope,
30+
snackBarHostState = snackBarHostState,
31+
)
32+
}
33+
}
34+
35+
@Stable
36+
class DmsAppState(
37+
val coroutineScope: CoroutineScope,
38+
val snackBarHostState: SnackbarHostState,
39+
) {
40+
private fun showSnackBar(
41+
visuals: DmsSnackBarVisuals,
42+
duration: Duration = 2.seconds,
43+
) {
44+
coroutineScope.launch {
45+
withTimeoutOrNull(duration) {
46+
snackBarHostState.showSnackbar(visuals)
47+
}
48+
}
49+
}
50+
51+
fun showSnackBar(
52+
snackBarType: DmsSnackBarType,
53+
message: String,
54+
) {
55+
showSnackBar(
56+
visuals = DmsSnackBarVisuals(
57+
snackBarType = snackBarType,
58+
message = message,
59+
),
60+
)
61+
}
62+
}

app/src/dev/kotlin/team/aliens/dms/android/app/EdgeToEdgeConfig.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package team.aliens.dms.android.app
22

3+
import android.graphics.Color
34
import android.os.Build
45
import androidx.activity.ComponentActivity
6+
import androidx.activity.SystemBarStyle
57
import androidx.activity.enableEdgeToEdge
68

79
fun ComponentActivity.setEdgeToEdgeConfig() {
8-
enableEdgeToEdge()
10+
enableEdgeToEdge(
11+
statusBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT),
12+
navigationBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT),
13+
)
914
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
1015
// Force the 3-button navigation bar to be transparent
1116
// See: https://developer.android.com/develop/ui/views/layout/edge-to-edge#create-transparent

app/src/dev/kotlin/team/aliens/dms/android/app/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class MainActivity : ComponentActivity() {
4545
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
4646
override fun onCreate(savedInstanceState: Bundle?) {
4747
super.onCreate(savedInstanceState)
48+
setEdgeToEdgeConfig()
4849
WindowCompat.setDecorFitsSystemWindows(window, false)
4950
window.setFlags(
5051
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,

app/src/dev/kotlin/team/aliens/dms/android/app/MainActivityViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
package team.aliens.dms.android.app
22

3+
import androidx.lifecycle.ViewModel
34
import androidx.lifecycle.viewModelScope
45
import dagger.hilt.android.lifecycle.HiltViewModel
56
import kotlinx.coroutines.flow.MutableStateFlow
67
import kotlinx.coroutines.flow.StateFlow
78
import kotlinx.coroutines.flow.asStateFlow
89
import kotlinx.coroutines.launch
910
import team.aliens.dms.android.core.jwt.JwtProvider
10-
import team.aliens.dms.android.core.ui.viewmodel.BaseViewModel
1111
import team.aliens.dms.android.onboarding.datastore.OnboardingDataStoreDataSource
1212
import javax.inject.Inject
1313

1414
@HiltViewModel
1515
class MainActivityViewModel @Inject constructor(
1616
private val jwtProvider: JwtProvider,
1717
private val onboardingDataSource: OnboardingDataStoreDataSource,
18-
) : BaseViewModel() {
18+
) : ViewModel() {
1919
val autoSignInAvailable: StateFlow<Boolean> = jwtProvider.isCachedAccessTokenAvailable
2020

2121
private val _isUpdateFailed = MutableStateFlow(false)

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,2 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools">
4-
5-
<uses-feature
6-
android:name="android.hardware.camera"
7-
android:required="false" />
8-
9-
<uses-permission android:name="android.permission.INTERNET" />
10-
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
11-
<uses-permission android:name="android.permission.CAMERA" />
12-
<uses-permission android:name="android.permission.VIBRATE" />
13-
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
14-
15-
<application
16-
android:name="team.aliens.dms.android.app.DmsApplication"
17-
android:allowBackup="true"
18-
android:enableOnBackInvokedCallback="true"
19-
android:icon="@mipmap/ic_launcher"
20-
android:label="@string/app_name"
21-
android:roundIcon="@mipmap/ic_launcher_round"
22-
android:supportsRtl="true"
23-
android:theme="@style/Theme.DMS"
24-
android:usesCleartextTraffic="true"
25-
tools:targetApi="tiramisu">
26-
27-
<activity
28-
android:name=".android.app.MainActivity"
29-
android:exported="true"
30-
android:screenOrientation="portrait">
31-
32-
<meta-data
33-
android:name="android.app.lib_name"
34-
android:value="" />
35-
<intent-filter>
36-
<action android:name="android.intent.action.MAIN" />
37-
38-
<category android:name="android.intent.category.LAUNCHER" />
39-
</intent-filter>
40-
</activity>
41-
<service android:name=".android.app.service.DmsMessagingService"
42-
android:exported="true">
43-
<intent-filter>
44-
<action android:name="com.google.firebase.MESSAGING_EVENT" />
45-
</intent-filter>
46-
</service>
47-
<meta-data
48-
android:name="com.google.firebase.messaging.default_notification_icon"
49-
android:resource="@drawable/ic_notification"/>
50-
<meta-data
51-
android:name="com.google.firebase.messaging.default_notification_channel_id"
52-
android:value="@string/default_notification_channel_id" />
53-
<meta-data
54-
android:name="com.google.firebase.messaging.default_notification_color"
55-
android:resource="@color/primary" />
56-
57-
<receiver
58-
android:name="team.aliens.dms.android.core.widget.meal.MealWidgetReceiver"
59-
android:label="@string/today_meal"
60-
android:exported="true">
61-
<intent-filter>
62-
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
63-
</intent-filter>
64-
<meta-data
65-
android:name="android.appwidget.provider"
66-
android:resource="@xml/big_meal_widget_provider"/>
67-
</receiver>
68-
69-
<provider
70-
android:name="androidx.startup.InitializationProvider"
71-
android:authorities="${applicationId}.androidx-startup"
72-
android:exported="false"
73-
tools:node="merge">
74-
<meta-data
75-
android:name="androidx.work.WorkManagerInitializer"
76-
android:value="androidx.startup"
77-
tools:node="remove" />
78-
</provider>
79-
80-
</application>
81-
</manifest>
2+
<manifest></manifest>
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources xmlns:tools="http://schemas.android.com/tools">
3-
43
<style name="Theme.DMS" parent="Theme.Material3.DayNight.NoActionBar">
54
<item name="android:navigationBarColor">@android:color/transparent</item>
65
<item name="android:statusBarColor">@android:color/transparent</item>
@@ -9,4 +8,4 @@
98
<item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">false</item>
109
<item name="android:windowLightStatusBar">false</item>
1110
</style>
12-
</resources>
11+
</resources>

app/src/main/res/values/themes.xml

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"?>
2-
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
3-
2+
<resources xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">
43
<style name="Theme.DMS" parent="Theme.Material3.DayNight.NoActionBar" android:fitsSystemWindows="true">
54
<item name="android:navigationBarColor">@android:color/transparent</item>
65
<item name="android:statusBarColor">@android:color/transparent</item>
@@ -9,4 +8,4 @@
98
<item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">true</item>
109
<item name="android:windowLightStatusBar">true</item>
1110
</style>
12-
</resources>
11+
</resources>

0 commit comments

Comments
 (0)