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
17 changes: 14 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.20'
}

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
android {
namespace 'org.sopt.dosopttemplate'
compileSdk 33
Expand All @@ -14,12 +16,14 @@ android {
targetSdk 33
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String", "REQRES_BASE_URL", properties["reqres.base.url"]
buildConfigField "String", "AUTH_BASE_URL", properties["base.url"]
}
buildFeatures {
viewBinding true
dataBinding true
buildConfig true
}
buildTypes {
release {
Expand All @@ -34,7 +38,6 @@ android {
kotlinOptions {
jvmTarget = '11'
}

}

dependencies {
Expand All @@ -49,4 +52,12 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.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:1.0.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.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
}
15 changes: 11 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand All @@ -11,17 +11,24 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DoSoptTemplate"
tools:targetApi="31">
tools:targetApi="31"
android:usesCleartextTraffic="true">
<activity
android:name=".presentation.login.LoginActivity"
android:exported="false">
android:exported="true">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".presentation.signup.SingUpActivity"
android:exported="false"></activity>
android:exported="false">
</activity>
<activity
android:name=".presentation.home.HomeActivity"
android:exported="false">
android:exported="true">
android:exported="true"
android:windowSoftInputMode="adjustResize"
Expand Down
49 changes: 49 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/APIFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.sopt.dosopttemplate.api

import android.util.Log
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.sopt.dosopttemplate.BuildConfig
import retrofit2.Retrofit

object ApiFactory {
lateinit var url: String
private fun getLogOkHttpClient(): Interceptor {
val loggingInterceptor = HttpLoggingInterceptor { message ->
Log.d("Retrofit2", "CONNECTION INFO -> $message")
}
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}

val okHttpClient = OkHttpClient.Builder()
.addInterceptor(getLogOkHttpClient())
.build()

val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(url)
.client(okHttpClient)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
}

inline fun <reified T> create(url: String): T {
this.url = url
return retrofit.create<T>(T::class.java)
}
}

object ServicePool {
private const val BASE_URL = BuildConfig.AUTH_BASE_URL
private const val REQRES_BASE_URL = BuildConfig.REQRES_BASE_URL

val authService = ApiFactory.create<AuthService>(BASE_URL)
val followerService = ApiFactory.create<FollowerService>(REQRES_BASE_URL)
}


19 changes: 19 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/AuthService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.dosopttemplate.api

import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

interface AuthService {
@POST("api/v1/members/sign-in")
fun login(
@Body request: RequestLoginDto,
): Call<ResponseLoginDto>

@POST("api/v1/members")
fun signUp(
@Body request: RequestSignUpDto,
): Call<Unit>
}


46 changes: 46 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/AuthViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.sopt.dosopttemplate.api// λ³΄μ‹œλ©΄ μ•Œκ² μ§€λ§Œ LiveDataλŠ” lifecycle λΌμ΄λΈŒλŸ¬λ¦¬μ— λ“€μ–΄μžˆμŠ΅λ‹ˆλ‹€!
// μ„œλΉ„μŠ€ 객체λ₯Ό λ”°λ‘œ λ§Œλ“€μ§€ μ•Šκ³  λ°”λ‘œ λΆˆλŸ¬μ™”μŠ΅λ‹ˆλ‹€.
// μ–Έμ œλ‚˜ κ·Έλ ‡λ“― Callκ³Ό Callback은 Retrofit2의 것을 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. okhttp μ•„λ‹˜ 주의!
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.sopt.dosopttemplate.api.ServicePool.authService
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class AuthViewModel : ViewModel() {
// MutableLiveDataλ₯Ό μ‚¬μš©ν•˜μ—¬ login result 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

private val _loginResult: MutableLiveData<ResponseLoginDto> = MutableLiveData()
val loginResult: MutableLiveData<ResponseLoginDto> get() = _loginResult
private val _loginSuccess: MutableLiveData<Boolean> = MutableLiveData()
val loginSuccess: MutableLiveData<Boolean> get() = _loginSuccess

val isLoginButtonClicked: MutableLiveData<Boolean> = MutableLiveData(false)

fun login(id: String, password: String) {
authService.login(RequestLoginDto(id, password))
.enqueue(object : Callback<ResponseLoginDto> {
override fun onResponse(
call: Call<ResponseLoginDto>,
response: Response<ResponseLoginDto>,
) {
if (response.isSuccessful) {
_loginResult.value = response.body()
_loginSuccess.value = true
} else {
// TODO: μ—λŸ¬ 처리 둜직
_loginSuccess.value = false
}
}

override fun onFailure(call: Call<ResponseLoginDto>, t: Throwable) {
// TODO: μ—λŸ¬ 처리 둜직
}
})
}

fun onLoginButtonClick() {
isLoginButtonClicked.value = true
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/FollowerService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.dosopttemplate.api

import org.sopt.dosopttemplate.BuildConfig
import retrofit2.Call
import retrofit2.http.GET

private const val REQURES_BASE_URL = BuildConfig.REQRES_BASE_URL

interface FollowerService {
@GET(REQURES_BASE_URL)
fun getFollowerList(): Call<ResponseGetFollwerDto>
}
12 changes: 12 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/RequestLoginDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.dosopttemplate.api

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestLoginDto(
@SerialName("username")
val username: String,
@SerialName("password")
val password: String,
)
14 changes: 14 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/RequestSignUpDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.dosopttemplate.api

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestSignUpDto(
@SerialName("username")
val username: String,
@SerialName("nickname")
val nickname: String,
@SerialName("password")
val password: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.sopt.dosopttemplate.api

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseGetFollwerDto(
@SerialName("page")
val page: Int,
@SerialName("per_page")
val perPage: Int,
@SerialName("total")
val total: Int,
@SerialName("total_pages")
val totalPages: Int,
@SerialName("data")
val data: List<ResponseData>,
@SerialName("support")
val support: ResponseSupport
)

@Serializable
data class ResponseSupport(
@SerialName("url")
val url: String,
@SerialName("text")
val text: String
)

@Serializable
data class ResponseData(
@SerialName("id")
val id: Int,
@SerialName("email")
val email: String,
@SerialName("first_name")
val firstName: String,
@SerialName("last_name")
val lastName: String,
@SerialName("avatar")
val avatar: String,
)
14 changes: 14 additions & 0 deletions app/src/main/java/org/sopt/dosopttemplate/api/ResponseLoginDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.dosopttemplate.api

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseLoginDto(
@SerialName("id")
val id: Int,
@SerialName("username")
val username: String,
@SerialName("nickname")
val nickname: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.dosopttemplate.api

sealed class SignupResponse {
data class ResponseSignUpDto(
val location: String
)
}
26 changes: 2 additions & 24 deletions app/src/main/java/org/sopt/dosopttemplate/data/Music.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,9 @@ package org.sopt.dosopttemplate.data

import android.os.Parcel
import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class Music(val title: String, val artist: String) : Parcelable {
val string: String = "🎧$title - $artist"

constructor(parcel: Parcel) : this(
parcel.readString()!!,
parcel.readString()!!
)

override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(title)
parcel.writeString(artist)
}

override fun describeContents(): Int {
return 0
}

companion object CREATOR : Parcelable.Creator<Music> {
override fun createFromParcel(parcel: Parcel): Music {
return Music(parcel)
}

override fun newArray(size: Int): Array<Music?> {
return arrayOfNulls(size)
}
}
}
Loading