Skip to content

Commit

Permalink
[feat] #98 기존단체입장(초대코드) 그룹 단체 디테일 서버통신 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
Doreminwoo committed Jan 11, 2024
1 parent 0eeb106 commit 7ca7341
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.pingle.data.datasource.remote

import org.sopt.pingle.data.model.remote.response.ResponseJoinGroupInfoDto
import org.sopt.pingle.util.base.BaseResponse

interface JoinGroupCodeRemoteDataSource {
suspend fun getJoinGroupCodeInfo(teamId: Int): BaseResponse<ResponseJoinGroupInfoDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.pingle.data.datasourceimpl.remote

import org.sopt.pingle.data.datasource.remote.JoinGroupCodeRemoteDataSource
import org.sopt.pingle.data.model.remote.response.ResponseJoinGroupInfoDto
import org.sopt.pingle.data.service.JoinGroupService
import org.sopt.pingle.util.base.BaseResponse
import javax.inject.Inject

class JoinGroupCodeRemoteDataSourceImpl @Inject constructor(
private val joinGroupService: JoinGroupService
) : JoinGroupCodeRemoteDataSource {
override suspend fun getJoinGroupCodeInfo(teamId: Int): BaseResponse<ResponseJoinGroupInfoDto> =
joinGroupService.getJoinGroupDetail(teamId = teamId)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sopt.pingle.data.model.remote.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.sopt.pingle.domain.model.JoinGroupInfoEntity

@Serializable
data class ResponseJoinGroupInfoDto(
@SerialName("id")
val id: Int,
@SerialName("keyword")
val keyword: String,
@SerialName("name")
val name: String,
@SerialName("meetingCount")
val meetingCount: Int,
@SerialName("participantCount")
val participantCount: Int
) {
fun toJoinGroupCodeEntity() = JoinGroupInfoEntity(
id = this.id,
keyword = this.keyword,
name = this.name,
meetingCount = this.meetingCount,
participantCount = this.participantCount
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.pingle.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import org.sopt.pingle.data.datasource.remote.JoinGroupCodeRemoteDataSource
import org.sopt.pingle.domain.model.JoinGroupInfoEntity
import org.sopt.pingle.domain.repository.JoinGroupCodeRepository
import javax.inject.Inject

class JoinGroupCodeRepositoryImpl @Inject constructor(
private val joinGroupCodeRemoteDataSource: JoinGroupCodeRemoteDataSource
) : JoinGroupCodeRepository {
override fun getJoinGroupInfo(teamId: Int): Flow<JoinGroupInfoEntity> = flow {
val result = runCatching {
joinGroupCodeRemoteDataSource.getJoinGroupCodeInfo(teamId = teamId).data.toJoinGroupCodeEntity()
}
emit(result.getOrThrow())
}
}
19 changes: 19 additions & 0 deletions app/src/main/java/org/sopt/pingle/data/service/JoinGroupService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.pingle.data.service

import org.sopt.pingle.data.model.remote.response.ResponseJoinGroupInfoDto
import org.sopt.pingle.util.base.BaseResponse
import retrofit2.http.GET
import retrofit2.http.Path

interface JoinGroupService {
@GET("$VERSION/$TEAMS/{$TEAM_ID}")
suspend fun getJoinGroupDetail(
@Path("$TEAM_ID") teamId: Int
): BaseResponse<ResponseJoinGroupInfoDto>

companion object {
const val VERSION = "v1"
const val TEAMS = "teams"
const val TEAM_ID = "teamId"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.sopt.pingle.domain.model

data class JoinGroupCodeEntity(
data class JoinGroupInfoEntity(
val id: Int,
val keyword: String,
val name: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.pingle.domain.repository

import kotlinx.coroutines.flow.Flow
import org.sopt.pingle.domain.model.JoinGroupInfoEntity

interface JoinGroupCodeRepository {
fun getJoinGroupInfo(teamId: Int): Flow<JoinGroupInfoEntity>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.pingle.domain.usecase

import kotlinx.coroutines.flow.Flow
import org.sopt.pingle.domain.model.JoinGroupInfoEntity
import org.sopt.pingle.domain.repository.JoinGroupCodeRepository

class GetJoinGroupInfoUseCase(
private val joinGroupCodeRepository: JoinGroupCodeRepository
) {
operator fun invoke(teamId: Int): Flow<JoinGroupInfoEntity> =
joinGroupCodeRepository.getJoinGroupInfo(teamId = teamId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ package org.sopt.pingle.presentation.ui.joingroup
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.sopt.pingle.R
import org.sopt.pingle.databinding.ActivityJoinGroupCodeBinding
import org.sopt.pingle.util.base.BindingActivity
import org.sopt.pingle.util.view.UiState
import timber.log.Timber

@AndroidEntryPoint
class JoinGroupCodeActivity :
Expand All @@ -15,16 +21,25 @@ class JoinGroupCodeActivity :

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.joinViewModel = viewModel

initLayout()
addListeners()
addObservers()
collectData()
}

private fun initLayout() {
binding.joinViewModel = viewModel
viewModel.getJoinGroupInfo(TEAM_ID)
}

private fun addListeners() {
binding.btnJoinGroupCodeNext.setOnClickListener {
// TODO 초대코드 일치하지 않을 시
// CustomSnackbar.makeSnackbar(binding.root, getString(R.string.join_group_code_snackbar_message), 97)
// PingleSnackbar.makeSnackbar(
// binding.root,
// getString(R.string.join_group_code_snackbar_message),
// 97
// )
navigateToJoinGroupSuccess()
}

Expand All @@ -34,34 +49,52 @@ class JoinGroupCodeActivity :
}

private fun addObservers() {
viewModel.joinGroupData.observe(this) { joinGroupData ->
with(binding) {
tvJoinGroupCodeTag.text = joinGroupData.keyword
tvJoinGroupCodeGroupName.text = joinGroupData.name
tvJoinGroupCodeMeetingCount.text =
getString(R.string.join_group_code_meeting_count, joinGroupData.meetingCount)
tvJoinGroupCodeParticipantCount.text =
getString(
R.string.join_group_code_participant_count,
joinGroupData.participantCount
)
}
}

viewModel.joinGroupCode.observe(this) { editText ->
binding.btnJoinGroupCodeNext.isEnabled = editText.isNotEmpty()
}
}

private fun collectData() {
viewModel.joinGroupCodeUiState.flowWithLifecycle(lifecycle).onEach { uiState ->
when (uiState) {
is UiState.Success -> {
with(binding) {
tvJoinGroupCodeTag.text = uiState.data.keyword
tvJoinGroupCodeGroupName.text = uiState.data.name
tvJoinGroupCodeMeetingCount.text =
getString(
R.string.join_group_code_meeting_count,
uiState.data.meetingCount
)
tvJoinGroupCodeParticipantCount.text =
getString(
R.string.join_group_code_participant_count,
uiState.data.participantCount
)
}
}

is UiState.Error -> Timber.tag(JOIN_GROUP_CODE_ACTIVITY).d(uiState.message)

is UiState.Loading -> Timber.tag(JOIN_GROUP_CODE_ACTIVITY).d(LOADING)

is UiState.Empty -> Timber.tag(JOIN_GROUP_CODE_ACTIVITY).d(EMPTY)
}
}.launchIn(lifecycleScope)
}

private fun navigateToJoinGroupSuccess() {
Intent(this, JoinGroupSuccessActivity::class.java).apply {
// TODO 서버통신시 group name 가져와서 전달하기
putExtra(GROUP_NAME, viewModel.joinGroupData.value?.name)
putExtra(GROUP_NAME, binding.tvJoinGroupCodeGroupName.text)
startActivity(this)
}
}

companion object {
const val GROUP_NAME = "groupName"
const val TEAM_ID = 1
const val LOADING = "Loding"
const val EMPTY = "Empty"
const val JOIN_GROUP_CODE_ACTIVITY = "JoinGroupCodeActivity"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@ package org.sopt.pingle.presentation.ui.joingroup

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.sopt.pingle.domain.model.JoinGroupCodeEntity
import kotlinx.coroutines.launch
import org.sopt.pingle.domain.model.JoinGroupInfoEntity
import org.sopt.pingle.domain.model.JoinGroupSearchEntity
import org.sopt.pingle.domain.usecase.GetJoinGroupInfoUseCase
import org.sopt.pingle.util.view.UiState
import javax.inject.Inject

class JoinViewModel : ViewModel() {
private val _joinGroupData = MutableLiveData<JoinGroupCodeEntity>()
val joinGroupData get() = _joinGroupData
@HiltViewModel
class JoinViewModel @Inject constructor(
private val getJoinGroupInfoUseCase: GetJoinGroupInfoUseCase
) : ViewModel() {
private val _joinGroupCodeUiState =
MutableStateFlow<UiState<JoinGroupInfoEntity>>(UiState.Empty)
val joinGroupCodeUiState get() = _joinGroupCodeUiState.asStateFlow()

private var _isJoinGroupCodeBtn = MutableLiveData(false)
val isJoinGroupCodeBtn get() = _isJoinGroupCodeBtn
Expand All @@ -27,9 +37,7 @@ class JoinViewModel : ViewModel() {
private var oldPosition = DEFAULT_OLD_POSITION
fun updateJoinGroupSearchList(newPosition: Int) {
when (oldPosition) {
DEFAULT_OLD_POSITION -> {
setIsSelected(newPosition)
}
DEFAULT_OLD_POSITION -> setIsSelected(newPosition)

newPosition -> {
setIsSelected(newPosition)
Expand All @@ -52,16 +60,23 @@ class JoinViewModel : ViewModel() {
)
}

fun getJoinGroupInfo(teamId: Int) {
_joinGroupCodeUiState.value = UiState.Loading
viewModelScope.launch {
_joinGroupCodeUiState.value = UiState.Loading
runCatching {
getJoinGroupInfoUseCase.invoke(teamId = teamId).collect { joinGroupInfo ->
_joinGroupCodeUiState.value = UiState.Success(joinGroupInfo)
}
}.onFailure {
_joinGroupCodeUiState.value = UiState.Error(it.message)
}
}
}

private fun getIsSelected(position: Int) = _joinGroupSearchData.value[position].isSelected.get()

init {
_joinGroupData.value = JoinGroupCodeEntity(
id = 0,
keyword = "연합동아리",
name = "SOPT",
meetingCount = 10,
participantCount = 200
)

_joinGroupSearchData.value = listOf(
JoinGroupSearchEntity(
Expand Down

0 comments on commit 7ca7341

Please sign in to comment.