-
Notifications
You must be signed in to change notification settings - Fork 0
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
Week6 essential #7
base: develop/view
Are you sure you want to change the base?
Changes from all commits
72a2211
7e8c872
c8564d4
08d95de
492b431
c091778
9726d40
492ad8d
e375027
852345b
a5a0013
46caf62
2deac32
49e32d2
4cb433e
1c49452
d028069
21ec506
a6b625a
cf6778d
13cc35e
af10a27
d76ff72
aa4f280
3f7a157
74e078b
0e6f55c
e07dbc7
a59effc
da35a8a
d8c2333
62d3792
3c5cddf
e592c82
2f06c36
f1892f4
99b5678
cab3425
1ce3e66
b7a5b87
aadb1b3
cf77ae0
db3bbbd
e96d769
9914e5d
2507ac6
105ac43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,7 @@ | ||||||
plugins { | ||||||
id 'com.android.application' | ||||||
id 'org.jetbrains.kotlin.android' | ||||||
id 'org.jetbrains.kotlin.plugin.serialization' version('1.7.10') | ||||||
} | ||||||
|
||||||
android { | ||||||
|
@@ -49,4 +50,20 @@ dependencies { | |||||
// ViewModel 생성함수를 편하게 사용하고 싶다면? | ||||||
implementation "androidx.fragment:fragment-ktx:1.5.3" | ||||||
implementation "androidx.activity:activity-ktx:1.5.1" | ||||||
|
||||||
//레트로핏 | ||||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0' | ||||||
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1' | ||||||
implementation 'com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0' | ||||||
|
||||||
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0")) | ||||||
implementation("com.squareup.okhttp3:okhttp") | ||||||
implementation("com.squareup.okhttp3:logging-interceptor") | ||||||
|
||||||
//글라이드 | ||||||
implementation 'com.github.bumptech.glide:glide:4.14.2' | ||||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
//로티 뷰 | ||||||
implementation "com.airbnb.android:lottie:5.2.0" | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,9 +16,9 @@ class MySharedPreferences(context: Context) { | |
get() = loginPreferences.getBoolean("AUTO_LOGIN", false) | ||
set(value) = editor.putBoolean("AUTO_LOGIN", value).apply() | ||
|
||
var loginId: String? | ||
get() = loginPreferences.getString("LOGIN_ID", null) | ||
set(value) = editor.putString("LOGIN_ID", value).apply() | ||
var loginEmail: String? | ||
get() = loginPreferences.getString("LOGIN_EMAIL", null) | ||
set(value) = editor.putString("LOGIN_EMAIL", value).apply() | ||
Comment on lines
+19
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터타입이 nullable한 이유가 있을까유?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 처리해도 될 것 같은게 어차피 빈 스트링이나 null이나 저장이 안된값으로 인식하면 되어서 처리 로직은 거의 비슷할 듯. 다만 '?.' 연산자를 항상 써야되냐 말아야되나 차이인데 그정도는 취향차이라고 봐도 될 것 같아용 |
||
|
||
var loginPw: String? | ||
get() = loginPreferences.getString("LOGIN_PW", null) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.sopt.sample.data.remote | ||
|
||
import okhttp3.Interceptor | ||
import okhttp3.Response | ||
|
||
class AuthInterceptor : Interceptor { | ||
override fun intercept(chain: Interceptor.Chain): Response { | ||
val originRequest = chain.request() | ||
val headerRequest = originRequest.newBuilder() | ||
.header("token", "") | ||
.build() | ||
return chain.proceed(headerRequest) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.sopt.sample.data.remote | ||
|
||
import org.sopt.sample.data.remote.entity.auth.RequestSignInDTO | ||
import org.sopt.sample.data.remote.entity.auth.RequestSignUpDTO | ||
import org.sopt.sample.data.remote.entity.auth.ResponseSignInDTO | ||
import org.sopt.sample.data.remote.entity.auth.ResponseSignUpDTO | ||
import retrofit2.Call | ||
import retrofit2.http.Body | ||
import retrofit2.http.POST | ||
|
||
interface AuthService { | ||
@POST("api/user/signin") | ||
fun postSignIn( | ||
@Body body: RequestSignInDTO | ||
): Call<ResponseSignInDTO> | ||
|
||
@POST("api/user/signup") | ||
fun postSignUp( | ||
@Body body: RequestSignUpDTO | ||
) : Call<ResponseSignUpDTO> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.sopt.sample.data.remote | ||
|
||
import org.sopt.sample.data.remote.entity.reqres.ResponseReqresDTO | ||
import retrofit2.http.GET | ||
import retrofit2.http.Query | ||
import retrofit2.Call | ||
|
||
interface ReqresService { | ||
@GET("users") | ||
fun getUsers( | ||
@Query("page") page : Int | ||
) : Call<ResponseReqresDTO> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.sopt.sample.data.remote | ||
|
||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory | ||
import kotlinx.serialization.json.Json | ||
import okhttp3.MediaType.Companion.toMediaType | ||
import retrofit2.Retrofit | ||
|
||
object ServiceFactory { | ||
private const val AUTH_BASE_URL = "http://3.39.169.52:3000/" | ||
private const val REQRES_BASE_URL = "https://reqres.in/api/" | ||
|
||
val retrofitAuth: Retrofit by lazy { | ||
Retrofit.Builder() | ||
.baseUrl(AUTH_BASE_URL) | ||
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) | ||
.build() | ||
} | ||
|
||
val retrofitReqres: Retrofit by lazy { | ||
Retrofit.Builder() | ||
.baseUrl(REQRES_BASE_URL) | ||
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) | ||
.build() | ||
} | ||
|
||
//inline fun <reified T> create(): T = retrofitAuth.create<T>(T::class.java) | ||
} | ||
|
||
object ServicePool { | ||
val authService: AuthService = ServiceFactory.retrofitAuth.create(AuthService::class.java) | ||
val reqresService : ReqresService = ServiceFactory.retrofitReqres.create(ReqresService::class.java) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.sopt.sample.data.remote.entity.auth | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class RequestSignInDTO( | ||
@SerialName("email") | ||
val email: String, | ||
@SerialName("password") | ||
val password: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.sopt.sample.data.remote.entity.auth | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class RequestSignUpDTO( | ||
val email: String, | ||
val password: String, | ||
val name: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.sopt.sample.data.remote.entity.auth | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ResponseSignInDTO( | ||
@SerialName("status") | ||
val status: Int, | ||
@SerialName("message") | ||
val message: String, | ||
@SerialName("result") | ||
val result: User | ||
) { | ||
@Serializable | ||
data class User( | ||
@SerialName("id") | ||
val id: Int, | ||
@SerialName("name") | ||
val name: String, | ||
@SerialName("profileImage") | ||
val profileImage: String?, | ||
@SerialName("bio") | ||
val bio: String?, | ||
@SerialName("email") | ||
val email: String, | ||
@SerialName("password") | ||
val password: String | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.sopt.sample.data.remote.entity.auth | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ResponseSignUpDTO( | ||
val message: String, | ||
val newUser: NewUser, | ||
val status: Int | ||
) { | ||
@Serializable | ||
data class NewUser( | ||
val bio: String?, | ||
val email: String, | ||
val id: Int, | ||
val name: String, | ||
val password: String, | ||
val profileImage: String? | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.sopt.sample.data.remote.entity.reqres | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ResponseReqresDTO( | ||
val data: List<Data>, | ||
val page: Int, | ||
@SerialName("per_page") | ||
val perPage: Int, | ||
val support: Support, | ||
val total: Int, | ||
@SerialName("total_pages") | ||
val totalPages: Int | ||
) { | ||
@Serializable | ||
data class Data( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이것도 플러그인이 만들어주신 이름 같다만 Data라는 이름은 최대한 피해주는게 좋을 것 같아. 가독성/직관성이 떨어져보여 |
||
val avatar: String, | ||
val email: String, | ||
@SerialName("first_name") | ||
val firstName: String, | ||
val id: Int, | ||
@SerialName("last_name") | ||
val lastName: String | ||
) | ||
|
||
@Serializable | ||
data class Support( | ||
val text: String, | ||
val url: String | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,7 @@ class SplashActivity : AppCompatActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
binding = ActivitySplashBinding.inflate(layoutInflater) | ||
sharedPref = MySharedPreferences() | ||
sharedPref.init(this) | ||
sharedPref = MySharedPreferences(this) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Application 클래스 만들어서 거기서 한번만 init하고 사용하는걸 추천할게용 |
||
setName() | ||
setContentView(binding.root) | ||
|
||
|
@@ -34,7 +33,7 @@ class SplashActivity : AppCompatActivity() { | |
} | ||
|
||
private fun checkAutoLogin() { | ||
val id = sharedPref.loginId | ||
val id = sharedPref.loginEmail | ||
val autoLogin = sharedPref.autoLogin | ||
if (id == null) startLogin() | ||
else if (autoLogin) startHome() | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -1,52 +1,81 @@ | ||||||||
package org.sopt.sample.ui.auth | ||||||||
|
||||||||
import android.content.Context | ||||||||
import org.sopt.sample.R | ||||||||
import org.sopt.sample.shortToast | ||||||||
|
||||||||
class AuthChecking { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스로 따로 빼서 관리해주는 거 좋네요 |
||||||||
fun isSignUpIdValid(id: String): Boolean = (id.length in 6..10) | ||||||||
|
||||||||
fun isSignUpPwValid(pw: String): Boolean = (pw.length in 8..12) | ||||||||
|
||||||||
fun isSignUpNameValid(name : String) : Boolean = (name.length in 1..3) | ||||||||
|
||||||||
fun isSignUpMbtiValid(mbti: String): Int { | ||||||||
if (mbti.length < 4) return SHORT | ||||||||
else if (mbti in mbtiList) return CORRECT | ||||||||
else return STRANGE | ||||||||
} | ||||||||
|
||||||||
fun isSignInValid( | ||||||||
context: Context, id: String?, pw: String?, inputId: String, inputPw: String | ||||||||
): Boolean { | ||||||||
if (id == null) { | ||||||||
context.shortToast(R.string.needSignUp) | ||||||||
return false | ||||||||
} else if ((inputId != id) and (inputPw != pw)) { | ||||||||
context.shortToast(R.string.checkIdPw) | ||||||||
return false | ||||||||
} else if (inputId != id) { | ||||||||
context.shortToast(R.string.checkId) | ||||||||
return false | ||||||||
} else if (inputPw != pw) { | ||||||||
context.shortToast(R.string.checkPw) | ||||||||
return false | ||||||||
} else { | ||||||||
context.shortToast(R.string.succeedSignIn) | ||||||||
|
||||||||
fun validateId(id: String): EditTextUiState { | ||||||||
if (haveNumber(id) and haveAlphabet(id) and checkLength(id, ID_RANGE)) { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 미친 가독성 좋은데? |
||||||||
return EditTextUiState.CORRECT | ||||||||
} | ||||||||
if (id.isEmpty()) { | ||||||||
return EditTextUiState.NOT_FOCUSED | ||||||||
} | ||||||||
return EditTextUiState.INCORRECT | ||||||||
} | ||||||||
|
||||||||
fun validatePw(pw: String): EditTextUiState { | ||||||||
if (haveNumber(pw) and haveAlphabet(pw) and haveSpecialCharacter(pw) and checkLength(pw, PW_RANGE) | ||||||||
) { | ||||||||
return EditTextUiState.CORRECT | ||||||||
} | ||||||||
if (pw.isEmpty()) { | ||||||||
return EditTextUiState.NOT_FOCUSED | ||||||||
} | ||||||||
return EditTextUiState.INCORRECT | ||||||||
} | ||||||||
|
||||||||
private fun haveSpecialCharacter(input: String): Boolean { | ||||||||
return !input.all { Character.isLetterOrDigit(it) } | ||||||||
} | ||||||||
|
||||||||
private fun haveNumber(input: String): Boolean { | ||||||||
return input.any { Character.isDigit(it) } | ||||||||
} | ||||||||
|
||||||||
private fun haveAlphabet(input: String): Boolean { | ||||||||
if (input.any { it.toString() in "a".."z" }) { | ||||||||
return true | ||||||||
} | ||||||||
if (input.any { it.toString() in "A".."Z" }) { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
조금더 직관성있게...!! |
||||||||
return true | ||||||||
} | ||||||||
return false | ||||||||
} | ||||||||
|
||||||||
private fun checkLength(input: String, range: IntRange): Boolean { | ||||||||
if (input.length in range) { | ||||||||
return true | ||||||||
} | ||||||||
return false | ||||||||
} | ||||||||
|
||||||||
fun validateMbti(input: String): EditTextUiState { | ||||||||
if (input in mbtiList) { | ||||||||
return EditTextUiState.CORRECT | ||||||||
} | ||||||||
if (input.isEmpty()) { | ||||||||
return EditTextUiState.NOT_FOCUSED | ||||||||
} | ||||||||
return EditTextUiState.INCORRECT | ||||||||
} | ||||||||
|
||||||||
fun validateName(input: String): EditTextUiState { | ||||||||
if (input.length in 2..4) { | ||||||||
return EditTextUiState.CORRECT | ||||||||
} | ||||||||
if (input.isEmpty()) { | ||||||||
return EditTextUiState.NOT_FOCUSED | ||||||||
} | ||||||||
return EditTextUiState.INCORRECT | ||||||||
} | ||||||||
|
||||||||
private val mbtiList: List<String> = listOf( | ||||||||
private val mbtiList: Set<String> = setOf( | ||||||||
"ESTJ", "ESTP", "ESFJ", "ESFP", "ENTJ", "ENTP", "ENFJ", "ENFP", | ||||||||
"ISTJ", "ISTP", "ISFJ", "ISFP", "INTJ", "INTP", "INFJ", "INFP", | ||||||||
"CUTE", "SEXY" | ||||||||
) | ||||||||
|
||||||||
companion object { | ||||||||
const val SHORT = 0 | ||||||||
const val STRANGE = 1 | ||||||||
const val CORRECT = 2 | ||||||||
val ID_RANGE = IntRange(6, 10) | ||||||||
val PW_RANGE = IntRange(6, 12) | ||||||||
Comment on lines
+78
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 |
||||||||
} | ||||||||
} | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아래에 kapt 기능 사용해야되니까 이거 추가해야됨