Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat/#9] 4주차 필수 과제 구현 #11

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
Open
21 changes: 21 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.util.Properties

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
Expand All @@ -7,6 +9,10 @@ plugins {
alias(libs.plugins.kotlin.serialization)
}

val properties = Properties().apply {
load(rootProject.file("local.properties").inputStream())
}

android {
namespace = "org.sopt.and"
compileSdk = 34
Expand All @@ -19,6 +25,12 @@ android {
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField(
"String",
"BASE_URL",
properties.getProperty("base.url")
)
}

buildTypes {
Expand All @@ -39,6 +51,7 @@ android {
}
buildFeatures {
compose = true
buildConfig = true
}
}

Expand Down Expand Up @@ -83,4 +96,12 @@ dependencies {

//coil
implementation(libs.coil)

//retrofit
implementation(libs.okhttp)
implementation(libs.okhttp.logging)
implementation(platform(libs.okhttp.bom))
implementation(libs.retrofit)
implementation(libs.retrofit)
implementation(libs.retrofit.kotlinx.serialization.converter)
}
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ANDANDROID"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".presentation.main.MainActivity"
Expand Down
36 changes: 0 additions & 36 deletions app/src/main/java/org/sopt/and/core/data/di/RepositoryModule.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.sopt.and.R
import org.sopt.and.core.data.repositoryimpl.DummyPopularProgramRepositoryImpl
import org.sopt.and.core.designsystem.component.BasicPreview
import org.sopt.and.core.designsystem.theme.Grey500
import org.sopt.and.core.extension.noRippleClickable
import org.sopt.and.core.model.Program
import org.sopt.and.data.repositoryimpl.DummyPopularProgramRepositoryImpl
import org.sopt.and.presentation.search.component.SearchItem

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.VisualTransformation
Expand All @@ -26,8 +27,8 @@ import androidx.compose.ui.unit.dp
fun WavveBasicTextField(
value: String,
hint: String,
cursorBrush: Brush,
modifier: Modifier = Modifier,
cursorBrush: Brush = SolidColor(Color.Blue),
hintColor: Color = Color.LightGray,
valueColor: Color = Color.White,
onValueChange: (String) -> Unit = {},
Expand Down
19 changes: 7 additions & 12 deletions app/src/main/java/org/sopt/and/core/preference/PreferenceUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,20 @@ class PreferenceUtil(
PREF_NAME, Context.MODE_PRIVATE
)

var id: String
get() = preference.getString(ID, DEFAULT_STRING).toString()
set(value) = preference.edit().putString(ID, value).apply()
var token: String
get() = preference.getString(TOKEN, DEFAULT_STRING).toString()
set(value) = preference.edit().putString(TOKEN, value).apply()

var password: String
get() = preference.getString(PASSWORD, DEFAULT_STRING).toString()
set(value) = preference.edit().putString(PASSWORD, value).apply()

fun clearIdPassword() {
id = ""
password = ""
fun clearToken() {
token = ""
}
Comment on lines +18 to 20
Copy link
Contributor

Choose a reason for hiding this comment

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

sharedPreferences를 clear 시켜주는 것 대신 토큰만 clear 해준 이유가 있는지 궁금해요!
또, sharedPreference에서 remove 함수를 사용해 줄 수도 있습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

그냥 필요한 부분만 지우는게 좋지 않을까 싶어서 저렇게 했습니다!
remove에 대해선 자세히 알아보고 적용할게요~


companion object {
private const val PREF_NAME = "wavve_prefs"
private const val ID = "ID"
private const val PASSWORD = "PASSWORD"
private const val TOKEN = "TOKEN"
private const val DEFAULT_STRING = ""


Comment on lines 26 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

2줄 공백이다 ㅋㅋ

Copy link
Contributor Author

Choose a reason for hiding this comment

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

들켰다ㅎ

val LocalPreference = staticCompositionLocalOf<PreferenceUtil> {
error("PreferenceUtil is not initialized")
}
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/org/sopt/and/data/datasource/AuthDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.and.data.datasource

import org.sopt.and.data.dto.BaseResponse
import org.sopt.and.data.dto.request.SignInRequestDto
import org.sopt.and.data.dto.request.SignUpRequestDto
import org.sopt.and.data.dto.response.SignInResponseDto
import org.sopt.and.data.dto.response.SignUpResponseDto
import retrofit2.Call

interface AuthDataSource {
fun postSignUp(
request: SignUpRequestDto
): Call<BaseResponse<SignUpResponseDto>>
Comment on lines +11 to +13

Choose a reason for hiding this comment

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

To reviewer에 원래는 call을 안쓰셨다고 했던 것 같은데 원래 하셨던 방법이 뭐였나요?!
그리고 이번에는 특별히 call을 쓰신 이유가 있을까요? (suspend 적용 바로 안하시고...!!)
datasource 부분까지 call을 사용하신 이유가 있을까요?!

Choose a reason for hiding this comment

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

저도 궁금합니다~!!

Copy link
Contributor

Choose a reason for hiding this comment

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

suspend 다음주에 알려줄 거야 ㅜㅜ 앞서나가지마잉 ㅋㅋ

Copy link
Contributor Author

Choose a reason for hiding this comment

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

앞서나기 싫어서 Call 사용했습니다ㅎㅎ (근데 진짜에요)


fun postSignIn(
request: SignInRequestDto
): Call<BaseResponse<SignInResponseDto>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.and.data.datasource

import org.sopt.and.data.dto.BaseResponse
import org.sopt.and.data.dto.response.MyHobbyResponseDto
import retrofit2.Call

interface UserDataSource {
fun getMyHobby(token: String): Call<BaseResponse<MyHobbyResponseDto>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.and.data.datasourceImpl

import org.sopt.and.data.datasource.AuthDataSource
import org.sopt.and.data.dto.BaseResponse
import org.sopt.and.data.dto.request.SignInRequestDto
import org.sopt.and.data.dto.request.SignUpRequestDto
import org.sopt.and.data.dto.response.SignInResponseDto
import org.sopt.and.data.dto.response.SignUpResponseDto
import org.sopt.and.data.remote.AuthService
import retrofit2.Call
import javax.inject.Inject

class AuthDataSourceImpl @Inject constructor(
private val userService: AuthService
): AuthDataSource {
override fun postSignUp(request: SignUpRequestDto): Call<BaseResponse<SignUpResponseDto>> = userService.signUp(request)

Choose a reason for hiding this comment

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

요기도 뭔가 줄 분리하면 좋을 것 같아요!

override fun postSignIn(request: SignInRequestDto): Call<BaseResponse<SignInResponseDto>> = userService.signIn(request)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.sopt.and.data.datasourceImpl

import org.sopt.and.data.datasource.UserDataSource
import org.sopt.and.data.dto.BaseResponse
import org.sopt.and.data.dto.response.MyHobbyResponseDto
import org.sopt.and.data.remote.UserService
import retrofit2.Call
import javax.inject.Inject

class UserDataSourceImpl @Inject constructor(
private val userService: UserService
) : UserDataSource {
override fun getMyHobby(token: String): Call<BaseResponse<MyHobbyResponseDto>> =
userService.getMyHobby(token)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.sopt.and.core.data.di
package org.sopt.and.data.di

import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import org.sopt.and.core.data.local.database.StarredProgramDatabase
import org.sopt.and.data.local.database.StarredProgramDatabase
import javax.inject.Singleton

@InstallIn(SingletonComponent::class)
Expand Down
29 changes: 29 additions & 0 deletions app/src/main/java/org/sopt/and/data/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.sopt.and.data.di

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.sopt.and.data.datasource.AuthDataSource
import org.sopt.and.data.datasource.UserDataSource
import org.sopt.and.data.datasourceImpl.AuthDataSourceImpl
import org.sopt.and.data.datasourceImpl.UserDataSourceImpl
import javax.inject.Singleton

@InstallIn(SingletonComponent::class)
@Module
abstract class DataSourceModule {

@Binds
@Singleton
abstract fun bindsAuthDataSource(
authDataSourceImpl: AuthDataSourceImpl
): AuthDataSource

@Binds
@Singleton
abstract fun bindsUserDataSource(
userDataSourceImpl: UserDataSourceImpl
): UserDataSource

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

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.sopt.and.data.repositoryimpl.DummyPopularProgramRepositoryImpl
import org.sopt.and.data.repositoryimpl.DummyRecommendationRepositoryImpl
import org.sopt.and.data.repositoryimpl.MyHobbyRepositoryImpl
import org.sopt.and.data.repositoryimpl.SignInRepositoryImpl
import org.sopt.and.data.repositoryimpl.SignUpRepositoryImpl
import org.sopt.and.data.repositoryimpl.StarredProgramRepositoryImpl
import org.sopt.and.domain.repository.MyHobbyRepository
import org.sopt.and.domain.repository.PopularProgramRepository
import org.sopt.and.domain.repository.RecommendationRepository
import org.sopt.and.domain.repository.SignInRepository
import org.sopt.and.domain.repository.SignUpRepository
import org.sopt.and.domain.repository.StarredProgramRepository
import javax.inject.Singleton

@InstallIn(SingletonComponent::class)
@Module
abstract class RepositoryModule() {

@Binds
@Singleton
abstract fun bindsDummyRecommendationRepository(
recommendationRepositoryImpl: DummyRecommendationRepositoryImpl
): RecommendationRepository

@Binds
@Singleton
abstract fun bindsDummyPopularProgramRepository(
popularProgramRepositoryImpl: DummyPopularProgramRepositoryImpl
): PopularProgramRepository

@Binds
@Singleton
abstract fun bindsStarredProgramRepository(
starredProgramRepositoryImpl: StarredProgramRepositoryImpl
): StarredProgramRepository

@Binds
@Singleton
abstract fun bindsSignUpRepository(
signUpRepositoryImpl: SignUpRepositoryImpl
): SignUpRepository


@Binds
@Singleton
abstract fun bindsSignInRepository(
signInRepositoryImpl: SignInRepositoryImpl
): SignInRepository

@Binds
@Singleton
abstract fun bindsMyHobbyRepository(
myHobbyRepositoryImpl: MyHobbyRepositoryImpl
): MyHobbyRepository

}
49 changes: 49 additions & 0 deletions app/src/main/java/org/sopt/and/data/di/RetrofitModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.sopt.and.data.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.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.sopt.and.BuildConfig.BASE_URL
import retrofit2.Converter
import retrofit2.Retrofit
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object RetrofitModule {

@Provides
Copy link
Contributor

Choose a reason for hiding this comment

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

@provides@BINDS의 차이는 뭘까용?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Provides는 클래스의 객체를 직접 생성해야 할 때 사용합니다. 주로 외부 라이브러리 클래스의 객체를 생성하고 의존성 그래프에 제공하기 위해 사용하죠!

@Binds는 구현체를 인터페이스에 바인딩하기 위해 사용한다고 합니다.
즉, 인터페이스와 그 구현체를 연결하고 인스턴스를 생성하여 그 인스턴스를 인터페이스로 사용할 수 있도록 해주는 것이죠!

@Singleton
fun providesLoggingInterceptor() = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}

@Provides
@Singleton
fun providesOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor
): OkHttpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()

@Provides
@Singleton
fun providesConverterFactory(): Converter.Factory = Json.asConverterFactory("application/json".toMediaType())

@Provides
@Singleton
fun providesRetrofit(
client: OkHttpClient,
converterFactory: Converter.Factory
): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(converterFactory)
.build()
}
Loading