diff --git a/app/src/main/java/com/whyranoid/walkie/KoinModules.kt b/app/src/main/java/com/whyranoid/walkie/KoinModules.kt index aeeaddf2..303c0e12 100644 --- a/app/src/main/java/com/whyranoid/walkie/KoinModules.kt +++ b/app/src/main/java/com/whyranoid/walkie/KoinModules.kt @@ -59,6 +59,7 @@ import com.whyranoid.domain.usecase.GetUserBadgesUseCase import com.whyranoid.domain.usecase.GetUserDetailUseCase import com.whyranoid.domain.usecase.GetUserPostPreviewsUseCase import com.whyranoid.domain.usecase.LikePostUseCase +import com.whyranoid.domain.usecase.RequestLoginUseCase import com.whyranoid.domain.usecase.SignOutUseCase import com.whyranoid.domain.usecase.UploadPostUseCase import com.whyranoid.domain.usecase.broadcast.AddGpsListener @@ -166,6 +167,7 @@ val useCaseModule = module { single { GetMyFollowingUseCase(get(), get()) } single { GetFollowingsPostsUseCase(get(), get()) } single { LikePostUseCase(get(), get()) } + single { RequestLoginUseCase(get()) } } val databaseModule = module { diff --git a/data/src/main/java/com/whyranoid/data/API.kt b/data/src/main/java/com/whyranoid/data/API.kt index 4b069a5e..c65b80ff 100644 --- a/data/src/main/java/com/whyranoid/data/API.kt +++ b/data/src/main/java/com/whyranoid/data/API.kt @@ -27,6 +27,8 @@ object API { const val SEND_LIKE = "api/community/send-like" + const val LOGIN = "api/walkies/login" + object WalkingControl { const val RUNNING_START = "api/walk/start" diff --git a/data/src/main/java/com/whyranoid/data/datasource/account/AccountDataSourceImpl.kt b/data/src/main/java/com/whyranoid/data/datasource/account/AccountDataSourceImpl.kt index 3dbfd8b2..4e3aa8c4 100644 --- a/data/src/main/java/com/whyranoid/data/datasource/account/AccountDataSourceImpl.kt +++ b/data/src/main/java/com/whyranoid/data/datasource/account/AccountDataSourceImpl.kt @@ -1,7 +1,10 @@ package com.whyranoid.data.datasource.account +import com.whyranoid.data.getResult import com.whyranoid.data.model.account.SignUpRequest +import com.whyranoid.data.model.account.toLoginData import com.whyranoid.domain.datasource.AccountDataSource +import com.whyranoid.domain.model.account.LoginData class AccountDataSourceImpl(private val accountService: AccountService) : AccountDataSource { override suspend fun signUp( @@ -38,4 +41,13 @@ class AccountDataSourceImpl(private val accountService: AccountService) : Accoun requireNotNull(response.body()).let { Pair(it.isDuplicated, it.nickName ?: "empty") } } } + + override suspend fun signIn(authorId: String): Result { + return kotlin.runCatching { + val response = accountService.login(authorId) + response.getResult { + it.toLoginData() + } + } + } } diff --git a/data/src/main/java/com/whyranoid/data/datasource/account/AccountService.kt b/data/src/main/java/com/whyranoid/data/datasource/account/AccountService.kt index 87058ce1..2d430dbb 100644 --- a/data/src/main/java/com/whyranoid/data/datasource/account/AccountService.kt +++ b/data/src/main/java/com/whyranoid/data/datasource/account/AccountService.kt @@ -1,6 +1,7 @@ package com.whyranoid.data.datasource.account import com.whyranoid.data.API +import com.whyranoid.data.model.account.LoginDataResponse import com.whyranoid.data.model.account.NickCheckResponse import com.whyranoid.data.model.account.SignUpRequest import com.whyranoid.data.model.account.SignUpResponse @@ -20,4 +21,9 @@ interface AccountService { suspend fun signUp( @Body signUpRequest: SignUpRequest, ): Response + + @GET(API.LOGIN) + suspend fun login( + @Query("uid") uid: String, + ): Response } diff --git a/data/src/main/java/com/whyranoid/data/model/account/LoginDataResponse.kt b/data/src/main/java/com/whyranoid/data/model/account/LoginDataResponse.kt new file mode 100644 index 00000000..5810ffcb --- /dev/null +++ b/data/src/main/java/com/whyranoid/data/model/account/LoginDataResponse.kt @@ -0,0 +1,15 @@ +package com.whyranoid.data.model.account + +import com.whyranoid.domain.model.account.LoginData + +data class LoginDataResponse( + val walkieId: Long, + val nickname: String, + val profileImg: String, +) + +fun LoginDataResponse.toLoginData() = LoginData( + walkieId = walkieId, + nickname = nickname, + profileImg = profileImg, +) \ No newline at end of file diff --git a/data/src/main/java/com/whyranoid/data/repository/AccountRepositoryImpl.kt b/data/src/main/java/com/whyranoid/data/repository/AccountRepositoryImpl.kt index 4232c60f..35274fb3 100644 --- a/data/src/main/java/com/whyranoid/data/repository/AccountRepositoryImpl.kt +++ b/data/src/main/java/com/whyranoid/data/repository/AccountRepositoryImpl.kt @@ -49,10 +49,19 @@ class AccountRepositoryImpl( } } - override suspend fun signIn(): Result { + override suspend fun signIn(authorId: String, name: String): Result { return kotlin.runCatching { - // TODO API CALL and update - 0L + accountDataSource.signIn(authorId).onSuccess { + val (uid, nickname, profileImg) = it + accountDataStore.updateUId(uid) + accountDataStore.updateUserName(name) + accountDataStore.updateNickName(nickname) + profileImg?.let { url -> accountDataStore.updateProfileUrl(url) } + return@runCatching it.walkieId + }.onFailure { + // Error handling + } + return Result.failure(Exception("로그인 실패")) } } diff --git a/domain/src/main/java/com/whyranoid/domain/datasource/AccountDataSource.kt b/domain/src/main/java/com/whyranoid/domain/datasource/AccountDataSource.kt index d18d99a7..56b5e794 100644 --- a/domain/src/main/java/com/whyranoid/domain/datasource/AccountDataSource.kt +++ b/domain/src/main/java/com/whyranoid/domain/datasource/AccountDataSource.kt @@ -1,5 +1,7 @@ package com.whyranoid.domain.datasource +import com.whyranoid.domain.model.account.LoginData + interface AccountDataSource { suspend fun signUp( nickName: String, @@ -10,4 +12,6 @@ interface AccountDataSource { ): Result suspend fun nickCheck(nickName: String): Result> + + suspend fun signIn(authorId: String): Result } diff --git a/domain/src/main/java/com/whyranoid/domain/model/account/LoginData.kt b/domain/src/main/java/com/whyranoid/domain/model/account/LoginData.kt new file mode 100644 index 00000000..6c3063b2 --- /dev/null +++ b/domain/src/main/java/com/whyranoid/domain/model/account/LoginData.kt @@ -0,0 +1,7 @@ +package com.whyranoid.domain.model.account + +data class LoginData( + val walkieId: Long, + val nickname: String, + val profileImg: String, +) \ No newline at end of file diff --git a/domain/src/main/java/com/whyranoid/domain/repository/AccountRepository.kt b/domain/src/main/java/com/whyranoid/domain/repository/AccountRepository.kt index b7c09542..a92868c4 100644 --- a/domain/src/main/java/com/whyranoid/domain/repository/AccountRepository.kt +++ b/domain/src/main/java/com/whyranoid/domain/repository/AccountRepository.kt @@ -26,7 +26,7 @@ interface AccountRepository { suspend fun getUID(): Long - suspend fun signIn(): Result + suspend fun signIn(authorId: String, name: String): Result suspend fun singOut(): Result suspend fun checkNickName(nickName: String): Result> diff --git a/domain/src/main/java/com/whyranoid/domain/usecase/RequestLoginUseCase.kt b/domain/src/main/java/com/whyranoid/domain/usecase/RequestLoginUseCase.kt new file mode 100644 index 00000000..10151cb7 --- /dev/null +++ b/domain/src/main/java/com/whyranoid/domain/usecase/RequestLoginUseCase.kt @@ -0,0 +1,12 @@ +package com.whyranoid.domain.usecase + +import com.whyranoid.domain.repository.AccountRepository + +class RequestLoginUseCase( + private val accountRepository: AccountRepository, +) { + + suspend operator fun invoke(authorId: String, name: String): Result { + return accountRepository.signIn(authorId, name) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInInitialScreen.kt b/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInInitialScreen.kt index d3bc50ba..e6ff3d22 100644 --- a/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInInitialScreen.kt +++ b/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInInitialScreen.kt @@ -39,20 +39,25 @@ import com.google.android.gms.auth.api.signin.GoogleSignInAccount import com.google.android.gms.auth.api.signin.GoogleSignInOptions import com.google.android.gms.common.api.ApiException import com.google.android.gms.tasks.Task +import com.whyranoid.domain.usecase.RequestLoginUseCase import com.whyranoid.presentation.R import com.whyranoid.presentation.theme.WalkieTheme import com.whyranoid.presentation.theme.WalkieTypography import kotlinx.coroutines.launch +import org.koin.androidx.compose.get @SuppressLint("UnusedMaterialScaffoldPaddingParameter") @Composable fun SignInInitialScreen( isDay: Boolean = true, + alreadySignUp: () -> Unit, goToAgreeState: (authId: String, name: String, url: String?) -> Unit, ) { val scope = rememberCoroutineScope() val scaffoldState = rememberScaffoldState() + val requestLoginUseCase = get() + val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == AppCompatActivity.RESULT_OK) { @@ -60,12 +65,27 @@ fun SignInInitialScreen( val task: Task = GoogleSignIn.getSignedInAccountFromIntent(data) task.getResult(ApiException::class.java)?.let { account -> - handleSignInResult( - account = account, - goToAgreeState = goToAgreeState, - ) { errorMsg -> - scope.launch { scaffoldState.snackbarHostState.showSnackbar(errorMsg) } + + scope.launch { + val isRegistered = requestLoginUseCase( + requireNotNull(account.id), + requireNotNull(account.displayName) + ).getOrNull() + + if (isRegistered != -1L && isRegistered != null) { + alreadySignUp() + } else { + handleSignInResult( + account = account, + goToAgreeState = goToAgreeState, + ) { errorMsg -> + scope.launch { + scaffoldState.snackbarHostState.showSnackbar(errorMsg) + } + } + } } + } } else { scope.launch { @@ -157,7 +177,7 @@ private fun signInWithGoogle( @Composable fun DaySignInInitialScreenPreview() { WalkieTheme { - SignInInitialScreen(true) { _, _, _ -> } + SignInInitialScreen(true, {}) { _, _, _ -> } } } @@ -165,6 +185,6 @@ fun DaySignInInitialScreenPreview() { @Composable fun NightSignInInitialScreenPreview() { WalkieTheme { - SignInInitialScreen(false) { _, _, _ -> } + SignInInitialScreen(false, {}) { _, _, _ -> } } } diff --git a/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInScreen.kt b/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInScreen.kt index 34e8a894..243a0cb8 100644 --- a/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInScreen.kt +++ b/presentation/src/main/java/com/whyranoid/presentation/screens/signin/SignInScreen.kt @@ -17,7 +17,7 @@ fun SignInScreen( val signInState = viewModel.signInState.collectAsStateWithLifecycle() when (signInState.value) { - is SignInState.InitialState -> SignInInitialScreen(isDay = isDay) { authId, name, url -> + is SignInState.InitialState -> SignInInitialScreen(isDay = isDay, finishSignIn) { authId, name, url -> viewModel.goToAgreeState(authId, name, url) }