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

#33 / 초대장 보내기 받기 서버통신 구현 #69

Merged
merged 10 commits into from
Jul 19, 2023
12 changes: 7 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
android:name=".presentation.wish.WishActivity"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.UNIAOS.GrayStatusBar"/>
android:theme="@style/Theme.UNIAOS.GrayStatusBar"
android:windowSoftInputMode="adjustPan" />

<activity
android:name=".presentation.invite.NickNameActivity"
Expand All @@ -82,7 +82,8 @@
<activity
android:name=".presentation.invite.EnterInviteCodeActivity"
android:exported="false"
android:screenOrientation="portrait" />
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".presentation.shortgame.missiondetailcreate.MissionDetailCreateActivity"
android:exported="false"
Expand Down Expand Up @@ -120,9 +121,10 @@
android:name=".presentation.mypage.MypageSettingActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity android:name=".presentation.wish.WishFcActivity"
<activity
android:name=".presentation.wish.WishFcActivity"
android:exported="false"
android:screenOrientation="portrait"/>
android:screenOrientation="portrait" />

<activity
android:name=".presentation.shortgame.missionresult.MissionResultActivity"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package sopt.uni.data.repository.onboarding

import retrofit2.Response

interface OnBoardingRepository {

suspend fun patchNickName(nickname: String)

suspend fun postStartDate(startDate: String)
suspend fun postStartDate(startDate: String): String

suspend fun checkCoupleConnection(): Boolean

suspend fun postCheckConnection(inviteCode: String): Response<Unit>
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package sopt.uni.data.repository.onboarding

import retrofit2.Response
import sopt.uni.data.service.OnBoardingService
import sopt.uni.data.source.remote.request.RequestNickNameDto
import sopt.uni.data.source.remote.request.RequestPostCheckConnectionDto
import sopt.uni.data.source.remote.request.RequestStartDateDto
import javax.inject.Inject

Expand All @@ -13,7 +15,15 @@ class OnBoardingRepositoryImpl @Inject constructor(
onBoardingService.patchNickName(RequestNickNameDto(nickname))
}

override suspend fun postStartDate(startDate: String) {
onBoardingService.postStartDate(RequestStartDateDto(startDate))
override suspend fun postStartDate(startDate: String): String {
return onBoardingService.postStartDate(RequestStartDateDto(startDate)).inviteCode
}

override suspend fun checkCoupleConnection(): Boolean {
return onBoardingService.checkConnection().connection
}

override suspend fun postCheckConnection(inviteCode: String): Response<Unit> {
return onBoardingService.postCheckConnection(RequestPostCheckConnectionDto(inviteCode))
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/sopt/uni/data/service/OnBoardingService.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package sopt.uni.data.service

import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.PATCH
import retrofit2.http.POST
import sopt.uni.data.source.remote.request.RequestNickNameDto
import sopt.uni.data.source.remote.request.RequestPostCheckConnectionDto
import sopt.uni.data.source.remote.request.RequestStartDateDto
import sopt.uni.data.source.remote.response.ResponseCheckConnectionDto
import sopt.uni.data.source.remote.response.ResponseNickNameDto
import sopt.uni.data.source.remote.response.ResponseStartDateDto

Expand All @@ -19,4 +23,12 @@ interface OnBoardingService {
suspend fun postStartDate(
@Body request: RequestStartDateDto,
): ResponseStartDateDto

@GET("api/couple/join")
suspend fun checkConnection(): ResponseCheckConnectionDto

@POST("api/couple/join")
suspend fun postCheckConnection(
@Body request: RequestPostCheckConnectionDto,
): Response<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package sopt.uni.data.source.remote.request

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

@Serializable
data class RequestPostCheckConnectionDto(
@SerialName("inviteCode")
val inviteCode: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package sopt.uni.data.source.remote.response

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

@Serializable
data class ResponseCheckConnectionDto(
@SerialName("connection")
val connection: Boolean,
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package sopt.uni.presentation.common.content

const val MAX_LENGTH = 10
const val INVITECODE = "inviteCode"
Comment on lines 3 to +4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 내가 쓰는 const value 여기다가 빼야겠다.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헤헤 알아봐주셔서 감사합니다

18 changes: 14 additions & 4 deletions app/src/main/java/sopt/uni/presentation/invite/DdayActivity.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package sopt.uni.presentation.invite

import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import sopt.uni.R
import sopt.uni.databinding.ActivityDDayBinding
import sopt.uni.presentation.common.content.INVITECODE
import sopt.uni.util.DateUtil
import sopt.uni.util.binding.BindingActivity
import sopt.uni.util.extension.setOnSingleClickListener
import sopt.uni.util.extension.startActivity
import timber.log.Timber
import java.util.Calendar

@AndroidEntryPoint
Expand All @@ -30,9 +32,17 @@ class DdayActivity : BindingActivity<ActivityDDayBinding>(R.layout.activity_d_da
binding.dpDDay.dayOfMonth,
)
binding.btnNext.setOnSingleClickListener {
Timber.e(formatedDate)
dDayViewModel.postStartDate(formatedDate)
startActivity<ShareInviteCodeActivity>()
lifecycleScope.launch {
dDayViewModel.inviteCode.collect { inviteCode ->
if (inviteCode.isNotEmpty()) {
Intent(this@DdayActivity, ShareInviteCodeActivity::class.java).apply {
putExtra(INVITECODE, inviteCode)
startActivity(this)
}
}
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sopt.uni.presentation.invite
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import sopt.uni.data.repository.onboarding.OnBoardingRepository
import timber.log.Timber
Expand All @@ -13,11 +14,14 @@ class DdayViewModel @Inject constructor(
private val onBoardingRepository: OnBoardingRepository,
) : ViewModel() {

var inviteCode = MutableStateFlow("")

fun postStartDate(startDate: String) {
viewModelScope.launch {
kotlin.runCatching {
onBoardingRepository.postStartDate(startDate = startDate)
}.fold({
inviteCode.emit(it)
Timber.d("기념일 갱신이 완료되었습니다.")
}, {
Timber.d("기념일 갱신이 실패했습니다.")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
package sopt.uni.presentation.invite

import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import sopt.uni.R
import sopt.uni.databinding.ActivityEnterInviteCodeBinding
import sopt.uni.presentation.home.HomeActivity
import sopt.uni.util.binding.BindingActivity
import sopt.uni.util.extension.setOnSingleClickListener
import sopt.uni.util.extension.showToast
import sopt.uni.util.extension.startActivity

@AndroidEntryPoint
class EnterInviteCodeActivity :
BindingActivity<ActivityEnterInviteCodeBinding>(R.layout.activity_enter_invite_code) {
private val enterInviteCodeViewModel by viewModels<EnterInviteCodeViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)

binding.viewModel = enterInviteCodeViewModel
moveToPrevPage()
checkInviteCode()
changeBoxStrokeColor()
}

private fun moveToPrevPage() {
binding.ivBackArrow.setOnSingleClickListener {
finish()
}
}

private fun changeBoxStrokeColor() {
if (binding.etInviteCode.text.isNotBlank()) {
binding.etInviteCode.background = getDrawable(R.drawable.bg_mypage_edit_text)
}
}

private fun checkInviteCode() {
binding.btnConnect.setOnSingleClickListener {
enterInviteCodeViewModel.checkCoupleConnection()
lifecycleScope.launch {
enterInviteCodeViewModel.connectState.collect { responseCode ->
if (responseCode == "204") {
[email protected](getString(R.string.couple_connect_success))
binding.etInviteCode.background = getDrawable(R.drawable.bg_mypage_edit_text)
binding.tvInviteCodeErrorMessage.visibility = View.INVISIBLE
startActivity<HomeActivity>()
finishAffinity()
} else {
binding.etInviteCode.background =
getDrawable(R.drawable.bg_mypage_edit_text_error)
binding.tvInviteCodeErrorMessage.visibility = View.VISIBLE
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package sopt.uni.presentation.invite

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import sopt.uni.data.repository.onboarding.OnBoardingRepository
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class EnterInviteCodeViewModel @Inject constructor(
private val onBoardingRepository: OnBoardingRepository,
) : ViewModel() {

val inviteCode = MutableStateFlow("")
val connectState = MutableStateFlow("")

fun checkCoupleConnection() {
viewModelScope.launch {
kotlin.runCatching {
Timber.d("invite = ${inviteCode.value}")
onBoardingRepository.postCheckConnection(inviteCode = inviteCode.value)
}.fold({
connectState.emit(it.code().toString())
}, {
Timber.d(it)
})
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,72 @@
package sopt.uni.presentation.invite

import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import sopt.uni.R
import sopt.uni.databinding.ActivityShareInviteCodeBinding
import sopt.uni.presentation.common.content.INVITECODE
import sopt.uni.presentation.home.HomeActivity
import sopt.uni.util.binding.BindingActivity
import sopt.uni.util.extension.setOnSingleClickListener
import sopt.uni.util.extension.showSnackbar
import sopt.uni.util.extension.startActivity
import timber.log.Timber

@AndroidEntryPoint
class ShareInviteCodeActivity :
BindingActivity<ActivityShareInviteCodeBinding>(R.layout.activity_share_invite_code) {
private val shareInviteCodeViewModel by viewModels<ShareInviteCodeViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)

moveToPrevPage()
getInviteCode()
checkCoupleConnection()
copyInviteCode()
}

private fun getInviteCode() {
Timber.e(intent.getStringExtra(INVITECODE))
binding.tvInviteCode.text = intent.getStringExtra(INVITECODE)
}

private fun moveToPrevPage() {
binding.ivBackArrow.setOnSingleClickListener {
finish()
}
}

private fun checkCoupleConnection() {
binding.llCheckConnection.setOnSingleClickListener {
shareInviteCodeViewModel.checkCoupleConnection()
lifecycleScope.launch {
shareInviteCodeViewModel.isConnected.collect { isConnected ->
if (isConnected) {
startActivity<HomeActivity>()
finishAffinity()
} else {
showSnackbar(binding.root, getString(R.string.cannot_connect))
}
}
}
}
}

private fun copyInviteCode() {
binding.btnCopyInviteCode.setOnSingleClickListener {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, binding.tvInviteCode.text.toString())
type = "text/plain"
}

val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package sopt.uni.presentation.invite

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import sopt.uni.data.repository.onboarding.OnBoardingRepository
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class ShareInviteCodeViewModel @Inject constructor(
private val onBoardingRepository: OnBoardingRepository,
) : ViewModel() {
val isConnected = MutableStateFlow<Boolean>(false)

fun checkCoupleConnection() {
viewModelScope.launch {
kotlin.runCatching {
onBoardingRepository.checkCoupleConnection()
}.fold({
isConnected.emit(it)
}, {
Timber.d(it)
})
}
}
}
Loading
Loading