diff --git a/.editorconfig b/.editorconfig index 4843fc57..0716e72f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,4 +12,6 @@ trim_trailing_whitespace = true insert_final_newline = true tab_width = 4 ij_kotlin_allow_trailing_comma = true -ktlint_function_naming_ignore_when_annotated_with=Composable \ No newline at end of file +ij_kotlin_allow_trailing_comma_on_call_site = true +ktlint_function_naming_ignore_when_annotated_with=Composable +ktlint_standard_annotation = disabled \ No newline at end of file diff --git a/core/datastore/src/main/java/com/threegap/bitnagil/datastore/serializer/AuthTokenSerializer.kt b/core/datastore/src/main/java/com/threegap/bitnagil/datastore/serializer/AuthTokenSerializer.kt index a22ff63a..952cc266 100644 --- a/core/datastore/src/main/java/com/threegap/bitnagil/datastore/serializer/AuthTokenSerializer.kt +++ b/core/datastore/src/main/java/com/threegap/bitnagil/datastore/serializer/AuthTokenSerializer.kt @@ -10,41 +10,39 @@ import java.io.OutputStream import java.util.Base64 import javax.inject.Inject -internal class AuthTokenSerializer - @Inject - constructor( - private val crypto: Crypto, - ) : TokenSerializer { - override val defaultValue: AuthToken - get() = AuthToken() +internal class AuthTokenSerializer @Inject constructor( + private val crypto: Crypto, +) : TokenSerializer { + override val defaultValue: AuthToken + get() = AuthToken() - override suspend fun readFrom(input: InputStream): AuthToken { - return try { - val encryptedBytes = - withContext(Dispatchers.IO) { - input.use { it.readBytes() } - } - val decodedBytes = Base64.getDecoder().decode(encryptedBytes) - val decryptedBytes = crypto.decrypt(decodedBytes) - val decodedJsonString = decryptedBytes.decodeToString() - Json.decodeFromString(decodedJsonString) - } catch (e: Exception) { - AuthToken() - } + override suspend fun readFrom(input: InputStream): AuthToken { + return try { + val encryptedBytes = + withContext(Dispatchers.IO) { + input.use { it.readBytes() } + } + val decodedBytes = Base64.getDecoder().decode(encryptedBytes) + val decryptedBytes = crypto.decrypt(decodedBytes) + val decodedJsonString = decryptedBytes.decodeToString() + Json.decodeFromString(decodedJsonString) + } catch (e: Exception) { + AuthToken() } + } - override suspend fun writeTo( - t: AuthToken, - output: OutputStream, - ) { - val json = Json.encodeToString(t) - val bytes = json.toByteArray() - val encryptedBytes = crypto.encrypt(bytes) - val encryptedBytesBase64 = Base64.getEncoder().encode(encryptedBytes) - withContext(Dispatchers.IO) { - output.use { - it.write(encryptedBytesBase64) - } + override suspend fun writeTo( + t: AuthToken, + output: OutputStream, + ) { + val json = Json.encodeToString(t) + val bytes = json.toByteArray() + val encryptedBytes = crypto.encrypt(bytes) + val encryptedBytesBase64 = Base64.getEncoder().encode(encryptedBytes) + withContext(Dispatchers.IO) { + output.use { + it.write(encryptedBytesBase64) } } } +} diff --git a/core/datastore/src/main/java/com/threegap/bitnagil/datastore/storage/AuthTokenDataStoreImpl.kt b/core/datastore/src/main/java/com/threegap/bitnagil/datastore/storage/AuthTokenDataStoreImpl.kt index afdf001f..efdc5730 100644 --- a/core/datastore/src/main/java/com/threegap/bitnagil/datastore/storage/AuthTokenDataStoreImpl.kt +++ b/core/datastore/src/main/java/com/threegap/bitnagil/datastore/storage/AuthTokenDataStoreImpl.kt @@ -6,62 +6,60 @@ import com.threegap.bitnagil.datastore.model.AuthToken import kotlinx.coroutines.flow.Flow import javax.inject.Inject -internal class AuthTokenDataStoreImpl - @Inject - constructor( - private val dataStore: DataStore, - ) : AuthTokenDataStore { - override val tokenFlow: Flow = dataStore.data +internal class AuthTokenDataStoreImpl @Inject constructor( + private val dataStore: DataStore, +) : AuthTokenDataStore { + override val tokenFlow: Flow = dataStore.data - override suspend fun updateAuthToken(authToken: AuthToken): AuthToken = - runCatching { - dataStore.updateData { authToken } - }.fold( - onSuccess = { it }, - onFailure = { - Log.e(TAG, "updateAuthToken failed:", it) - throw it - }, - ) + override suspend fun updateAuthToken(authToken: AuthToken): AuthToken = + runCatching { + dataStore.updateData { authToken } + }.fold( + onSuccess = { it }, + onFailure = { + Log.e(TAG, "updateAuthToken failed:", it) + throw it + }, + ) - override suspend fun updateAccessToken(accessToken: String): AuthToken = - runCatching { - dataStore.updateData { authToken -> - authToken.copy(accessToken = accessToken) - } - }.fold( - onSuccess = { it }, - onFailure = { - Log.e(TAG, "updateAccessToken failed:", it) - throw it - }, - ) + override suspend fun updateAccessToken(accessToken: String): AuthToken = + runCatching { + dataStore.updateData { authToken -> + authToken.copy(accessToken = accessToken) + } + }.fold( + onSuccess = { it }, + onFailure = { + Log.e(TAG, "updateAccessToken failed:", it) + throw it + }, + ) - override suspend fun updateRefreshToken(refreshToken: String): AuthToken = - runCatching { - dataStore.updateData { authToken -> - authToken.copy(refreshToken = refreshToken) - } - }.fold( - onSuccess = { it }, - onFailure = { - Log.e(TAG, "updateRefreshToken failed:", it) - throw it - }, - ) + override suspend fun updateRefreshToken(refreshToken: String): AuthToken = + runCatching { + dataStore.updateData { authToken -> + authToken.copy(refreshToken = refreshToken) + } + }.fold( + onSuccess = { it }, + onFailure = { + Log.e(TAG, "updateRefreshToken failed:", it) + throw it + }, + ) - override suspend fun clearAuthToken(): AuthToken = - runCatching { - dataStore.updateData { AuthToken() } - }.fold( - onSuccess = { it }, - onFailure = { - Log.e(TAG, "clearAuthToken failed:", it) - throw it - }, - ) + override suspend fun clearAuthToken(): AuthToken = + runCatching { + dataStore.updateData { AuthToken() } + }.fold( + onSuccess = { it }, + onFailure = { + Log.e(TAG, "clearAuthToken failed:", it) + throw it + }, + ) - companion object { - private const val TAG = "AuthTokenDataStore" - } + companion object { + private const val TAG = "AuthTokenDataStore" } +} diff --git a/core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Type.kt b/core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Type.kt index 2297913d..695118d6 100644 --- a/core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Type.kt +++ b/core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/Type.kt @@ -9,12 +9,11 @@ import androidx.compose.ui.unit.sp // Set of Material typography styles to start with val Typography = Typography( - bodyLarge = - TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp, - ), + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp, + ), ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4b59be35..35b6d950 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ versionName = "1.0" androidGradlePlugin = "8.10.1" # Formatting Plugin -ktlint = "12.3.0" +ktlint = "11.3.2" # AndroidX androidxCore = "1.16.0" diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt index 9f8b3b5c..f57b0e97 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt @@ -17,10 +17,9 @@ fun HomeScreen(modifier: Modifier = Modifier) { Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, - modifier = - modifier - .fillMaxSize() - .background(Color.White), + modifier = modifier + .fillMaxSize() + .background(Color.White), ) { Text(text = "여긴 홈 화면") } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginScreen.kt index dcf6ff2e..b7a5904a 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginScreen.kt @@ -56,10 +56,9 @@ private fun LoginScreen( modifier: Modifier = Modifier, ) { Box( - modifier = - modifier - .fillMaxSize() - .background(Color.White), + modifier = modifier + .fillMaxSize() + .background(Color.White), ) { Text( text = "빛나길 로고", @@ -68,10 +67,9 @@ private fun LoginScreen( Button( onClick = onKakaoLoginClick, - modifier = - Modifier - .align(Alignment.BottomCenter) - .padding(20.dp), + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(20.dp), ) { Text( text = "카카오 로그인버튼", diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginViewModel.kt index 653b8619..6964a4cb 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/login/LoginViewModel.kt @@ -14,55 +14,53 @@ import org.orbitmvi.orbit.syntax.simple.SimpleSyntax import javax.inject.Inject @HiltViewModel -class LoginViewModel - @Inject - constructor( - private val savedStateHandle: SavedStateHandle, - ) : MviViewModel( - initState = LoginState(), - savedStateHandle = savedStateHandle, - ) { - override suspend fun SimpleSyntax.reduceState( - intent: LoginIntent, - state: LoginState, - ): LoginState? = - when (intent) { - is LoginIntent.OnKakaoLoginClick -> { - if (!intent.onKakaoTalkLoginAvailable) { - sendSideEffect(LoginSideEffect.RequestKakaoAccountLogin) - } else { - sendSideEffect(LoginSideEffect.RequestKakaoTalkLogin) - } - null +class LoginViewModel @Inject constructor( + private val savedStateHandle: SavedStateHandle, +) : MviViewModel( + initState = LoginState(), + savedStateHandle = savedStateHandle, +) { + override suspend fun SimpleSyntax.reduceState( + intent: LoginIntent, + state: LoginState, + ): LoginState? = + when (intent) { + is LoginIntent.OnKakaoLoginClick -> { + if (!intent.onKakaoTalkLoginAvailable) { + sendSideEffect(LoginSideEffect.RequestKakaoAccountLogin) + } else { + sendSideEffect(LoginSideEffect.RequestKakaoTalkLogin) } + null + } - is LoginIntent.OnKakaoLoginResult -> { - when { - intent.token != null -> { - Log.i("KakaoLogin", "로그인 성공 ${intent.token.accessToken}") - UserApiClient.instance.me { user, error -> - if (error != null) { - Log.e("KakaoLogin", "사용자 정보 요청 실패", error) - } else if (user != null) { - Log.i( - "KakaoLogin", - "사용자 정보 요청 성공" + - "\n이메일: ${user.kakaoAccount?.email}" + - "\n닉네임: ${user.kakaoAccount?.profile?.nickname}", - ) - } + is LoginIntent.OnKakaoLoginResult -> { + when { + intent.token != null -> { + Log.i("KakaoLogin", "로그인 성공 ${intent.token.accessToken}") + UserApiClient.instance.me { user, error -> + if (error != null) { + Log.e("KakaoLogin", "사용자 정보 요청 실패", error) + } else if (user != null) { + Log.i( + "KakaoLogin", + "사용자 정보 요청 성공" + + "\n이메일: ${user.kakaoAccount?.email}" + + "\n닉네임: ${user.kakaoAccount?.profile?.nickname}", + ) } } + } - intent.error is ClientError && intent.error.reason == ClientErrorCause.Cancelled -> { - Log.e("KakaoLogin", "로그인 취소", intent.error) - } + intent.error is ClientError && intent.error.reason == ClientErrorCause.Cancelled -> { + Log.e("KakaoLogin", "로그인 취소", intent.error) + } - intent.error != null -> { - Log.e("KakaoLogin", "로그인 실패", intent.error) - } + intent.error != null -> { + Log.e("KakaoLogin", "로그인 실패", intent.error) } - null } + null } - } + } +}