Skip to content

Commit

Permalink
✨ Feat: 친구 초대 API 연동
Browse files Browse the repository at this point in the history
Related to: #347
  • Loading branch information
nahy-512 committed Jan 8, 2025
1 parent 9de9293 commit 4d7f297
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.mongmong.namo.data.dto.GetMoimCalendarResponse
import com.mongmong.namo.data.dto.GetMoimDetailResponse
import com.mongmong.namo.data.dto.GetMoimDetailResult
import com.mongmong.namo.data.dto.GetMoimResponse
import com.mongmong.namo.data.dto.InviteMoimParticipantRequestBody
import com.mongmong.namo.data.dto.MoimBaseResponse
import com.mongmong.namo.data.dto.MoimScheduleRequestBody
import com.mongmong.namo.data.dto.PostMoimScheduleResponse
Expand Down Expand Up @@ -278,6 +279,25 @@ class RemoteScheduleDataSource @Inject constructor(
return scheduleResponse
}

// 모임 일정 참석자 초대
suspend fun inviteMoimParticipant(
moimScheduleId: Long,
request: InviteMoimParticipantRequestBody
): BaseResponse {
var scheduleResponse = BaseResponse()
withContext(Dispatchers.IO) {
runCatching {
moimApiService.inviteMoimParticipants(moimScheduleId, request)
}.onSuccess {
scheduleResponse = it
Log.d("RemoteScheduleDataSource", "inviteMoimParticipant Success $it")
}.onFailure {
Log.d("RemoteScheduleDataSource", "inviteMoimParticipant Failure $it")
}
}
return scheduleResponse
}

