Skip to content

Commit

Permalink
Merge branch 'develop' into feat-login-api-connection
Browse files Browse the repository at this point in the history
  • Loading branch information
jooyyoo committed Sep 19, 2023
2 parents 1cfede4 + 126a3e1 commit d346911
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.sopt.geonppang.data.interceptor

import android.app.Application
import android.content.Intent
import com.sopt.geonppang.BuildConfig
import com.sopt.geonppang.data.datasource.local.GPDataSource
import com.sopt.geonppang.presentation.auth.SignActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject

class AuthInterceptor @Inject constructor(
private val gpDataSource: GPDataSource
private val gpDataSource: GPDataSource,
private val context: Application,
) : Interceptor {

override fun intercept(chain: Interceptor.Chain): Response {
Expand All @@ -18,9 +26,49 @@ class AuthInterceptor @Inject constructor(

when (response.code) {
401 -> {
// TODO 토큰 재발급 api 연동
response.close()
val refreshTokenRequest = originalRequest.newBuilder().get()
.url("${BuildConfig.GP_BASE_URL}auth/refresh")
.addHeader(ACCESS_TOKEN, gpDataSource.accessToken)
.addHeader(REFRESH_TOKEN, gpDataSource.refreshToken)
.build()
val refreshTokenResponse = chain.proceed(refreshTokenRequest)

if (refreshTokenResponse.isSuccessful) {
val responseHeader = refreshTokenResponse.headers
val responseAccessToken = responseHeader[ACCESS_TOKEN]
val responseRefreshToken = responseHeader[REFRESH_TOKEN]

with(gpDataSource) {
accessToken = BEARER_PREFIX + responseAccessToken.toString()
refreshToken = BEARER_PREFIX + responseRefreshToken.toString()
}

refreshTokenResponse.close()
val newRequest = originalRequest.newBuilder()
.addHeader(ACCESS_TOKEN, gpDataSource.accessToken)
.addHeader(REFRESH_TOKEN, gpDataSource.refreshToken)
.build()
return chain.proceed(newRequest)
} else {
with(context) {
CoroutineScope(Dispatchers.Main).launch {
startActivity(
Intent(this@with, SignActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
)
}
}
gpDataSource.clear()
}
}
}
return response
}

companion object {
const val ACCESS_TOKEN = "Authorization"
const val REFRESH_TOKEN = "Authorization-refresh"
const val BEARER_PREFIX = "Bearer "
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.geonppang.presentation.model

import com.sopt.geonppang.presentation.type.KeyWordType
import com.sopt.geonppang.presentation.type.LikeType

data class AmplitudeReviewWritingInfo(
val likeType: LikeType?,
val userKeyWordType: Map<KeyWordType, Boolean>,
val reviewText: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ class LogoutDialog : BindingDialogFragment<DialogMiddleBinding>(R.layout.dialog_
}

private fun addListeners() {
binding.btnDialogNo.setOnClickListener {
binding.btnDialogRight.setOnClickListener {
dismiss()
}

binding.btnDialogYes.setOnClickListener {
binding.btnDialogLeft.setOnClickListener {
when (viewModel.platformType) {
PlatformType.NONE.name -> {
viewModel.logout()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ class WithdrawDialog : BindingDialogFragment<DialogMiddleBinding>(R.layout.dialo
}

private fun addListeners() {
binding.btnDialogNo.setOnClickListener {
binding.btnDialogRight.setOnClickListener {
dismiss()
}

binding.btnDialogYes.setOnClickListener {
binding.btnDialogLeft.setOnClickListener {
when (viewModel.platformType) {
PlatformType.NONE.name -> {
viewModel.withdraw()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.view.View
import androidx.fragment.app.activityViewModels
import com.sopt.geonppang.R
import com.sopt.geonppang.databinding.DialogBottomReviewWritingCancelBinding
import com.sopt.geonppang.util.AmplitudeUtils
import com.sopt.geonppang.util.binding.BindingBottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint

Expand All @@ -22,11 +23,18 @@ class ReviewCancelBottomDialogFragment :

private fun addListeners() {
binding.btnContinue.setOnClickListener {
AmplitudeUtils.trackEvent(CLICK_REVIEW_WRITING_CONTINUE)
dismiss()
}

binding.btnStop.setOnClickListener {
AmplitudeUtils.trackEvent(CLICK_REVIEW_WRITING_STOP)
viewModel.setReviewCancelState(false)
}
}

companion object {
const val CLICK_REVIEW_WRITING_STOP = "click_reviewwrting_stop"
const val CLICK_REVIEW_WRITING_CONTINUE = "click_reviewwrting_continue"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package com.sopt.geonppang.presentation.reviewWriting

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import com.sopt.geonppang.R
import com.sopt.geonppang.databinding.DialogBottomReviewWritingSuccessBinding
import com.sopt.geonppang.util.binding.BindingBottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class ReviewSuccessBottomDialogFragment :
class ReviewSuccessBottomDialogFragment(
private val moveToDetail: () -> Unit
) :
BindingBottomSheetDialogFragment<DialogBottomReviewWritingSuccessBinding>(R.layout.dialog_bottom_review_writing_success) {
private val viewModel: ReviewWritingViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Expand All @@ -22,8 +22,8 @@ class ReviewSuccessBottomDialogFragment :

private fun addListeners() {
binding.btnReviewWritingSuccess.setOnClickListener {
viewModel.writeReview()
dismiss()
moveToDetail()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import com.sopt.geonppang.R
import com.sopt.geonppang.databinding.ActivityReviewWritingBinding
import com.sopt.geonppang.presentation.detail.DetailActivity
import com.sopt.geonppang.presentation.model.BakeryReviewWritingInfo
import com.sopt.geonppang.presentation.type.KeyWordType
import com.sopt.geonppang.presentation.type.LikeType
import com.sopt.geonppang.util.AmplitudeUtils
import com.sopt.geonppang.util.UiState
import com.sopt.geonppang.util.binding.BindingActivity
import com.sopt.geonppang.util.extension.hideKeyboard
Expand Down Expand Up @@ -47,32 +50,47 @@ class ReviewWritingActivity :

binding.etWriteYourReview.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
AmplitudeUtils.trackEvent(CLICK_REVIEW_WRITING_TEXT)
binding.layoutScrollView.smoothScrollTo(0, binding.etWriteYourReview.top)
}
}

binding.btnReviewSuccess.setOnClickListener {
showReviewSuccessDialog()
viewModel.writeReview()
}

binding.toolbar.ivBack.setOnClickListener {
AmplitudeUtils.trackEvent(CLICK_REVIEW_WRITING_BACK)
showReviewCancelDialog()
}

binding.layoutParent.setOnClickListener {
binding.etWriteYourReview.clearFocus()
hideKeyboard(it)
}

binding.layoutScrollViewConstraint.setOnClickListener {
binding.etWriteYourReview.clearFocus()
hideKeyboard(it)
}
}

private fun collectData() {
viewModel.reviewSuccessState.flowWithLifecycle(lifecycle).onEach {
when (it) {
viewModel.reviewSuccessState.flowWithLifecycle(lifecycle).onEach { uiState ->
when (uiState) {
is UiState.Success -> {
moveToDetail()
AmplitudeUtils.trackEvent(CLICK_REVIEW_WRITING_COMPLETE)
uiState.data.likeType?.let { likeType ->
AmplitudeUtils.trackEventWithMapProperties(
COMPLETE_REVIEW_WRITING,
mapOf(
OPTION to getStringByLikeType(likeType),
KEYWORD to getSelectedKeyWord(uiState.data.userKeyWordType),
TEXT to uiState.data.reviewText
)
)
}
showReviewSuccessDialog()
}

else -> {}
Expand All @@ -81,27 +99,70 @@ class ReviewWritingActivity :
viewModel.reviewCancelState.flowWithLifecycle(lifecycle).onEach { reviewCancelState ->
if (reviewCancelState == false) moveToDetail()
}.launchIn(lifecycleScope)
viewModel.isLike.flowWithLifecycle(lifecycle).onEach {
it?.let { likeType ->
AmplitudeUtils.trackEventWithProperties(
CLICK_REVIEW_WRITING_OPTION,
OPTION,
getStringByLikeType(likeType)
)
}
}.launchIn(lifecycleScope)
viewModel.userKeyWordType.flowWithLifecycle(lifecycle).onEach { keywordType ->
AmplitudeUtils.trackEventWithProperties(
CLICK_RECOMMEND_KEYWORD,
KEYWORD,
getSelectedKeyWord(keywordType)
)
}.launchIn(lifecycleScope)
}

private fun showReviewSuccessDialog() {
ReviewSuccessBottomDialogFragment().show(supportFragmentManager, "reviewSuccessDialog")
ReviewSuccessBottomDialogFragment(::moveToDetail).show(
supportFragmentManager,
REVIEW_SUCCESS_DIALOG
)
}

private fun showReviewCancelDialog() {
ReviewCancelBottomDialogFragment().show(supportFragmentManager, "reviewCancelDialog")
ReviewCancelBottomDialogFragment().show(supportFragmentManager, REVIEW_CANCEL_DIALOG)
}

private fun moveToDetail() {
val intent = Intent(this, DetailActivity::class.java)
viewModel.bakeryId.value?.let { id ->
viewModel.bakeryId.value.let { id ->
intent.putExtra(BAKERY_ID, id)
}
startActivity(intent)
finish()
}

private fun getStringByLikeType(likeType: LikeType): String {
return when (likeType) {
LikeType.LIKE -> LIKE
LikeType.BAD -> BAD
}
}

private fun getSelectedKeyWord(inputKeyWordType: Map<KeyWordType, Boolean>): List<String> {
return inputKeyWordType.entries.filter { it.value }.map { getString(it.key.keywordNameRes) }
}

companion object {
const val BAKERY_ID = "bakeryId"
const val BAKERY_INFO = "bakeryInfo"
const val REVIEW_SUCCESS_DIALOG = "reviewSuccessDialog"
const val REVIEW_CANCEL_DIALOG = "reviewCancelDialog"
const val LIKE = "좋았어요"
const val BAD = "아쉬웠어요"
const val CLICK_REVIEW_WRITING_OPTION = "click_reviewwriting_option"
const val CLICK_RECOMMEND_KEYWORD = "click_recommend_keyword"
const val CLICK_REVIEW_WRITING_TEXT = "click_reviewwritng_text"
const val CLICK_REVIEW_WRITING_BACK = "click_reviewwriting_back"
const val CLICK_REVIEW_WRITING_COMPLETE = "click_reviewwriting_complete"
const val COMPLETE_REVIEW_WRITING = "complete_reviewwriting"
const val OPTION = "option"
const val KEYWORD = "keyword"
const val TEXT = "text"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.geonppang.data.model.request.RequestReviewWriting
import com.sopt.geonppang.domain.repository.ReviewWritingRepository
import com.sopt.geonppang.presentation.model.AmplitudeReviewWritingInfo
import com.sopt.geonppang.presentation.model.BakeryReviewWritingInfo
import com.sopt.geonppang.presentation.type.KeyWordType
import com.sopt.geonppang.presentation.type.LikeType
Expand All @@ -29,7 +30,8 @@ class ReviewWritingViewModel @Inject constructor(private val reviewWritingReposi
val bakeryId get() = _bakeryId.asStateFlow()
private val _isLike = MutableStateFlow<LikeType?>(null)
val isLike get() = _isLike.asStateFlow()
private val _reviewSuccessState = MutableStateFlow<UiState<Boolean>>(UiState.Loading)
private val _reviewSuccessState =
MutableStateFlow<UiState<AmplitudeReviewWritingInfo>>(UiState.Loading)
val reviewSuccessState get() = _reviewSuccessState
private val _reviewCancelState = MutableStateFlow<Boolean?>(null)
val reviewCancelState get() = _reviewCancelState
Expand Down Expand Up @@ -78,7 +80,7 @@ class ReviewWritingViewModel @Inject constructor(private val reviewWritingReposi

private fun getKeyWordTypeList(): List<RequestReviewWriting.KeywordName> {
val trueKeyWordTypes = mutableListOf<RequestReviewWriting.KeywordName>()
userKeyWordType.value?.forEach { (keyWordType, value) ->
userKeyWordType.value.forEach { (keyWordType, value) ->
if (value) {
trueKeyWordTypes.add(RequestReviewWriting.KeywordName(keyWordType.keywordType))
}
Expand All @@ -92,8 +94,8 @@ class ReviewWritingViewModel @Inject constructor(private val reviewWritingReposi

fun writeReview() {
viewModelScope.launch {
reviewText.value?.let { reviewText ->
_bakeryId.value?.let {
reviewText.value.let { reviewText ->
_bakeryId.value.let {
reviewWritingRepository.writeReview(
it,
RequestReviewWriting(
Expand All @@ -103,7 +105,13 @@ class ReviewWritingViewModel @Inject constructor(private val reviewWritingReposi
)
)
.onSuccess {
_reviewSuccessState.value = UiState.Success(true)
_reviewSuccessState.value = UiState.Success(
AmplitudeReviewWritingInfo(
likeType = _isLike.value,
userKeyWordType = userKeyWordType.value,
reviewText = reviewText
)
)
}
.onFailure { throwable ->
_reviewSuccessState.value = UiState.Error(throwable.message)
Expand Down
Loading

0 comments on commit d346911

Please sign in to comment.