Skip to content

Commit

Permalink
Merge pull request #554 from TeamSparker/release-1.1.0
Browse files Browse the repository at this point in the history
#551 재재업로드 Release 1.1.0
  • Loading branch information
2chang5 authored Nov 2, 2022
2 parents c09b34b + 821956a commit ac536c8
Show file tree
Hide file tree
Showing 125 changed files with 1,503 additions and 88 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ android {
applicationId "com.teamsparker.android"
minSdk 26
targetSdk 31
versionCode 4
versionName "1.0.2"
versionCode 5
versionName "1.1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ class LocalPreferencesDataSourceImpl @Inject constructor(
}

companion object {
private const val ACCESS_TOKEN = "ACCESS_TOKEN"
private const val USER_KAKAO_USER_ID = "USER_KAKAO_USER_ID"
private const val USER_NICKNAME = "USER_NAME"
private const val ALARM_LOCAL_SAVED = "ALARM_LOCAL_SAVED"
const val ACCESS_TOKEN = "ACCESS_TOKEN"
const val USER_KAKAO_USER_ID = "USER_KAKAO_USER_ID"
const val USER_NICKNAME = "USER_NAME"
const val ALARM_LOCAL_SAVED = "ALARM_LOCAL_SAVED"
const val DEFAULT_STRING_VALUE = ""
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.teamsparker.android.data.remote

import com.teamsparker.android.data.remote.calladapter.CustomCallAdapterFactory
import com.teamsparker.android.data.remote.service.*
import okhttp3.Interceptor
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -28,19 +29,20 @@ object RetrofitBuilder {
.addInterceptor(headerInterceptor)
.build()


private val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addCallAdapterFactory(CustomCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()

// 이 밑에다가 이런식으로 서비스 객체 생성하기
// val sampleService: SampleService = retrofit.create(SampleService::class.java)

val habitService : HabitService = retrofit.create(HabitService::class.java)
val habitService: HabitService = retrofit.create(HabitService::class.java)
val storageService: StorageService = retrofit.create(StorageService::class.java)
val photoCollectionService: PhotoCollectionService = retrofit.create(PhotoCollectionService::class.java)
val photoCollectionService: PhotoCollectionService =
retrofit.create(PhotoCollectionService::class.java)
val photoMainService: PhotoMainService = retrofit.create(PhotoMainService::class.java)
val setStatusService: SetStatusService = retrofit.create(SetStatusService::class.java)
val sendSparkService: SendSparkService = retrofit.create(SendSparkService::class.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.teamsparker.android.data.remote.calladapter

import okhttp3.Request
import okio.Timeout
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.IOException

class CustomCall<T : Any>(private val call: Call<T>) : Call<NetworkState<T>> {

override fun enqueue(callback: Callback<NetworkState<T>>) {
call.enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
val body = response.body()
val code = response.code()
val error = response.errorBody()?.string()

if (response.isSuccessful) {
if (body != null) {
callback.onResponse(
this@CustomCall,
Response.success(NetworkState.Success(body))
)
} else {
callback.onResponse(
this@CustomCall,
Response.success(
NetworkState.UnknownError(
IllegalStateException("body값이 null로 넘어옴"),
"body값이 null로 넘어옴"
)
)
)
}
} else {
callback.onResponse(
this@CustomCall,
Response.success(NetworkState.Failure(code, error))
)
}
}

override fun onFailure(call: Call<T>, t: Throwable) {
val errorResponse = when (t) {
is IOException -> NetworkState.NetworkError(t)
else -> NetworkState.UnknownError(t, "onFailure에 진입,IoException 이외의 에러")
}
callback.onResponse(this@CustomCall, Response.success(errorResponse))
}
})
}

override fun clone(): Call<NetworkState<T>> = CustomCall(call.clone())

override fun execute(): Response<NetworkState<T>> {
throw UnsupportedOperationException("커스텀한 callAdapter에서는 execute를 사용하지 않습니다 ")
}

override fun isExecuted(): Boolean = call.isExecuted

override fun cancel() = call.cancel()

override fun isCanceled(): Boolean = call.isCanceled

override fun request(): Request = call.request()

override fun timeout(): Timeout = call.timeout()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.teamsparker.android.data.remote.calladapter

import retrofit2.Call
import retrofit2.CallAdapter
import java.lang.reflect.Type

class CustomCallAdapter<R : Any>(private val responseType: Type) :
CallAdapter<R, Call<NetworkState<R>>> {
override fun responseType(): Type = responseType

override fun adapt(call: Call<R>): Call<NetworkState<R>> = CustomCall(call)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.teamsparker.android.data.remote.calladapter

import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Retrofit
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class CustomCallAdapterFactory : CallAdapter.Factory() {

override fun get(
returnType: Type,
annotations: Array<out Annotation>,
retrofit: Retrofit
): CallAdapter<*, *>? {
if (Call::class.java != getRawType(returnType)) {
return null
}

check(returnType is ParameterizedType) {
"return type must be parameterized as Call<NetworkState<Foo>> or Call<NetworkState<out Foo>>"
}

val responseType = getParameterUpperBound(0, returnType)

if (getRawType(responseType) != NetworkState::class.java) {
return null
}

check(responseType is ParameterizedType) {
"Response must be parameterized as NetworkState<Foo> or NetworkState<out Foo>"
}

val bodyType = getParameterUpperBound(0, responseType)

return CustomCallAdapter<Any>(bodyType)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.teamsparker.android.data.remote.calladapter

import java.io.IOException

sealed class NetworkState<out T : Any> {

// 200대 응답 성공한것
data class Success<T : Any>(val body: T) : NetworkState<T>()

// isSuccessful 이 false인 경우(200~300대 응답이 아닌경우)
data class Failure(val code: Int, val error: String?) : NetworkState<Nothing>()

// onFailure로 넘어간경우(네트워크 오류,timeout 같은거)
data class NetworkError(val error: IOException) : NetworkState<Nothing>()

// 예상 못한에러(기타 모든 에러처리)
data class UnknownError(val t: Throwable?, val errorState: String) : NetworkState<Nothing>()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.teamsparker.android.data.remote.calladapter

class RetrofitFailureStateException(error: String?, val code: Int) : Exception(error)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.teamsparker.android.data.remote.datasource

import com.teamsparker.android.data.remote.calladapter.NetworkState
import com.teamsparker.android.data.remote.entity.response.BaseResponse
import com.teamsparker.android.data.remote.entity.response.HabitRoomTimeLine
import com.teamsparker.android.data.remote.service.HabitRoomTimeLineService
import javax.inject.Inject

class HabitRoomTImeLineDataSourceImpl @Inject constructor(
private val habitRoomTimeLineService: HabitRoomTimeLineService
) : HabitRoomTimeLineDataSource {
override suspend fun getHabitRoomTimeLine(roomId: Int): NetworkState<BaseResponse<HabitRoomTimeLine>> =
habitRoomTimeLineService.getHabitRoomRimeLine(roomId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.teamsparker.android.data.remote.datasource

import com.teamsparker.android.data.remote.calladapter.NetworkState
import com.teamsparker.android.data.remote.entity.response.BaseResponse
import com.teamsparker.android.data.remote.entity.response.HabitRoomTimeLine

interface HabitRoomTimeLineDataSource {

suspend fun getHabitRoomTimeLine(roomId: Int): NetworkState<BaseResponse<HabitRoomTimeLine>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ data class HabitResponse(
val roomName: String,
val leftDay: Int,
val life: Int,
val lifeDeductionCount : Int,
val startDate: String,
val endDate: String,
val fromStart: Boolean,
val moment: String,
val purpose: String,
val myRecord: HabitRecord,
val otherRecords: List<OtherRecord>,
val isTimelineNew: Boolean,
val isTermNew: Boolean
)

data class HabitRecord(
Expand All @@ -22,13 +23,13 @@ data class HabitRecord(
val recordId: Int,
val rest: Int = -1,
val status: String,
val userId: Int,
val userId: Int
)

data class OtherRecord(
val nickname: String,
val profileImg: String,
val recordId: Int,
val status: String,
val userId: Int,
val userId: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.teamsparker.android.data.remote.entity.response

import com.google.gson.annotations.SerializedName

data class HabitRoomTimeLine(
@SerializedName("timelines")
val timelines: List<Timeline>
)

data class Timeline(
@SerializedName("content")
val content: String,
@SerializedName("day")
val day: String,
@SerializedName("isNew")
val isNew: Boolean,
@SerializedName("profiles")
val profiles: List<String>,
@SerializedName("title")
val title: String
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.teamsparker.android.data.remote.repository

import com.teamsparker.android.data.remote.entity.response.HabitRoomTimeLine

interface HabitRepository {

fun setHabitUserGuideState(state: Boolean)

fun getHabitUserGuideState(): Boolean

suspend fun getHabitRoomTimeLine(roomId: Int): Result<HabitRoomTimeLine>
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.teamsparker.android.data.remote.repository

import com.teamsparker.android.data.local.datasource.LocalPreferencesHabitDataSource
import com.teamsparker.android.data.remote.calladapter.NetworkState
import com.teamsparker.android.data.remote.calladapter.RetrofitFailureStateException
import com.teamsparker.android.data.remote.datasource.HabitRoomTimeLineDataSource
import com.teamsparker.android.data.remote.entity.response.HabitRoomTimeLine
import timber.log.Timber.Forest.tag
import java.security.cert.CertificateException
import javax.inject.Inject

class HabitRepositoryImpl @Inject constructor(
private val localPreferencesHabitDataSource: LocalPreferencesHabitDataSource
private val localPreferencesHabitDataSource: LocalPreferencesHabitDataSource,
private val habitRoomTimeLineDataSource: HabitRoomTimeLineDataSource
) : HabitRepository {

override fun setHabitUserGuideState(state: Boolean) {
Expand All @@ -13,4 +20,22 @@ class HabitRepositoryImpl @Inject constructor(

override fun getHabitUserGuideState(): Boolean =
localPreferencesHabitDataSource.getHabitUserGuideState()

override suspend fun getHabitRoomTimeLine(roomId: Int): Result<HabitRoomTimeLine> {
when (val response = habitRoomTimeLineDataSource.getHabitRoomTimeLine(roomId)) {
is NetworkState.Success -> return Result.success(
response.body.data
)
is NetworkState.Failure ->
if (response.code == 401) throw CertificateException("토큰 만료 오류")
else return Result.failure(
RetrofitFailureStateException(response.error, response.code)
)
is NetworkState.NetworkError -> tag("${this.javaClass.name}_getHabitRoomTimeLine")
.d(response.error)
is NetworkState.UnknownError -> tag("${this.javaClass.name}_getHabitRoomTimeLine")
.d(response.t)
}
return Result.failure(IllegalStateException("NetworkError or UnKnownError please check timber"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.teamsparker.android.data.remote.service

import com.teamsparker.android.data.remote.calladapter.NetworkState
import com.teamsparker.android.data.remote.entity.response.BaseResponse
import com.teamsparker.android.data.remote.entity.response.HabitRoomTimeLine
import retrofit2.http.GET
import retrofit2.http.Path

interface HabitRoomTimeLineService {
@GET("room/{roomId}/timeline")
suspend fun getHabitRoomRimeLine(
@Path("roomId") roomId: Int
): NetworkState<BaseResponse<HabitRoomTimeLine>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.teamsparker.android.di

import com.teamsparker.android.data.remote.datasource.*
import com.teamsparker.android.data.remote.service.*
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -57,4 +58,11 @@ object RemoteDataSourceModule {
alarmCenterService: AlarmCenterService
): AlarmCenterDataSource =
AlarmCenterDataSourceImpl(alarmCenterService)

@Provides
@Singleton
fun provideHabitRoomTimeLineDataSource(
habitRoomTimeLineService: HabitRoomTimeLineService
): HabitRoomTimeLineDataSource =
HabitRoomTImeLineDataSourceImpl(habitRoomTimeLineService)
}
Loading

0 comments on commit ac536c8

Please sign in to comment.