Skip to content

Commit

Permalink
[feat] #7 sync with compose branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Sangwook123 committed May 3, 2024
1 parent 422db96 commit 2cf484b
Show file tree
Hide file tree
Showing 33 changed files with 635 additions and 15 deletions.
11 changes: 1 addition & 10 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ android {
versionName = "1.0"
}
viewBinding.enable = true
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
}

dependencies {
Expand All @@ -30,6 +21,6 @@ dependencies {
implementation(projects.core.database)
implementation(projects.core.common)
implementation(projects.core.data)

implementation(projects.core.network)
implementation(projects.feature.main)
}
1 change: 1 addition & 0 deletions build-logic/convention/src/main/java/DataPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal class DataPlugin : Plugin<Project> {
dependencies {
"implementation"(project(":core:model"))
"implementation"(libs.findBundle("coroutine").get())
"implementation"(libs.findLibrary("androidx-paging").get())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sopt.convention

import com.android.build.api.dsl.CommonExtension
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
Expand All @@ -15,6 +16,17 @@ internal fun Project.configureKotlinAndroid(
minSdk = Const.minSdk

vectorDrawables.useSupportLibrary = true

buildConfigField(
type = "String",
name = "AUTH_BASE_URL",
gradleLocalProperties(rootDir, providers).getProperty("auth.base.url")
)
buildConfigField(
type = "String",
name = "REQRES_BASE_URL",
gradleLocalProperties(rootDir, providers).getProperty("reqres.base.url")
)
}

compileOptions {
Expand Down
3 changes: 3 additions & 0 deletions core/data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ dependencies {
implementation(projects.core.datastore)
implementation(projects.core.database)
implementation(projects.core.common)
implementation(projects.core.network)
implementation(libs.retrofit.kotlin.serialization)
implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.paging)
}
13 changes: 10 additions & 3 deletions core/data/src/main/java/org/sopt/data/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@ import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.sopt.data.repository.AuthRepositoryImpl
import org.sopt.data.repository.FriendRepository
import org.sopt.data.repository.UserDataRepositoryImpl
import org.sopt.data.repository.UserRepositoryImpl
import org.sopt.domain.repo.AuthRepository
import org.sopt.domain.repo.SoptRepository
import org.sopt.domain.repo.UserDataRepository
import javax.inject.Singleton
import org.sopt.domain.repo.UserRepository

@Module
@InstallIn(SingletonComponent::class)
abstract class DataModule {
@Singleton
@Binds
abstract fun bindsFriendRepo(soptRepository: FriendRepository): SoptRepository

@Singleton
@Binds
abstract fun bindsUserRepo(userDataRepository: UserDataRepositoryImpl): UserDataRepository

@Binds
abstract fun bindsMemberRepo(userRepository: UserRepositoryImpl): UserRepository

@Binds
abstract fun authRepo(authRepository: AuthRepositoryImpl): AuthRepository
}
39 changes: 39 additions & 0 deletions core/data/src/main/java/org/sopt/data/paging/UserPagingSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.sopt.data.paging

import androidx.paging.PagingSource
import androidx.paging.PagingState
import org.sopt.model.ReqresUser
import org.sopt.network.api.ReqresApi
import org.sopt.network.model.response.toReqresUser
import retrofit2.HttpException
import java.io.IOException
import javax.inject.Inject

class UserPagingSource @Inject constructor(
private val reqresApi: ReqresApi,
) : PagingSource<Int, ReqresUser>() {
override fun getRefreshKey(state: PagingState<Int, ReqresUser>): Int? {
return state.anchorPosition
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ReqresUser> {
return try {
val currentPage = params.key ?: 1
val users = toReqresUser(
reqresApi.getUsers(
currentPage
).data
)

LoadResult.Page(
data = users,
prevKey = if (currentPage == 1) null else currentPage - 1,
nextKey = if (users.isEmpty()) null else currentPage + 1
)
} catch (exception: IOException) {
return LoadResult.Error(exception)
} catch (exception: HttpException) {
return LoadResult.Error(exception)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.sopt.data.repository

import kotlinx.serialization.json.Json
import org.sopt.domain.repo.AuthRepository
import org.sopt.model.Base
import org.sopt.model.Member
import org.sopt.network.api.AuthApi
import org.sopt.network.model.request.RequestPatchPasswordDto
import org.sopt.network.model.request.RequestPostSigninDto
import org.sopt.network.model.request.RequestPostSignupDto
import org.sopt.network.model.response.base.ApiError
import org.sopt.network.model.response.base.BaseResponse
import org.sopt.network.model.response.base.toCoreModel
import org.sopt.network.model.response.base.toCoreModelNothingType
import org.sopt.network.model.response.toCoreModel
import retrofit2.HttpException
import javax.inject.Inject

class AuthRepositoryImpl @Inject constructor(
private val authApi: AuthApi,
) : AuthRepository {
override suspend fun postSignup(member: Member, pw: String): Result<Base<Nothing>> {
val result = runCatching {
authApi.postSignup(
RequestPostSignupDto(
authenticationId = member.id,
nickname = member.nickname,
password = pw,
phone = member.phone
)
)
}
return handleResult(result)
}

override suspend fun getUserinfo(): Result<Member> = runCatching {
authApi.getUserinfo().data!!.toCoreModel()
}

override suspend fun postSignin(id: String, pw: String): Result<Base<Nothing>> {
val result = runCatching {
authApi.postSignin(
RequestPostSigninDto(
id,
pw
)
)
}
return handleResult(result)
}

override suspend fun patchPassword(
previousPassword: String,
newPassword: String,
newPasswordVerification: String,
): Result<Base<Nothing>> {
val result = runCatching {
authApi.patchPassword(
RequestPatchPasswordDto(
previousPassword = previousPassword,
newPassword = newPassword,
newPasswordVerification = newPasswordVerification
)
)
}
return handleResult(result)
}

private fun handleResult(result: Result<BaseResponse<Unit>>) =
when (val exception = result.exceptionOrNull()) {
null -> result.map {
it.toCoreModelNothingType()
}

is HttpException -> {
val json = exception.response()?.errorBody()?.string()
val api = Json.decodeFromString<ApiError>(json!!)
Result.success(
api.toCoreModel()
)
}

else -> {
Result.failure(exception)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sopt.data.repository

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import kotlinx.coroutines.flow.Flow
import org.sopt.data.paging.UserPagingSource
import org.sopt.domain.repo.UserRepository
import org.sopt.model.ReqresUser
import javax.inject.Inject

class UserRepositoryImpl @Inject constructor(
private val userPagingSource: UserPagingSource,
) : UserRepository {
override fun getUser(): Flow<PagingData<ReqresUser>> {
return Pager(PagingConfig(6, 2)) {
userPagingSource
}.flow
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlinx.serialization.Serializable

@Serializable
data class UserData(
val memberId: Int? = null,
val id: String? = null,
val pw: String? = null,
val name: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class UserPreferencesDataSource @Inject constructor(
suspend fun setUserData(user: UserData) {
try {
userPreferences.updateData {
it.copy(user.id, user.pw, user.name, user.hobby)
it.copy(user.memberId, user.id, user.pw, user.name, user.hobby)
}
} catch (ioException: IOException) {
Log.e("exception", "setUserData ioException")
Expand All @@ -31,10 +31,20 @@ class UserPreferencesDataSource @Inject constructor(
}
}

suspend fun setMemberId(id: Int) {
try {
userPreferences.updateData {
it.copy(memberId = id)
}
} catch (ioException: IOException) {
Log.e("exception", "setMemberId ioException")
}
}

suspend fun deleteUser() {
try {
userPreferences.updateData {
it.copy("","","","",false)
it.copy(null, "", "", "", "", false)
}
} catch (ioException: IOException) {
Log.e("exception", "deleteUser ioException")
Expand Down
1 change: 1 addition & 0 deletions core/domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ dependencies {
implementation(projects.core.model)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.javax.inject)
implementation(libs.androidx.paging.common)
}
18 changes: 18 additions & 0 deletions core/domain/src/main/java/org/sopt/domain/repo/AuthRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.domain.repo

import org.sopt.model.Base
import org.sopt.model.Member

interface AuthRepository {
suspend fun postSignup(member: Member, pw: String): Result<Base<Nothing>>

suspend fun getUserinfo(): Result<Member?>

suspend fun postSignin(id: String, pw: String): Result<Base<Nothing>>

suspend fun patchPassword(
previousPassword: String,
newPassword: String,
newPasswordVerification: String,
): Result<Base<Nothing>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.domain.repo

import androidx.paging.PagingData
import kotlinx.coroutines.flow.Flow
import org.sopt.model.ReqresUser

interface UserRepository {
fun getUser(): Flow<PagingData<ReqresUser>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.domain.usecase

import org.sopt.model.ValidateResult
import org.sopt.model.getResult
import javax.inject.Inject

class ValidatePasswordUseCase @Inject constructor() {
operator fun invoke(password: String): ValidateResult {
if (password.isBlank()) return ValidateResult.EmptyError
return getResult(passwordPattern.matches(password))
}

companion object {
val passwordPattern = Regex(
"""^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*()-_=+{};:,<>/~`|'"\[\]\\?\.]).{8,}$"""
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.domain.usecase

import org.sopt.model.ValidateResult
import org.sopt.model.getResult
import javax.inject.Inject

class ValidatePhoneNumberUseCase @Inject constructor() {
operator fun invoke(phone: String): ValidateResult {
if (phone.isBlank()) return ValidateResult.EmptyError
return getResult(phoneNumberPattern.matches(phone))
}

companion object {
val phoneNumberPattern = Regex(
"""^01[0-9]-[0-9]{3,4}-[0-9]{4}$"""
)
}
}
8 changes: 8 additions & 0 deletions core/model/src/main/java/org/sopt/model/Base.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.model

data class Base<T>(
val code: Int,
val data: T? = null,
val message: String,
)

7 changes: 7 additions & 0 deletions core/model/src/main/java/org/sopt/model/Member.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.model

data class Member(
val id: String,
val nickname: String,
val phone: String,
)
9 changes: 9 additions & 0 deletions core/model/src/main/java/org/sopt/model/ReqresUser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.model

data class ReqresUser(
val id: Int? = null,
val email: String? = null,
val firstName: String? = null,
val lastName: String? = null,
val avatar: String? = null,
)
Loading

0 comments on commit 2cf484b

Please sign in to comment.