-
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
Feat/#10 홈 화면 구현 #36
The head ref may contain hidden characters: "feat/#10-\uD648-\uD654\uBA74-\uAD6C\uD604"
Feat/#10 홈 화면 구현 #36
Changes from 58 commits
f854667
cb9ab61
5f647ca
61c2816
df51ab0
d77d56c
aff6ac8
47b02dd
7f016d4
adc78d5
1229b39
8ca2caf
f4a4f7e
6e14a0f
ac99d21
8dabdab
a290fdc
52c1d29
75258ec
6ca6b75
3eba04c
695e481
fa47ecc
21e1f5e
018d854
bf2effa
aedadf2
d6d4093
739c0a4
6cd5b19
2ab5d6d
9dcf219
04ba3e5
294e276
4150e1e
d94108c
f491b28
997acc6
dc2ff41
0c2c295
b42fd08
c81ea3d
4a03a2f
0344d53
d1082d7
3bf0615
499634b
80ca345
eb30b93
b064b14
f5b4fbf
f67a719
28bd569
7ac79fb
8376e76
c65f3f5
a41f69e
83aff20
6d32027
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.owori.android.core | ||
|
||
|
||
object AppConfig { | ||
const val TAG_DEBUG = "TAG_DEBUG" | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.owori.android.core | ||
|
||
import android.graphics.Color | ||
import android.graphics.drawable.ColorDrawable | ||
import android.os.Bundle | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT | ||
import androidx.fragment.app.DialogFragment | ||
import com.owori.android.databinding.DialogBaseBinding | ||
|
||
class BaseDialogFragment( | ||
private val title: String, | ||
private val contents: String, | ||
private val positiveButtonText: String? = null, | ||
private val cancelButtonText: String? = null, | ||
private val onClickPositiveButton: () -> Unit = {} | ||
) : DialogFragment() { | ||
private var _binding: DialogBaseBinding? = null | ||
private val binding get() = _binding!! | ||
|
||
override fun onCreateView( | ||
inflater: LayoutInflater, | ||
container: ViewGroup?, | ||
savedInstanceState: Bundle? | ||
): View { | ||
_binding = DialogBaseBinding.inflate(inflater, container, false) | ||
val view = binding.root | ||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) | ||
|
||
with(binding) { | ||
titleTextview.text = title | ||
contentsTextview.text = contents | ||
|
||
positiveButtonText?.let { positiveText.text = it } | ||
cancelButtonText?.let { cancelText.text = it } | ||
|
||
cancelButton.setOnClickListener { | ||
dialog?.dismiss() | ||
} | ||
|
||
positiveButton.setOnClickListener { | ||
onClickPositiveButton() | ||
dialog?.dismiss() | ||
} | ||
} | ||
|
||
return view | ||
} | ||
|
||
override fun onResume() { | ||
super.onResume() | ||
[email protected]?.window?.setLayout(WRAP_CONTENT, WRAP_CONTENT) | ||
} | ||
|
||
override fun onDestroyView() { | ||
super.onDestroyView() | ||
_binding = null | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,44 @@ | ||
package com.owori.android.core | ||
|
||
import android.annotation.SuppressLint | ||
import android.app.Application | ||
import com.kakao.sdk.common.KakaoSdk | ||
import android.content.Context | ||
import androidx.annotation.StringRes | ||
import androidx.lifecycle.DefaultLifecycleObserver | ||
import androidx.lifecycle.LifecycleOwner | ||
import com.owori.android.R | ||
import com.owori.android.module.NetworkConnectionChecker | ||
import com.kakao.sdk.common.KakaoSdk | ||
import dagger.hilt.android.HiltAndroidApp | ||
|
||
@HiltAndroidApp | ||
class OworiApplication: Application() { | ||
class OworiApplication : Application(), DefaultLifecycleObserver { | ||
override fun onCreate() { | ||
super.onCreate() | ||
super<Application>.onCreate() | ||
context = applicationContext | ||
networkConnectionChecker = NetworkConnectionChecker(context) | ||
KakaoSdk.init(this, getString(R.string.kakao_login_key)) | ||
} | ||
|
||
override fun onStop(owner: LifecycleOwner) { | ||
networkConnectionChecker.unregister() | ||
super.onStop(owner) | ||
} | ||
|
||
override fun onStart(owner: LifecycleOwner) { | ||
networkConnectionChecker.register() | ||
super.onStart(owner) | ||
} | ||
|
||
companion object { | ||
@SuppressLint("StaticFieldLeak") | ||
private lateinit var context: Context | ||
|
||
fun getString(@StringRes stringResId: Int): String { | ||
return context.getString(stringResId) | ||
} | ||
|
||
private lateinit var networkConnectionChecker: NetworkConnectionChecker | ||
fun isOnline() = networkConnectionChecker.isOnline() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package com.owori.android.core.di | ||
|
||
import com.owori.android.R | ||
import com.owori.android.core.OworiApplication | ||
import com.owori.android.data.api.auth.AuthApi | ||
import com.owori.android.module.HttpRequestInterceptor | ||
import dagger.Module | ||
import dagger.Provides | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import okhttp3.OkHttpClient | ||
import retrofit2.Retrofit | ||
import retrofit2.converter.gson.GsonConverterFactory | ||
import retrofit2.converter.scalars.ScalarsConverterFactory | ||
import javax.inject.Singleton | ||
|
||
/* | ||
* Created by JJJoonngg | ||
*/ | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
object NetworkModule { | ||
const val NETWORK_EXCEPTION_OFFLINE_CASE = "network status is offline" | ||
const val NETWORK_EXCEPTION_BODY_IS_NULL = "result body is null" | ||
|
||
@Provides | ||
@Singleton | ||
fun provideOKHttpClient(): OkHttpClient { | ||
return OkHttpClient.Builder() | ||
.addInterceptor(HttpRequestInterceptor()) | ||
.retryOnConnectionFailure(false) | ||
.build() | ||
} | ||
|
||
@Provides | ||
@Singleton | ||
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit { | ||
return Retrofit.Builder() | ||
.client(okHttpClient) | ||
.baseUrl(OworiApplication.getString(R.string.base_url)) | ||
.addConverterFactory(ScalarsConverterFactory.create()) | ||
.addConverterFactory(GsonConverterFactory.create()) | ||
.build() | ||
} | ||
|
||
@Provides | ||
@Singleton | ||
fun provideAuthApi(retrofit: Retrofit): AuthApi { | ||
return retrofit.buildService() | ||
} | ||
|
||
private inline fun <reified T> Retrofit.buildService(): T { | ||
return this.create(T::class.java) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.owori.android.data.api.auth | ||
|
||
import com.owori.android.data.model.SignUpRequest | ||
import com.owori.android.data.model.SignUpResponse | ||
import com.owori.android.module.DataResult | ||
import retrofit2.http.Body | ||
import retrofit2.http.POST | ||
|
||
/* | ||
* Created by JJJoonngg | ||
*/ | ||
|
||
interface AuthApi { | ||
@POST("/members/kakao") | ||
fun kakaoLogin(@Body data: SignUpRequest) : DataResult<SignUpResponse> | ||
|
||
@POST("/members/google") | ||
fun googleLogin(@Body data: SignUpRequest) : DataResult<SignUpResponse> | ||
|
||
@POST("/members/apple") | ||
fun appleLogin(@Body data: SignUpRequest) : DataResult<SignUpResponse> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.owori.android.data.model | ||
|
||
import com.google.gson.annotations.SerializedName | ||
|
||
data class SignUpRequest( | ||
val token: String, | ||
@SerializedName("auth_provider") | ||
val authProvider: AuthProvider | ||
) { | ||
enum class AuthProvider { | ||
GOOGLE, KAKAO, APPLE | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.owori.android.data.model | ||
|
||
import com.google.gson.annotations.SerializedName | ||
|
||
data class SignUpResponse( | ||
@SerializedName("member_name") | ||
val memberId: String, | ||
@SerializedName("is_service_member") | ||
val isMember: Boolean, | ||
@SerializedName("jwt_token") | ||
val token: Token, | ||
) { | ||
data class Token ( | ||
@SerializedName("access_token") | ||
val accessToken: String, | ||
@SerializedName("refresh_token") | ||
val refreshToken: String, | ||
) | ||
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. Token이라는 단어는 여기서만 사용되면 상관이 없지만 좀 더 범용적으로 사용되는 단어이니 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. 오 좋네요! 수정하겠습니다!! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.owori.android.module | ||
|
||
/* | ||
* Created by JJJoonngg | ||
*/ | ||
|
||
sealed class DataResult<out T> { | ||
data class Success<T>(val data: T) : DataResult<T>() | ||
data class Fail(val statusCode: Int, val message: String) : DataResult<Nothing>() | ||
data class Error(val exception: Exception) : DataResult<Nothing>() | ||
} | ||
|
||
inline fun <T> DataResult<T>.onSuccess(action: (T) -> Unit): DataResult<T> { | ||
if (this is DataResult.Success) { | ||
action(data) | ||
} | ||
return this | ||
} | ||
|
||
inline fun <T> DataResult<T>.onFail(resultCode: (Int) -> Unit): DataResult<T> { | ||
if (this is DataResult.Fail) { | ||
resultCode(this.statusCode) | ||
} | ||
return this | ||
} | ||
|
||
inline fun <T> DataResult<T>.onError(action: (Exception) -> Unit): DataResult<T> { | ||
if (this is DataResult.Fail) { | ||
action(IllegalArgumentException("code : ${this.statusCode}, message : ${this.message}")) | ||
} else if (this is DataResult.Error) { | ||
action(this.exception) | ||
} | ||
return this | ||
} | ||
|
||
inline fun <T> DataResult<T>.onException(action: (Exception) -> Unit): DataResult<T> { | ||
if (this is DataResult.Error) { | ||
action(this.exception) | ||
} | ||
return this | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.owori.android.module | ||
|
||
import com.owori.android.core.OworiApplication | ||
import com.owori.android.core.di.NetworkModule | ||
import retrofit2.Response | ||
|
||
/* | ||
* Created by JJJoonngg | ||
*/ | ||
|
||
suspend fun <T : Any, R : Any> handleApi( | ||
execute: suspend () -> Response<T>, | ||
mapper: (T) -> R | ||
): DataResult<R> { | ||
if (OworiApplication.isOnline().not()) { | ||
return DataResult.Error(Exception(NetworkModule.NETWORK_EXCEPTION_OFFLINE_CASE)) | ||
} | ||
|
||
return try { | ||
val response = execute() | ||
val body = response.body() | ||
if (response.isSuccessful) { | ||
body?.let { | ||
DataResult.Success(mapper(it)) | ||
} ?: run { | ||
throw NullPointerException(NetworkModule.NETWORK_EXCEPTION_BODY_IS_NULL) | ||
} | ||
} else { | ||
getFailDataResult(body, response) | ||
} | ||
} catch (e: Exception) { | ||
DataResult.Error(e) | ||
} | ||
} | ||
|
||
|
||
private fun <T : Any> getFailDataResult(body: T?, response: Response<T>) = body?.let { | ||
DataResult.Fail(statusCode = response.code(), message = it.toString()) | ||
} ?: run { | ||
DataResult.Fail(statusCode = response.code(), message = response.message()) | ||
} |
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.
별도의 enum class로 빼주는게 추후에 다른 곳에서 사용시 편할 수 있슴다.
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.
별도로 분리할께요!