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

리워드 홈 배너 및 팝업 기능 추가 #114

Merged
merged 54 commits into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
605b7a7
refactor : 카카오 로그인 버튼 title param 추가
nohjunh May 27, 2024
5f34518
chore : 리소스 정의
nohjunh May 30, 2024
969caad
fix : 스크롤 위치 변경 수정
nohjunh Jun 1, 2024
4f79cdb
feat : Reward 관련 data, domain
nohjunh Jun 1, 2024
4f4aa76
feat : HomeRewardBanner Composable 추가
nohjunh Jun 1, 2024
8ea2f06
feat : 로그인 상태에서만 홈에 RewardBanner 추가
nohjunh Jun 1, 2024
8e8fa4c
feat : RewardPopup composable
nohjunh Jul 7, 2024
ff86e07
feat : show Reward Popup
nohjunh Jul 7, 2024
5db94ce
fix : shardFlow가 아닌 stateFlow로 처리하자.
nohjunh Jul 7, 2024
f2361b9
fix : 리워드팝업은 로그인 상태에서만
nohjunh Jul 7, 2024
ee87703
refactor : run보다 apply가 어울림
nohjunh Jul 7, 2024
8a2af31
chore : ballon api 추가
nohjunh Jul 7, 2024
685be22
fix : onNewIntent ? 제거
nohjunh Jul 7, 2024
0e0816d
chore : tooltip background color 변경
nohjunh Jul 7, 2024
ad55d3c
feat : totalParticipantCount 필드 추가
nohjunh Jul 7, 2024
88499d3
feat : eventEndDateTime 추가
nohjunh Jul 7, 2024
4aa0735
chore : isCoreLibraryDesugaringEnabled true
nohjunh Jul 13, 2024
d71a208
chore : resource, constants
nohjunh Jul 13, 2024
1f2d0af
feat : EventTimer Composable 추가
nohjunh Jul 13, 2024
27d04d6
feat : RewardPopup 추가
nohjunh Jul 13, 2024
550120b
refactor : messageRes 수정
nohjunh Jul 13, 2024
6d57459
refactor : 위치 변경
nohjunh Jul 13, 2024
a0a1f94
refactor : tooltip 옵션 변경
nohjunh Jul 13, 2024
68ce02f
refactor : rounded_button -> rounded_button_orange
nohjunh Jul 13, 2024
21b2393
chore : HomeFragment ItemDeco 제거
nohjunh Jul 13, 2024
c1cf1c7
feat : 이 글귀 공유하기 View 추가
nohjunh Jul 13, 2024
0d89fb9
feat : HomeFragment 카카오 공유 기능 추가
nohjunh Jul 13, 2024
e7308b0
refactor : ShowRewardPopup -> HomeRewardPopup
nohjunh Jul 13, 2024
162604f
feat : 티켓이 1개 이상 있을 때만 뱃지가 보이도록
nohjunh Jul 13, 2024
3d59ce3
feat : RewardInfo를 기준으로 endedTime 판단을 위해 combine 적용
nohjunh Jul 21, 2024
3d77801
feat : 응모권 갯수가 10개를 초과할 경우 대응 케이스 추가
nohjunh Jul 21, 2024
d95ef2a
refactor : companion object 위치 변경
nohjunh Jul 21, 2024
35d74b0
feat : 공유하기 이후 오늘 공유하기 횟수 및 팝업 업데이트
nohjunh Jul 21, 2024
23e2085
feat : 텍스트 색상 지정
nohjunh Jul 22, 2024
132ce61
chore : 불필요한 주석 제거
nohjunh Jul 22, 2024
a3b5490
refactor : RewardPopup Visi 조건 위치 변경
nohjunh Jul 22, 2024
5b74017
feat : EventTimer 카운트텍스트 pretendardFamily 제거
nohjunh Jul 22, 2024
1a9e242
feat :리워드팝업 텍스트 타이머 대응
nohjunh Jul 22, 2024
5c3b2df
refactor : 동일 조건식 추출
nohjunh Jul 22, 2024
637538c
feat : 카카오톡 공유 serverCallbackArgs 적용
nohjunh Jul 22, 2024
5b92ac6
chore : 불필요한 import 제거
nohjunh Jul 22, 2024
3fdd650
feat : proto 예외 처리
nohjunh Jul 24, 2024
627b2b9
refactor : 상수화
nohjunh Jul 24, 2024
c343791
refactor : 파라미터 순서 변경
nohjunh Jul 24, 2024
6be79e5
fix : 후행람다는 그대로 유지
nohjunh Jul 24, 2024
3ecc3c7
refactor : modifier 위치 변경
nohjunh Jul 27, 2024
d3f731a
refactor : 컴포저블 분리
nohjunh Jul 27, 2024
52c1f61
refactor : accessToken로 변수명 수정
nohjunh Jul 27, 2024
3c3d227
refactor : reward source 함수 네이밍 수정
nohjunh Jul 27, 2024
891ed0a
refactor : /prize에서 eventEndDateTime 제거된거 반영
nohjunh Jul 27, 2024
7780151
refactor : /info 변경사항 적용
nohjunh Jul 27, 2024
c591387
refactor : 우선적 ext 네이밍 수정
nohjunh Jul 27, 2024
70d01a5
chore : 필요한 네비게이션 위치 주석
nohjunh Jul 27, 2024
6b92ddc
Merge branch 'feat-115/reward' into feat-113/home_reward
nohjunh Jul 27, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.silvertown.android.dailyphrase.data.network.datasource