// 게스트 초대용 링크 조회
suspend fun getGuestInvitationLink(
moimScheduleId: Long
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/mongmong/namo/data/dto/MoimDTO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,9 @@ data class EditMoimScheduleRequestBody(
data class EditMoimScheduleProfileRequestBody(
var title: String = "",
var imageUrl: String = ""
)

/** 모임 일정 참석자 초대 */
data class InviteMoimParticipantRequestBody(
var memberIds: List<Long>
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.mongmong.namo.data.dto.EditMoimScheduleRequestBody
import com.mongmong.namo.data.dto.GetMoimCalendarResponse
import com.mongmong.namo.data.dto.GetMoimDetailResponse
import com.mongmong.namo.data.dto.GetMoimResponse
import com.mongmong.namo.data.dto.InviteMoimParticipantRequestBody
import com.mongmong.namo.data.dto.MoimBaseResponse
import com.mongmong.namo.data.dto.MoimScheduleRequestBody
import com.mongmong.namo.data.dto.PostMoimScheduleResponse
Expand Down Expand Up @@ -62,6 +63,13 @@ interface MoimApiService {
@Body body: EditMoimScheduleProfileRequestBody
): BaseResponse

// 모임 일정 참석자 초대
@POST("schedules/meeting/{meetingScheduleId}/invitations")
suspend fun inviteMoimParticipants(
@Path("meetingScheduleId") moimScheduleId: Long,
@Body body: InviteMoimParticipantRequestBody
): BaseResponse

// 게스트 초대용 링크 조회
@GET("schedules/meeting/{meetingScheduleId}/invitations")
suspend fun getGuestInvitationLink(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.mongmong.namo.data.repositoriyImpl
import android.util.Log
import com.mongmong.namo.data.datasource.schedule.RemoteScheduleDataSource
import com.mongmong.namo.data.dto.EditMoimScheduleProfileRequestBody
import com.mongmong.namo.data.dto.InviteMoimParticipantRequestBody
import com.mongmong.namo.domain.model.Schedule
import com.mongmong.namo.data.remote.NetworkChecker
import com.mongmong.namo.data.dto.PatchMoimScheduleAlarmRequestBody
Expand Down Expand Up @@ -107,6 +108,16 @@ class ScheduleRepositoryImpl @Inject constructor(
).isSuccess
}

override suspend fun inviteMoimParticipant(
moimScheduleId: Long,
memberIdsToInvite: List<Long>
): Boolean {
return remoteScheduleDataSource.inviteMoimParticipant(
moimScheduleId,
InviteMoimParticipantRequestBody(memberIdsToInvite)
).isSuccess
}

override suspend fun getGuestInvitaionLink(moimScheduleId: Long): String {
return remoteScheduleDataSource.getGuestInvitationLink(moimScheduleId).result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ interface ScheduleRepository {
imageUrl: String
): Boolean

suspend fun inviteMoimParticipant(
moimScheduleId: Long,
memberIdsToInvite: List<Long>
): Boolean

suspend fun getGuestInvitaionLink(
moimScheduleId: Long
): String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import com.mongmong.namo.R
import com.mongmong.namo.databinding.DialogConfirmBinding

class ConfirmDialog(
confirmDialogInterface: ConfirmDialogInterface,
title: String, content: String?, buttonText: String, id: Int
title: String, content: String?, buttonText: String?, id: Int
) : DialogFragment() {

interface ConfirmDialogInterface {
Expand Down Expand Up @@ -57,7 +58,9 @@ class ConfirmDialog(
binding.dialogDescTv.text = content
}
// 확인 버튼 텍스트
binding.dialogYesBtn.text = buttonText
if (buttonText != null) {
binding.dialogYesBtn.text = buttonText
}

// 취소 버튼이 없는 다이얼로그는 id를 -1로 넘겨줌
if (id == -1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.mongmong.namo.presentation.ui.community.friend

import android.util.Log
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.mongmong.namo.R
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.mongmong.namo.R
import com.mongmong.namo.databinding.ActivityFriendInviteBinding
import com.mongmong.namo.presentation.config.BaseActivity
import com.mongmong.namo.presentation.ui.common.ConfirmDialog
import com.mongmong.namo.presentation.ui.community.moim.schedule.adapter.FriendInvitePreparatoryRVAdapter
import com.mongmong.namo.presentation.ui.community.moim.schedule.adapter.FriendInviteRVAdapter
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class FriendInviteActivity : BaseActivity<ActivityFriendInviteBinding>(R.layout.activity_friend_invite) {
class FriendInviteActivity : BaseActivity<ActivityFriendInviteBinding>(R.layout.activity_friend_invite),
ConfirmDialog.ConfirmDialogInterface {

private val viewModel: FriendInviteViewModel by viewModels()

Expand All @@ -22,6 +24,10 @@ class FriendInviteActivity : BaseActivity<ActivityFriendInviteBinding>(R.layout.
override fun setup() {
binding.viewModel = viewModel

intent.getLongExtra(MOIM_INVITE_KEY, 0L).let { moimScheduleId ->
viewModel.moimScheduleId = moimScheduleId
}

initClickListeners()
initObserve()
}
Expand All @@ -37,6 +43,11 @@ class FriendInviteActivity : BaseActivity<ActivityFriendInviteBinding>(R.layout.
viewModel.resetAllSelectedFriend()
allFriendAdapter.resetAllSelectedFriend()
}

// 초대하기 버튼
binding.friendInviteBtn.setOnClickListener {
showCustomDialog(R.string.dialog_moim_schedule_invite_complete_title, R.string.dialog_moim_schedule_invite_complete_content, 0)
}
}

// 초대한 친구 현황 표시용
Expand Down Expand Up @@ -104,5 +115,26 @@ class FriendInviteActivity : BaseActivity<ActivityFriendInviteBinding>(R.layout.
allFriendAdapter.addFriend(it)
setFriendSelectedNum()
}

// API 호출 성공 여부
viewModel.isSuccess.observe(this) { isSuccess ->
if (isSuccess) {
finish()
}
}
}

private fun showCustomDialog(title: Int, content: Int, id: Int) {
val dialog = ConfirmDialog(this@FriendInviteActivity, getString(title), getString(content), null, id)
dialog.isCancelable = false
dialog.show(this.supportFragmentManager, "ConfirmDialog")
}

override fun onClickYesButton(id: Int) {
viewModel.inviteMoimParticipants() // 참석자 초대 진행
}

companion object {
const val MOIM_INVITE_KEY = "moim_invite_key"
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.mongmong.namo.presentation.ui.community.moim.schedule

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.mongmong.namo.domain.model.Friend
import com.mongmong.namo.domain.repositories.ScheduleRepository
import com.mongmong.namo.domain.usecases.friend.GetFriendsUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class FriendInviteViewModel @Inject constructor(
private val repository: ScheduleRepository,
private val getFriendsUseCase: GetFriendsUseCase,
): ViewModel() {
var moimScheduleId: Long = 0L

// 모든 친구 목록
private val _friendList = MutableLiveData<List<Friend>>()
val friendList: LiveData<List<Friend>> = _friendList
Expand All @@ -22,6 +27,10 @@ class FriendInviteViewModel @Inject constructor(
private val _friendToInviteList = MutableLiveData<ArrayList<Friend>>(ArrayList())
val friendToInviteList: LiveData<ArrayList<Friend>> = _friendToInviteList

// API 호출 성공 여부
private val _isSuccess = MutableLiveData<Boolean>()
var isSuccess: LiveData<Boolean> = _isSuccess

init {
getFriends()
}
Expand All @@ -33,6 +42,15 @@ class FriendInviteViewModel @Inject constructor(
}
}

/** 모임 일정 참석자 초대 */
fun inviteMoimParticipants() {
Log.d("FriendInviteVM", "moimScheduleId: $moimScheduleId")
if (moimScheduleId == 0L) return
viewModelScope.launch {
_isSuccess.value = repository.inviteMoimParticipant(moimScheduleId, _friendToInviteList.value!!.map { friend -> friend.userid })
}
}

// 초대할 친구 선택 초기화
fun resetAllSelectedFriend() {
_friendToInviteList.value = ArrayList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import com.mongmong.namo.presentation.ui.community.moim.schedule.adapter.MoimPar
import com.mongmong.namo.presentation.ui.home.schedule.map.MapActivity
import com.mongmong.namo.presentation.ui.common.ConfirmDialog
import com.mongmong.namo.presentation.ui.common.ConfirmDialog.ConfirmDialogInterface
import com.mongmong.namo.presentation.ui.community.moim.MoimFragment.Companion.MOIM_CREATE_KEY
import com.mongmong.namo.presentation.ui.community.moim.schedule.FriendInviteActivity.Companion.MOIM_INVITE_KEY
import com.mongmong.namo.presentation.utils.PermissionChecker.hasImagePermission
import com.mongmong.namo.presentation.utils.converter.PickerConverter.setSelectedTime
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -57,7 +59,6 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
private var kakaoMap: KakaoMap? = null
private lateinit var mapView: MapView

private lateinit var getMemberResult : ActivityResultLauncher<Intent>
private lateinit var participantAdapter: MoimParticipantRVAdapter

private val viewModel : MoimScheduleViewModel by viewModels()
Expand All @@ -68,7 +69,6 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
initViews()
initMapView()
setResultLocation()
setResultMember()
initClickListeners()
initObserve()
}
Expand Down Expand Up @@ -115,7 +115,10 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
// 친구 초대 버튼 클릭
binding.moimScheduleAddParticipantTv.setOnClickListener {
// 친구 추가하기 화면으로 이동
startActivity(Intent(this, FriendInviteActivity::class.java))
startActivity(
Intent(this, FriendInviteActivity::class.java)
.putExtra(MOIM_INVITE_KEY, viewModel.moimSchedule.value!!.moimId)
)
}

// 게스트 초대 버튼 클릭 (편집 모드)
Expand Down Expand Up @@ -175,7 +178,7 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
// 삭제 클릭
binding.moimScheduleDeleteBtn.setOnClickListener {
// 삭제 확인 다이얼로그 띄우기
showDialog()
showCustomDialog(getString(R.string.dialog_moim_delete_title), R.string.dialog_moim_delete_content, R.string.delete, 0)
}
}

Expand Down Expand Up @@ -212,6 +215,7 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
}

viewModel.successState.observe(this) { successState ->
Log.e("MoimScheduleACT", "API 요청 성공 여부: ${successState.isSuccess}")
if (successState.isSuccess) { // 요청이 성공한 경우
var message = ""
message = when (successState.type) {
Expand All @@ -220,8 +224,10 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
SuccessType.DELETE -> "모임 일정이 삭제되었습니다."
}
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
// 편집여부 전달 (업데이트)
val intent = Intent(this, MainActivity::class.java).apply {
putExtra(MOIM_EDIT_KEY, successState.isSuccess)
putExtra(MOIM_EDIT_KEY, successState.isSuccess) // 편집 여부
if (successState.type == SuccessType.ADD) putExtra(MOIM_CREATE_KEY, viewModel.moimSchedule.value?.title) // 친구 초대 팝업 표시용
}
setResult(Activity.RESULT_OK, intent)
finish()
Expand Down Expand Up @@ -343,15 +349,6 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
}
}

private fun setResultMember() {
getMemberResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
//TODO: 선택한 친구 넣기
// viewModel.updateMembers(result.data?.getSerializableExtra(GROUP_MEMBER_INTENT_KEY))
}
}
}

private fun setParticipantAdapter() {
participantAdapter = MoimParticipantRVAdapter(viewModel.moimSchedule.value!!.participants)
binding.moimScheduleParticipantRv.apply {
Expand Down Expand Up @@ -466,18 +463,19 @@ class MoimScheduleActivity : BaseActivity<ActivityMoimScheduleBinding>(R.layout.
kakaoMap?.labelManager?.layer?.addLabel(LabelOptions.from(latLng).setStyles(MapActivity.setPinStyle(false)))
}

private fun showDialog() {
// 탈퇴 확인 다이얼로그
val title = "모임 일정을 정말 삭제하시겠어요?"
val content = "삭제한 모임 일정은\n모든 참여자의 일정에서 삭제됩니다."

val dialog = ConfirmDialog(this@MoimScheduleActivity, title, content, "삭제", 0)
private fun showCustomDialog(title: String, content: Int, buttonText: Int, id: Int) {
val dialog = ConfirmDialog(this@MoimScheduleActivity, title, getString(content), getString(buttonText), id)
dialog.isCancelable = false
dialog.show(this.supportFragmentManager, "ConfirmDialog")
}

override fun onClickYesButton(id: Int) {
// 일정 삭제 진행
deleteSchedule()
when (id) {
0 -> deleteSchedule() // 일정 삭제 진행
1 -> startActivity(
Intent(this, FriendInviteActivity::class.java)
.putExtra(MOIM_INVITE_KEY, viewModel.moimSchedule.value!!.moimId)
) // 친구 초대 화면으로 이동
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ class MoimScheduleViewModel @Inject constructor(

/** 모임 일정 생성 */
fun postMoimSchedule() {
//TODO: 친구 API 연동 후 삭제
updateMembers(listOf(Participant(userId = 4))) // 참석자 선택
viewModelScope.launch {
uploadImageToServer(_moimSchedule.value?.coverImg)

Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@
<string name="moim_guest_invite">게스트 초대</string>
<string name="moim_guest_invite_link">초대 링크</string>
<string name="moim_guest_invite_notification">링크는 나모 어플을 설치하지 않은 게스트와 공유할 수 있습니다. 편집은 불가하며, 보기 권한이 주어집니다.</string>
<string name="dialog_moim_schedule_invite_complete_title">초대를 확정하시겠습니까?</string>
<string name="dialog_moim_schedule_invite_complete_content">초대한 이후에는 참석자를\n변경하실 수 없습니다.</string>

<!-- 친구 -->
<string name="friend_search_hint">닉네임 혹은 이름 입력</string>
Expand Down

0 comments on commit 4d7f297

Please sign in to comment.