Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.hilt.android)
id("kotlin-kapt")
}

val properties = Properties().apply {
Expand Down Expand Up @@ -46,9 +48,18 @@ android {
compose = true
buildConfig = true
}

hilt {
enableAggregatingTask = false
}
Comment on lines +52 to +54
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 관련해서 합세 리뷰에 적어두었으니 확인해주시면 좋을 것 같네요 ~

}

dependencies {
// Hilt
implementation(libs.hilt.android)
implementation(libs.hilt.navigation.compose)
implementation(libs.androidx.appcompat)
kapt(libs.hilt.compiler)
// Network
implementation(platform(libs.okhttp.bom))
implementation(libs.okhttp)
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".WavveApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -16,7 +17,7 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".feature.main.MainActivity"
android:name=".presentation.main.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.ANDANDROID">
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/java/org/sopt/and/WavveApp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.sopt.and

import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class WavveApp: Application() {
override fun onCreate() {
super.onCreate()
setDarkMode()
}

private fun setDarkMode() {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
}
36 changes: 0 additions & 36 deletions app/src/main/java/org/sopt/and/data/ApiFactory.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.data.remote.model
package org.sopt.and.data.local

data class TodayTopData(
val painterId: Int,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.and.data.mapper.todata

import org.sopt.and.data.remote.model.request.UserLoginRequestDto
import org.sopt.and.domain.model.request.UserLoginModel

fun UserLoginModel.toData() : UserLoginRequestDto = UserLoginRequestDto(
username = this.username,
password = this.password
)
Comment on lines +6 to +9
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapper 함수 네이밍이 조금 더 자세하면 좋을 것 같아요 ~ 저는 주로 toRequestLoginDto 같은 형태를 사용한답니다
그치만 정답은 없어요 !

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.and.data.mapper.todata

import org.sopt.and.data.remote.model.request.UserSignUpRequestDto
import org.sopt.and.domain.model.request.UserSignUpModel

fun UserSignUpModel.toData() : UserSignUpRequestDto = UserSignUpRequestDto(
username = this.username,
password = this.password,
hobby = this.hobby
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.and.data.mapper.todomain

import org.sopt.and.data.remote.model.response.UserHobbyResponseDto
import org.sopt.and.domain.model.response.Hobby

fun UserHobbyResponseDto.toDomain(): Hobby = Hobby(
hobby = this.hobby
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.and.data.mapper.todomain

import org.sopt.and.data.remote.model.response.UserSignUpResponseDto
import org.sopt.and.domain.model.response.UserNumber

fun UserSignUpResponseDto.toDomain(): UserNumber = UserNumber(
userId = this.userId
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.and.data.mapper.todomain

import org.sopt.and.data.remote.model.response.UserTokenResponseDto
import org.sopt.and.domain.model.response.Token

fun UserTokenResponseDto.toDomain(): Token = Token(
token = this.token
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 Mapper를 사용하지 않아서 데이터 변환에 많은 고생을 했는데 Mapper를 꼭 써야겠다는 생각이 드네요

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.and.data.remote.datasource

import org.sopt.and.data.remote.model.base.ApiResponse
import org.sopt.and.data.remote.model.request.UserLoginRequestDto
import org.sopt.and.data.remote.model.request.UserSignUpRequestDto
import org.sopt.and.data.remote.model.response.UserHobbyResponseDto
import org.sopt.and.data.remote.model.response.UserSignUpResponseDto
import org.sopt.and.data.remote.model.response.UserTokenResponseDto

interface UserDataRemoteSource {
suspend fun postUserSignUp(userSignUpRequestDto: UserSignUpRequestDto): ApiResponse<UserSignUpResponseDto>
suspend fun postUserLogin(userLoginRequestDto: UserLoginRequestDto): ApiResponse<UserTokenResponseDto>
suspend fun getUserHobby(token: String): ApiResponse<UserHobbyResponseDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.sopt.and.data.remote.datasourceimpl

import org.sopt.and.data.remote.datasource.UserDataRemoteSource
import org.sopt.and.data.remote.model.base.ApiResponse
import org.sopt.and.data.remote.model.request.UserLoginRequestDto
import org.sopt.and.data.remote.model.request.UserSignUpRequestDto
import org.sopt.and.data.remote.model.response.UserHobbyResponseDto
import org.sopt.and.data.remote.model.response.UserSignUpResponseDto
import org.sopt.and.data.remote.model.response.UserTokenResponseDto
import org.sopt.and.data.remote.service.UserService
import javax.inject.Inject

class UserDataRemoteSourceImpl @Inject constructor(
private val userService: UserService
) : UserDataRemoteSource {

override suspend fun postUserSignUp(userSignUpRequestDto: UserSignUpRequestDto): ApiResponse<UserSignUpResponseDto> =
userService.postUserSignUp(body = userSignUpRequestDto)

override suspend fun postUserLogin(userLoginRequestDto: UserLoginRequestDto): ApiResponse<UserTokenResponseDto> =
userService.postUserLogin(body = userLoginRequestDto)


override suspend fun getUserHobby(token: String): ApiResponse<UserHobbyResponseDto> =
userService.getUserHobby(token = token)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ import kotlinx.serialization.Serializable
@Serializable
data class UserSignUpResponseDto(
@SerialName("no")
val no: Int
val userId: Int
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.data.network.service
package org.sopt.and.data.remote.service

import org.sopt.and.data.remote.model.base.ApiResponse
import org.sopt.and.data.remote.model.request.UserLoginRequestDto
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.sopt.and.data.remote.utils

import org.sopt.and.data.remote.model.base.ApiResponse

fun <T> ApiResponse<T>.handleApiResponse(): Result<T> {
return try {
Result.success(this.result)
} catch (e: Exception) {
Result.failure(e)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.sopt.and.data.repositoryimpl

import org.sopt.and.data.mapper.todata.toData
import org.sopt.and.data.mapper.todomain.toDomain
import org.sopt.and.data.remote.datasource.UserDataRemoteSource
import org.sopt.and.data.remote.utils.handleApiResponse
import org.sopt.and.domain.model.request.UserLoginModel
import org.sopt.and.domain.model.request.UserSignUpModel
import org.sopt.and.domain.model.response.Hobby
import org.sopt.and.domain.model.response.Token
import org.sopt.and.domain.model.response.UserNumber
import org.sopt.and.domain.repository.UserRepository
import javax.inject.Inject

class UserRepositoryImpl @Inject constructor(
private val userDataRemoteSource: UserDataRemoteSource
) : UserRepository {

override suspend fun postUserSignUp(userSignUpModel: UserSignUpModel): Result<UserNumber> {
return runCatching {
userDataRemoteSource.postUserSignUp(userSignUpModel.toData()).handleApiResponse().getOrThrow().toDomain()
}
}

override suspend fun postUserLogin(userLoginModel: UserLoginModel): Result<Token> {
return runCatching {
userDataRemoteSource.postUserLogin(userLoginModel.toData()).handleApiResponse().getOrThrow().toDomain()
}
}

override suspend fun getUserHobby(token: String): Result<Hobby> {
return runCatching {
userDataRemoteSource.getUserHobby(token = token).handleApiResponse().getOrThrow().toDomain()
}
}
}
19 changes: 19 additions & 0 deletions app/src/main/java/org/sopt/and/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.and.di

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.sopt.and.data.remote.datasource.UserDataRemoteSource
import org.sopt.and.data.remote.datasourceimpl.UserDataRemoteSourceImpl
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
abstract class DataSourceModule {
@Binds
@Singleton
abstract fun bindUserDataRemoteSource(
userDataRemoteSourceImpl: UserDataRemoteSourceImpl
): UserDataRemoteSource
}
Comment on lines +11 to +19
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저와는 다르게 data 폴더와 di 폴더를 아예 구분하셨군요 ! 굿굿 좋아요 ~

72 changes: 72 additions & 0 deletions app/src/main/java/org/sopt/and/di/NetworkModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.sopt.and.di

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.serialization.json.Json
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.sopt.and.BuildConfig
import retrofit2.Retrofit
import java.util.concurrent.TimeUnit
import javax.inject.Singleton


@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun providesOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor,
authInterceptor: Interceptor
): OkHttpClient =
OkHttpClient.Builder().apply {
connectTimeout(10, TimeUnit.SECONDS)
writeTimeout(10, TimeUnit.SECONDS)
readTimeout(10, TimeUnit.SECONDS)
addInterceptor(authInterceptor)
}.build()

@Provides
@Singleton
fun providesJson(): Json =
Json {
isLenient = true
prettyPrint = true
explicitNulls = false
ignoreUnknownKeys = true
}

@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}

@Provides
@Singleton
fun provideAuthInterceptor(): Interceptor = Interceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer <Your_Token_Here>")
.build()
chain.proceed(request)
}

@Provides
@Singleton
fun provideWavveRetrofit(
okHttpClient: OkHttpClient,
json: Json
): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
}
}
20 changes: 20 additions & 0 deletions app/src/main/java/org/sopt/and/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sopt.and.di

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.sopt.and.data.repositoryimpl.UserRepositoryImpl
import org.sopt.and.domain.repository.UserRepository
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
@Singleton
abstract fun bindUserRepository(
userRepositoryImpl: UserRepositoryImpl
): UserRepository

}
Loading