import com.silvertown.android.dailyphrase.data.network.common.ApiResponse
import com.silvertown.android.dailyphrase.data.network.model.response.BaseResponse
import com.silvertown.android.dailyphrase.data.network.model.response.RewardInfoResponse
import com.silvertown.android.dailyphrase.data.network.model.response.RewardWrapperResponse

interface RewardDataSource {
suspend fun getHomeRewards(): ApiResponse<BaseResponse<RewardWrapperResponse>>
suspend fun getRewardInfo(): ApiResponse<BaseResponse<RewardInfoResponse>>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.silvertown.android.dailyphrase.data.network.datasource

import com.silvertown.android.dailyphrase.data.network.common.ApiResponse
import com.silvertown.android.dailyphrase.data.network.model.response.BaseResponse
import com.silvertown.android.dailyphrase.data.network.model.response.RewardInfoResponse
import com.silvertown.android.dailyphrase.data.network.model.response.RewardWrapperResponse
import com.silvertown.android.dailyphrase.data.network.service.RewardApiService
import javax.inject.Inject

class RewardDataSourceImpl @Inject constructor(
private val rewardApiService: RewardApiService,
) : RewardDataSource {
override suspend fun getHomeRewards(): ApiResponse<BaseResponse<RewardWrapperResponse>> =
rewardApiService.getHomeRewards()

override suspend fun getRewardInfo(): ApiResponse<BaseResponse<RewardInfoResponse>> =
rewardApiService.getRewardInfo()

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import com.silvertown.android.dailyphrase.data.network.common.ApiResponse
import com.silvertown.android.dailyphrase.data.network.model.request.ShareEventRequest
import com.silvertown.android.dailyphrase.data.network.model.response.BaseResponse
import com.silvertown.android.dailyphrase.data.network.model.response.ShareEventResponse
import com.silvertown.android.dailyphrase.data.network.model.response.SharedCountResponse

interface ShareDataSource {
suspend fun logShareEvent(
data: ShareEventRequest,
): ApiResponse<BaseResponse<ShareEventResponse>>

suspend fun getSharedCount(): ApiResponse<BaseResponse<SharedCountResponse>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.silvertown.android.dailyphrase.data.network.common.ApiResponse
import com.silvertown.android.dailyphrase.data.network.model.request.ShareEventRequest
import com.silvertown.android.dailyphrase.data.network.model.response.BaseResponse
import com.silvertown.android.dailyphrase.data.network.model.response.ShareEventResponse
import com.silvertown.android.dailyphrase.data.network.model.response.SharedCountResponse
import com.silvertown.android.dailyphrase.data.network.service.ShareApiService
import javax.inject.Inject

Expand All @@ -14,4 +15,10 @@ class ShareDataSourceImpl @Inject constructor(
override suspend fun logShareEvent(data: ShareEventRequest): ApiResponse<BaseResponse<ShareEventResponse>> {
return shareApiService.logShareEvent(data = data)
}

override suspend fun getSharedCount(): ApiResponse<BaseResponse<SharedCountResponse>> {
return shareApiService.getSharedCount()
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.silvertown.android.dailyphrase.data.network.di
import com.silvertown.android.dailyphrase.data.network.service.MemberApiService
import com.silvertown.android.dailyphrase.data.network.service.ModalApiService
import com.silvertown.android.dailyphrase.data.network.service.PostApiService
import com.silvertown.android.dailyphrase.data.network.service.RewardApiService
import com.silvertown.android.dailyphrase.data.network.service.ShareApiService
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -58,4 +59,15 @@ object ApiServiceModule {
.client(okHttpclient)
.build()
.create(ModalApiService::class.java)

@Singleton
@Provides
fun provideRewardApiService(
@AuthOkHttpClient okHttpclient: OkHttpClient,
retrofit: Retrofit.Builder,
): RewardApiService =
retrofit
.client(okHttpclient)
.build()
.create(RewardApiService::class.java)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import com.silvertown.android.dailyphrase.data.network.datasource.ModalDataSourc
import com.silvertown.android.dailyphrase.data.network.datasource.ModalDataSourceImpl
import com.silvertown.android.dailyphrase.data.network.datasource.PostDataSource
import com.silvertown.android.dailyphrase.data.network.datasource.PostDataSourceImpl
import com.silvertown.android.dailyphrase.data.network.datasource.RewardDataSource
import com.silvertown.android.dailyphrase.data.network.datasource.RewardDataSourceImpl
import com.silvertown.android.dailyphrase.data.network.datasource.ShareDataSource
import com.silvertown.android.dailyphrase.data.network.datasource.ShareDataSourceImpl
import com.silvertown.android.dailyphrase.data.network.service.MemberApiService
import com.silvertown.android.dailyphrase.data.network.service.ModalApiService
import com.silvertown.android.dailyphrase.data.network.service.PostApiService
import com.silvertown.android.dailyphrase.data.network.service.RewardApiService
import com.silvertown.android.dailyphrase.data.network.service.ShareApiService
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -40,4 +43,9 @@ object DataSourceModule {
@Singleton
fun provideModalDataSource(modalApiService: ModalApiService): ModalDataSource =
ModalDataSourceImpl(modalApiService)

@Provides
@Singleton
fun provideRewardDataSource(rewardApiService: RewardApiService): RewardDataSource =
RewardDataSourceImpl(rewardApiService)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.silvertown.android.dailyphrase.data.network.model.response

import com.google.gson.annotations.SerializedName
import com.silvertown.android.dailyphrase.data.util.DateTimeUtils
import com.silvertown.android.dailyphrase.domain.model.RewardInfo
import java.time.LocalDateTime

data class RewardInfoResponse(
@SerializedName("eventId")
val eventId: Int?,
@SerializedName("name")
val name: String?,
@SerializedName("status")
val status: String?,
@SerializedName("eventEndDateTime")
val eventEndDateTime: String?,
juhwankim-dev marked this conversation as resolved.
Show resolved Hide resolved
)

fun RewardInfoResponse.toDomainModel(): RewardInfo {
val parsedEndDate = eventEndDateTime?.let {
LocalDateTime.parse(it, DateTimeUtils.localDateTimeFormatter)
}

return RewardInfo(
eventId = eventId,
name = name.orEmpty(),
eventEndDateTime = parsedEndDate
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.silvertown.android.dailyphrase.data.network.model.response

import com.google.gson.annotations.SerializedName
import com.silvertown.android.dailyphrase.data.util.DateTimeUtils
import com.silvertown.android.dailyphrase.domain.model.RewardBanner
import java.time.LocalDateTime

data class RewardResponse(
@SerializedName("eventId")
val eventId: Int?,
@SerializedName("imageUrl")
val imageUrl: String?,
@SerializedName("manufacturer")
val manufacturer: String?,
@SerializedName("myEntryCount")
val myEntryCount: Int?,
@SerializedName("myTicketCount")
val myTicketCount: Int?,
@SerializedName("name")
val name: String?,
@SerializedName("prizeId")
val prizeId: Int?,
@SerializedName("requiredTicketCount")
val requiredTicketCount: Int?,
@SerializedName("totalParticipantCount")
val totalParticipantCount: Int?,
@SerializedName("shortName")
val shortName: String?,
@SerializedName("totalEntryCount")
val totalEntryCount: Int?,
)

fun RewardResponse.toDomainModel(
eventEndDateTime: String?,
): RewardBanner {
val parsedEndDate = eventEndDateTime?.let {
LocalDateTime.parse(it, DateTimeUtils.localDateTimeFormatter)
juhwankim-dev marked this conversation as resolved.
Show resolved Hide resolved
}

return RewardBanner(
eventId = eventId ?: 0,
imageUrl = imageUrl.orEmpty(),
manufacturer = manufacturer.orEmpty(),
myEntryCount = myEntryCount ?: 0,
name = name.orEmpty(),
prizeId = prizeId ?: 0,
requiredTicketCount = requiredTicketCount ?: 0,
shortName = shortName.orEmpty(),
totalParticipantCount = totalParticipantCount ?: 0,
totalEntryCount = totalEntryCount ?: 0,
myTicketCount = myTicketCount ?: 0,
eventEndDateTime = parsedEndDate
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.silvertown.android.dailyphrase.data.network.model.response

import com.google.gson.annotations.SerializedName

data class RewardWrapperResponse(
@SerializedName("prizeList")
val rewardList: List<RewardResponse>?,
@SerializedName("total")
val total: Int?,
@SerializedName("eventEndDateTime")
val eventEndDateTime: String?,
juhwankim-dev marked this conversation as resolved.
Show resolved Hide resolved
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.silvertown.android.dailyphrase.data.network.model.response

import com.google.gson.annotations.SerializedName
import com.silvertown.android.dailyphrase.domain.model.SharedCountModel
import java.time.LocalDateTime

data class SharedCountResponse(
@SerializedName("shareCount")
val shareCount: Int?,
@SerializedName("date")
val date: LocalDateTime?,
)

fun SharedCountResponse.toDomainModel(): SharedCountModel {
return SharedCountModel(
sharedCount = shareCount ?: 0
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.silvertown.android.dailyphrase.data.network.service

import com.silvertown.android.dailyphrase.data.network.common.ApiResponse
import com.silvertown.android.dailyphrase.data.network.model.response.BaseResponse
import com.silvertown.android.dailyphrase.data.network.model.response.RewardInfoResponse
import com.silvertown.android.dailyphrase.data.network.model.response.RewardWrapperResponse
import retrofit2.http.GET

interface RewardApiService {
@GET("/api/v1/events/prizes")
suspend fun getHomeRewards(): ApiResponse<BaseResponse<RewardWrapperResponse>>
juhwankim-dev marked this conversation as resolved.
Show resolved Hide resolved

@GET("/api/v1/events/info")
suspend fun getRewardInfo(): ApiResponse<BaseResponse<RewardInfoResponse>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@ import com.silvertown.android.dailyphrase.data.network.common.ApiResponse
import com.silvertown.android.dailyphrase.data.network.model.request.ShareEventRequest
import com.silvertown.android.dailyphrase.data.network.model.response.BaseResponse
import com.silvertown.android.dailyphrase.data.network.model.response.ShareEventResponse
import com.silvertown.android.dailyphrase.data.network.model.response.SharedCountResponse
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query

interface ShareApiService {
@POST("/api/v1/shares")
suspend fun logShareEvent(
@Body data: ShareEventRequest,
): ApiResponse<BaseResponse<ShareEventResponse>>

@GET("/api/v1/shares/me")
suspend fun getSharedCount(
@Query("date") date: String? = null
): ApiResponse<BaseResponse<SharedCountResponse>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.silvertown.android.dailyphrase.data.repository

import com.silvertown.android.dailyphrase.data.network.common.toResultModel
import com.silvertown.android.dailyphrase.data.network.datasource.RewardDataSource
import com.silvertown.android.dailyphrase.data.network.model.response.toDomainModel
import com.silvertown.android.dailyphrase.domain.model.RewardBanner
import com.silvertown.android.dailyphrase.domain.model.RewardInfo
import com.silvertown.android.dailyphrase.domain.model.onFailure
import com.silvertown.android.dailyphrase.domain.model.onSuccess
import com.silvertown.android.dailyphrase.domain.repository.RewardRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import timber.log.Timber
import javax.inject.Inject

class RewardRepositoryImpl @Inject constructor(
private val rewardDataSource: RewardDataSource,
) : RewardRepository {
override fun getHomeRewardBanner(): Flow<RewardBanner> = flow {
rewardDataSource
.getHomeRewards()
.toResultModel { rewardWrapper ->
rewardWrapper.result?.rewardList?.map { reward ->
reward.toDomainModel(rewardWrapper.result.eventEndDateTime)
}
}
.onSuccess { rewardBannerList ->
rewardBannerList.randomOrNull()?.let { rewardBanner ->
emit(rewardBanner)
}
}
.onFailure { errorMessage, _ ->
Timber.e(errorMessage)
}
}

override fun getRewardInfo(): Flow<RewardInfo> = flow {
rewardDataSource.getRewardInfo()
.toResultModel {
it.result?.toDomainModel()
}
.onSuccess { rewardInfo ->
emit(rewardInfo)
}
.onFailure { errorMessage, _ ->
Timber.e(errorMessage)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import com.silvertown.android.dailyphrase.data.network.common.toResultModel
import com.silvertown.android.dailyphrase.data.network.datasource.ShareDataSource
import com.silvertown.android.dailyphrase.data.network.model.request.ShareEventRequest
import com.silvertown.android.dailyphrase.data.network.model.response.toDomainModel
import com.silvertown.android.dailyphrase.domain.model.SharedCountModel
import com.silvertown.android.dailyphrase.domain.model.onFailure
import com.silvertown.android.dailyphrase.domain.model.onSuccess
import com.silvertown.android.dailyphrase.domain.repository.ShareRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import timber.log.Timber
import javax.inject.Inject

class ShareRepositoryImpl @Inject constructor(
Expand All @@ -20,4 +26,17 @@ class ShareRepositoryImpl @Inject constructor(
),
).toResultModel { it.result?.toDomainModel() }
}

override fun getSharedCount(): Flow<SharedCountModel> = flow {
shareDataSource.getSharedCount()
.toResultModel {
it.result?.toDomainModel()
}
.onSuccess { sharedCount ->
emit(sharedCount)
}
.onFailure { errorMessage, _ ->
Timber.e(errorMessage)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package com.silvertown.android.dailyphrase.data.repository.di
import com.silvertown.android.dailyphrase.data.repository.MemberRepositoryImpl
import com.silvertown.android.dailyphrase.data.repository.ModalRepositoryImpl
import com.silvertown.android.dailyphrase.data.repository.PostRepositoryImpl
import com.silvertown.android.dailyphrase.data.repository.RewardRepositoryImpl
import com.silvertown.android.dailyphrase.data.repository.ShareRepositoryImpl
import com.silvertown.android.dailyphrase.domain.repository.MemberRepository
import com.silvertown.android.dailyphrase.domain.repository.ModalRepository
import com.silvertown.android.dailyphrase.domain.repository.PostRepository
import com.silvertown.android.dailyphrase.domain.repository.RewardRepository
import com.silvertown.android.dailyphrase.domain.repository.ShareRepository
import dagger.Binds
import dagger.Module
Expand Down Expand Up @@ -40,4 +42,10 @@ internal interface RepositoryModule {
fun bindModalRepository(
modalRepository: ModalRepositoryImpl,
): ModalRepository

@Singleton
@Binds
fun bindRewardRepository(
rewardRepository: RewardRepositoryImpl,
): RewardRepository
}
Loading