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

[FEAT/#32] 모임 참여 확인 & 완료 구현 #40

Merged
merged 8 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
android:exported="false" />
<activity android:name=".presentation.group.search.SearchActivity"
android:exported="false" />
<activity android:name=".presentation.group.join.GroupMeetCheckActivity"
android:exported="false" />
<activity android:name=".presentation.group.join.GroupMeetCompleteActivity"
android:exported="false" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.teumteum.teumteum.presentation.group.join

import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.teumteum.base.BindingActivity
import com.teumteum.base.component.appbar.AppBarLayout
import com.teumteum.base.component.appbar.AppBarMenu
import com.teumteum.base.databinding.LayoutCommonAppbarBinding
import com.teumteum.base.util.extension.toast
import com.teumteum.teumteum.R
import com.teumteum.teumteum.databinding.ActivityGroupMeetCheckBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class GroupMeetCheckActivity :
BindingActivity<ActivityGroupMeetCheckBinding>(R.layout.activity_group_meet_check),
AppBarLayout {

private val viewModel by viewModels<GroupMeetCheckViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initEvent()
observe()
}

override val appBarBinding: LayoutCommonAppbarBinding
get() = binding.appBar

override fun initAppBarLayout() {
setAppBarHeight(48)

addMenuToLeft(
AppBarMenu.IconStyle(
resourceId = R.drawable.ic_arrow_left_l,
useRippleEffect = false,
clickEvent = null
)
)
}

private fun initEvent() {
binding.checkboxWaring.setOnCheckedChangeListener { _, isCheck ->
binding.btnJoin.isEnabled = isCheck
}

binding.btnJoin.setOnClickListener {
// TODO 해당 그룹에 아이디로 변경해야함
viewModel.joinGroup(0L)
}
}

private fun observe() {
viewModel.joinState.flowWithLifecycle(lifecycle)
.onEach {
when (it) {
is MeetCheckUiState.Success -> {
// TODO 모임 참여 완료 화면으로 이동
}
is MeetCheckUiState.Failure -> {
toast(it.msg)
}

else -> {}
}
}.launchIn(lifecycleScope)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.teumteum.teumteum.presentation.group.join

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.teumteum.domain.repository.GroupRepository
import com.teumteum.teumteum.util.custom.uistate.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

@HiltViewModel
class GroupMeetCheckViewModel @Inject constructor(
private val repository: GroupRepository
): ViewModel() {
private val _joinState = MutableStateFlow<MeetCheckUiState>(MeetCheckUiState.Init)
val joinState: StateFlow<MeetCheckUiState> = _joinState

fun joinGroup(meetingId: Long) {
viewModelScope.launch {
repository.postGroupJoin(meetingId)
.onSuccess {
_joinState.value = MeetCheckUiState.Success
}.onFailure {
_joinState.value = MeetCheckUiState.Failure("모임 참여 서버 통신 실패")
}
}
}
}

sealed interface MeetCheckUiState {
object Init: MeetCheckUiState
object Success: MeetCheckUiState
data class Failure(val msg: String): MeetCheckUiState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.teumteum.teumteum.presentation.group.join

import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.teumteum.base.BindingActivity
import com.teumteum.base.component.appbar.AppBarLayout
import com.teumteum.base.component.appbar.AppBarMenu
import com.teumteum.base.databinding.LayoutCommonAppbarBinding
import com.teumteum.base.util.extension.toast
import com.teumteum.teumteum.R
import com.teumteum.teumteum.databinding.ActivityGroupMeetCompleteBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class GroupMeetCompleteActivity :
BindingActivity<ActivityGroupMeetCompleteBinding>(R.layout.activity_group_meet_complete),
AppBarLayout {

private val viewModel by viewModels<GroupMeetCompleteViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initEvent()
observe()
}

override val appBarBinding: LayoutCommonAppbarBinding
get() = binding.appBar

override fun initAppBarLayout() {
setAppBarHeight(48)

addMenuToLeft(
AppBarMenu.IconStyle(
resourceId = R.drawable.ic_arrow_left_l,
useRippleEffect = false,
clickEvent = null
)
)
}

private fun observe() {
viewModel.cancelState.flowWithLifecycle(lifecycle)
.onEach {
when (it) {
is GroupMeetCancelUiState.Success -> {
// TODO 홈으로 가기 구현
}
is GroupMeetCancelUiState.Failure -> {
toast(it.msg)
}

else -> {}
}
}.launchIn(lifecycleScope)
}

private fun initEvent() {
binding.btnCancel.setOnClickListener {
// TODO 모임 ID 넣어야 함
viewModel.deleteJoinCancel(0L)
}

binding.btnHome.setOnClickListener {
// TODO 홈으로 가기 구현
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.teumteum.teumteum.presentation.group.join

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.teumteum.domain.repository.GroupRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

@HiltViewModel
class GroupMeetCompleteViewModel @Inject constructor(
private val repository: GroupRepository
): ViewModel() {
private val _cancelState = MutableStateFlow<GroupMeetCancelUiState>(GroupMeetCancelUiState.Init)
val cancelState: StateFlow<GroupMeetCancelUiState> = _cancelState

fun deleteJoinCancel(meetingId: Long) {
viewModelScope.launch {
repository.deleteGroupJoin(meetingId)
.onSuccess {
if (it) {
_cancelState.value = GroupMeetCancelUiState.Success
} else {
_cancelState.value = GroupMeetCancelUiState.Failure("모임 참여 신청 취소 서버 통신 실패")
}
}.onFailure {
_cancelState.value = GroupMeetCancelUiState.Failure("모임 참여 신청 취소 서버 통신 실패")
}
}
}
}

sealed interface GroupMeetCancelUiState {
object Init: GroupMeetCancelUiState
object Success: GroupMeetCancelUiState
data class Failure(val msg: String): GroupMeetCancelUiState
}
5 changes: 5 additions & 0 deletions app/src/main/res/color/selector_check_box_group.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/text_headline_primary" android:state_checked="true" />
<item android:color="@color/text_headline_teritary" android:state_checked="false" />
</selector>
19 changes: 19 additions & 0 deletions app/src/main/res/drawable-night/ic_check_box_default.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0h24v24h-24z"/>
<path
android:strokeWidth="1"
android:pathData="M12,12m-11.5,0a11.5,11.5 0,1 1,23 0a11.5,11.5 0,1 1,-23 0"
android:fillColor="#00000000"
android:strokeColor="#292929"/>
<path
android:pathData="M17.71,8.895L16.529,7.768L10.797,13.772L7.424,10.659L6.316,11.859L10.87,16.062L17.71,8.895Z"
android:fillColor="#333333"
android:fillType="evenOdd"/>
</group>
</vector>
19 changes: 19 additions & 0 deletions app/src/main/res/drawable/ic_check_box_default.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0h24v24h-24z"/>
<path
android:strokeWidth="1"
android:pathData="M12,12m-11.5,0a11.5,11.5 0,1 1,23 0a11.5,11.5 0,1 1,-23 0"
android:fillColor="#00000000"
android:strokeColor="#F0F0F0"/>
<path
android:pathData="M17.71,8.895L16.529,7.768L10.797,13.772L7.424,10.659L6.316,11.859L10.87,16.062L17.71,8.895Z"
android:fillColor="#DFDFDF"
android:fillType="evenOdd"/>
</group>
</vector>
17 changes: 17 additions & 0 deletions app/src/main/res/drawable/ic_check_box_select.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0h24v24h-24z"/>
<path
android:pathData="M12,12m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0"
android:fillColor="#36B2FF"/>
<path
android:pathData="M17.71,8.895L16.529,7.767L10.797,13.772L7.424,10.658L6.316,11.858L10.87,16.062L17.71,8.895Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</group>
</vector>
40 changes: 40 additions & 0 deletions app/src/main/res/drawable/ic_meet_complete.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="276dp"
android:height="102dp"
android:viewportWidth="276"
android:viewportHeight="102">
<path
android:pathData="M111,61C111,44.43 124.43,31 141,31C157.57,31 171,44.43 171,61C171,77.57 157.57,91 141,91C124.43,91 111,77.57 111,61ZM150.59,50.3C151.82,49.02 153.85,49.01 155.09,50.28C156.29,51.51 156.3,53.49 155.14,54.74L140.47,71.64C140.46,71.66 140.44,71.68 140.42,71.7C139.2,72.98 137.17,72.99 135.93,71.72L126.92,62.48C125.71,61.24 125.69,59.25 126.89,57.99C128.11,56.7 130.14,56.69 131.38,57.96L138.08,64.82L150.54,50.37C150.56,50.35 150.57,50.32 150.59,50.3Z"
android:fillColor="#44AEFF"
android:fillType="evenOdd"/>
<path
android:pathData="M257.22,98.84L266.94,91.14C266.94,91.14 256.51,86.5 255.03,82.63L246.58,89.48C246.58,89.48 249.3,96.54 257.22,98.84Z"
android:fillColor="#958FFF"/>
<path
android:pathData="M47.5,96.87L47.2,86.42C47.2,86.42 52.73,86.42 57.63,83.84L62.31,91.18C62.31,91.18 56.42,96.87 47.5,96.87Z"
android:fillColor="#A6FFEA"/>
<path
android:pathData="M254.49,16.31L255.49,7.04C255.49,7.04 261.23,6.72 266.86,4.31L270.14,13.71C270.14,13.71 261.63,16.37 254.49,16.31Z"
android:fillColor="#A0A4FB"/>
<path
android:pathData="M18.8,19.8L17.79,10.53C17.79,10.53 12.05,10.21 6.43,7.8L3.15,17.2C3.15,17.2 11.66,19.86 18.8,19.8Z"
android:fillColor="#837CFF"/>
<path
android:pathData="M217.05,40.79L222.4,34.46C222.4,34.46 215.35,30.96 214.46,28.19L207.03,32.87C207.03,32.87 210.79,39 217.05,40.79Z"
android:fillColor="#C8A0FB"/>
<path
android:pathData="M205.48,68.64L199.07,62.31C199.07,62.31 205.07,59.9 205.96,57.13L213.38,60.73C213.38,60.73 210.62,65.33 205.48,68.64Z"
android:fillColor="#A6FFEA"/>
<path
android:pathData="M19.06,75.53L12.65,69.2C12.65,69.2 18.65,66.78 19.54,64.02L26.96,67.62C26.96,67.62 24.2,72.22 19.06,75.53Z"
android:fillColor="#C8A0FB"/>
<path
android:pathData="M61.32,41.29L68.26,36.92C68.26,36.92 63.36,33.56 63.1,30.91L55.78,32.64C55.78,32.64 57.37,37.3 61.32,41.29Z"
android:fillColor="#7CE0FF"/>
<path
android:pathData="M91.71,15.08L85.42,20.26C85.42,20.26 86.51,26.65 92.8,29.07C92.8,29.07 91.59,27.53 91.71,15.08Z"
android:fillColor="#FFB7FD"/>
<path
android:pathData="M269.71,42L276,47.18C276,47.18 274.91,53.57 268.62,55.99C268.62,55.99 269.83,54.45 269.71,42Z"
android:fillColor="#FFB7FD"/>
</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/selector_check_box.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_check_box_select" android:state_checked="true" />
<item android:drawable="@drawable/ic_check_box_default" android:state_checked="false" />
</selector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/shape_elevation_level1_8dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/elevation_level01" />
<corners android:radius="8dp" />
</shape>
Loading