diff --git a/app/src/main/java/com/mongmong/namo/data/datasource/schedule/RemoteScheduleDataSource.kt b/app/src/main/java/com/mongmong/namo/data/datasource/schedule/RemoteScheduleDataSource.kt index 0f6a0573..e5b8387d 100644 --- a/app/src/main/java/com/mongmong/namo/data/datasource/schedule/RemoteScheduleDataSource.kt +++ b/app/src/main/java/com/mongmong/namo/data/datasource/schedule/RemoteScheduleDataSource.kt @@ -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 @@ -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 diff --git a/app/src/main/java/com/mongmong/namo/data/dto/MoimDTO.kt b/app/src/main/java/com/mongmong/namo/data/dto/MoimDTO.kt index f5c4a900..367fb2cf 100644 --- a/app/src/main/java/com/mongmong/namo/data/dto/MoimDTO.kt +++ b/app/src/main/java/com/mongmong/namo/data/dto/MoimDTO.kt @@ -92,4 +92,9 @@ data class EditMoimScheduleRequestBody( data class EditMoimScheduleProfileRequestBody( var title: String = "", var imageUrl: String = "" +) + +/** 모임 일정 참석자 초대 */ +data class InviteMoimParticipantRequestBody( + var memberIds: List ) \ No newline at end of file diff --git a/app/src/main/java/com/mongmong/namo/data/remote/MoimApiService.kt b/app/src/main/java/com/mongmong/namo/data/remote/MoimApiService.kt index b3561c61..78cd0a67 100644 --- a/app/src/main/java/com/mongmong/namo/data/remote/MoimApiService.kt +++ b/app/src/main/java/com/mongmong/namo/data/remote/MoimApiService.kt @@ -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 @@ -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( diff --git a/app/src/main/java/com/mongmong/namo/data/repositoriyImpl/ScheduleRepositoryImpl.kt b/app/src/main/java/com/mongmong/namo/data/repositoriyImpl/ScheduleRepositoryImpl.kt index 34de5794..17d3e79b 100644 --- a/app/src/main/java/com/mongmong/namo/data/repositoriyImpl/ScheduleRepositoryImpl.kt +++ b/app/src/main/java/com/mongmong/namo/data/repositoriyImpl/ScheduleRepositoryImpl.kt @@ -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 @@ -107,6 +108,16 @@ class ScheduleRepositoryImpl @Inject constructor( ).isSuccess } + override suspend fun inviteMoimParticipant( + moimScheduleId: Long, + memberIdsToInvite: List + ): Boolean { + return remoteScheduleDataSource.inviteMoimParticipant( + moimScheduleId, + InviteMoimParticipantRequestBody(memberIdsToInvite) + ).isSuccess + } + override suspend fun getGuestInvitaionLink(moimScheduleId: Long): String { return remoteScheduleDataSource.getGuestInvitationLink(moimScheduleId).result } diff --git a/app/src/main/java/com/mongmong/namo/domain/repositories/ScheduleRepository.kt b/app/src/main/java/com/mongmong/namo/domain/repositories/ScheduleRepository.kt index d713305b..7f00585d 100644 --- a/app/src/main/java/com/mongmong/namo/domain/repositories/ScheduleRepository.kt +++ b/app/src/main/java/com/mongmong/namo/domain/repositories/ScheduleRepository.kt @@ -65,6 +65,11 @@ interface ScheduleRepository { imageUrl: String ): Boolean + suspend fun inviteMoimParticipant( + moimScheduleId: Long, + memberIdsToInvite: List + ): Boolean + suspend fun getGuestInvitaionLink( moimScheduleId: Long ): String diff --git a/app/src/main/java/com/mongmong/namo/presentation/ui/common/ConfirmDialog.kt b/app/src/main/java/com/mongmong/namo/presentation/ui/common/ConfirmDialog.kt index 34da29ed..43959a41 100644 --- a/app/src/main/java/com/mongmong/namo/presentation/ui/common/ConfirmDialog.kt +++ b/app/src/main/java/com/mongmong/namo/presentation/ui/common/ConfirmDialog.kt @@ -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 { @@ -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) { diff --git a/app/src/main/java/com/mongmong/namo/presentation/ui/community/friend/FriendFragment.kt b/app/src/main/java/com/mongmong/namo/presentation/ui/community/friend/FriendFragment.kt index f614e147..25bd9a60 100644 --- a/app/src/main/java/com/mongmong/namo/presentation/ui/community/friend/FriendFragment.kt +++ b/app/src/main/java/com/mongmong/namo/presentation/ui/community/friend/FriendFragment.kt @@ -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 diff --git a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteActivity.kt b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteActivity.kt index a6d6e213..84015e0f 100644 --- a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteActivity.kt +++ b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteActivity.kt @@ -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(R.layout.activity_friend_invite) { +class FriendInviteActivity : BaseActivity(R.layout.activity_friend_invite), + ConfirmDialog.ConfirmDialogInterface { private val viewModel: FriendInviteViewModel by viewModels() @@ -22,6 +24,10 @@ class FriendInviteActivity : BaseActivity(R.layout. override fun setup() { binding.viewModel = viewModel + intent.getLongExtra(MOIM_INVITE_KEY, 0L).let { moimScheduleId -> + viewModel.moimScheduleId = moimScheduleId + } + initClickListeners() initObserve() } @@ -37,6 +43,11 @@ class FriendInviteActivity : BaseActivity(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) + } } // 초대한 친구 현황 표시용 @@ -104,5 +115,26 @@ class FriendInviteActivity : BaseActivity(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" } } \ No newline at end of file diff --git a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteViewModel.kt b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteViewModel.kt index 9f831750..35b53dd9 100644 --- a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteViewModel.kt +++ b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/FriendInviteViewModel.kt @@ -1,10 +1,12 @@ 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 @@ -12,8 +14,11 @@ 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>() val friendList: LiveData> = _friendList @@ -22,6 +27,10 @@ class FriendInviteViewModel @Inject constructor( private val _friendToInviteList = MutableLiveData>(ArrayList()) val friendToInviteList: LiveData> = _friendToInviteList + // API 호출 성공 여부 + private val _isSuccess = MutableLiveData() + var isSuccess: LiveData = _isSuccess + init { getFriends() } @@ -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() diff --git a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleActivity.kt b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleActivity.kt index 56d50e9d..e6f8c6f1 100644 --- a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleActivity.kt +++ b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleActivity.kt @@ -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 @@ -57,7 +59,6 @@ class MoimScheduleActivity : BaseActivity(R.layout. private var kakaoMap: KakaoMap? = null private lateinit var mapView: MapView - private lateinit var getMemberResult : ActivityResultLauncher private lateinit var participantAdapter: MoimParticipantRVAdapter private val viewModel : MoimScheduleViewModel by viewModels() @@ -68,7 +69,6 @@ class MoimScheduleActivity : BaseActivity(R.layout. initViews() initMapView() setResultLocation() - setResultMember() initClickListeners() initObserve() } @@ -115,7 +115,10 @@ class MoimScheduleActivity : BaseActivity(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) + ) } // 게스트 초대 버튼 클릭 (편집 모드) @@ -175,7 +178,7 @@ class MoimScheduleActivity : BaseActivity(R.layout. // 삭제 클릭 binding.moimScheduleDeleteBtn.setOnClickListener { // 삭제 확인 다이얼로그 띄우기 - showDialog() + showCustomDialog(getString(R.string.dialog_moim_delete_title), R.string.dialog_moim_delete_content, R.string.delete, 0) } } @@ -212,6 +215,7 @@ class MoimScheduleActivity : BaseActivity(R.layout. } viewModel.successState.observe(this) { successState -> + Log.e("MoimScheduleACT", "API 요청 성공 여부: ${successState.isSuccess}") if (successState.isSuccess) { // 요청이 성공한 경우 var message = "" message = when (successState.type) { @@ -220,8 +224,10 @@ class MoimScheduleActivity : BaseActivity(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() @@ -343,15 +349,6 @@ class MoimScheduleActivity : BaseActivity(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 { @@ -466,18 +463,19 @@ class MoimScheduleActivity : BaseActivity(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) + ) // 친구 초대 화면으로 이동 + } } } \ No newline at end of file diff --git a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleViewModel.kt b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleViewModel.kt index 1435bfbd..b10d4d68 100644 --- a/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleViewModel.kt +++ b/app/src/main/java/com/mongmong/namo/presentation/ui/community/moim/schedule/MoimScheduleViewModel.kt @@ -60,8 +60,6 @@ class MoimScheduleViewModel @Inject constructor( /** 모임 일정 생성 */ fun postMoimSchedule() { - //TODO: 친구 API 연동 후 삭제 - updateMembers(listOf(Participant(userId = 4))) // 참석자 선택 viewModelScope.launch { uploadImageToServer(_moimSchedule.value?.coverImg) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a7adfc5f..249e60a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -221,6 +221,8 @@ 게스트 초대 초대 링크 링크는 나모 어플을 설치하지 않은 게스트와 공유할 수 있습니다. 편집은 불가하며, 보기 권한이 주어집니다. + 초대를 확정하시겠습니까? + 초대한 이후에는 참석자를\n변경하실 수 없습니다. 닉네임 혹은 이름 입력