From af42cc3932e7a0e5d2b811a073c31e6c45f05cac Mon Sep 17 00:00:00 2001 From: murjune Date: Sat, 2 Sep 2023 18:17:02 +0900 Subject: [PATCH 01/10] #308 [feat] update Represent Rules api, usecase --- .../hous/release/data/datasource/RuleDataSource.kt | 6 ++++++ .../request/rule/UpdateRepresentRulesRequest.kt | 5 +++++ .../release/data/repository/RuleRepositoryImpl.kt | 4 ++++ .../java/hous/release/data/service/RuleService.kt | 6 ++++++ .../hous/release/domain/repository/RuleRepository.kt | 4 ++++ .../usecase/rule/UpdateRepresentRulesUseCase.kt | 12 ++++++++++++ 6 files changed, 37 insertions(+) create mode 100644 data/src/main/java/hous/release/data/entity/request/rule/UpdateRepresentRulesRequest.kt create mode 100644 domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt diff --git a/data/src/main/java/hous/release/data/datasource/RuleDataSource.kt b/data/src/main/java/hous/release/data/datasource/RuleDataSource.kt index 88268537..f63f6df8 100644 --- a/data/src/main/java/hous/release/data/datasource/RuleDataSource.kt +++ b/data/src/main/java/hous/release/data/datasource/RuleDataSource.kt @@ -1,6 +1,7 @@ package hous.release.data.datasource import hous.release.data.entity.request.rule.AddRulesRequest +import hous.release.data.entity.request.rule.UpdateRepresentRulesRequest import hous.release.data.entity.request.rule.UpdateRuleRequest import hous.release.data.entity.response.NoDataResponse import hous.release.data.entity.response.rule.DetailRuleResponse @@ -50,6 +51,11 @@ class RuleDataSource @Inject constructor(private val ruleService: RuleService) { ) } + suspend fun updateRepresentRules(rules: List): NoDataResponse = + ruleService.updateRepresentRules( + UpdateRepresentRulesRequest(rules) + ) + suspend fun deleteRule(ruleId: Int): NoDataResponse = ruleService.deleteRule(ruleId) } diff --git a/data/src/main/java/hous/release/data/entity/request/rule/UpdateRepresentRulesRequest.kt b/data/src/main/java/hous/release/data/entity/request/rule/UpdateRepresentRulesRequest.kt new file mode 100644 index 00000000..fa5c1732 --- /dev/null +++ b/data/src/main/java/hous/release/data/entity/request/rule/UpdateRepresentRulesRequest.kt @@ -0,0 +1,5 @@ +package hous.release.data.entity.request.rule + +data class UpdateRepresentRulesRequest( + val rules: List = emptyList() +) diff --git a/data/src/main/java/hous/release/data/repository/RuleRepositoryImpl.kt b/data/src/main/java/hous/release/data/repository/RuleRepositoryImpl.kt index 64d61f8e..3753f77f 100644 --- a/data/src/main/java/hous/release/data/repository/RuleRepositoryImpl.kt +++ b/data/src/main/java/hous/release/data/repository/RuleRepositoryImpl.kt @@ -53,6 +53,10 @@ class RuleRepositoryImpl @Inject constructor( ) } + override suspend fun updateRepresentRules(rules: List) { + ruleDataSource.updateRepresentRules(rules) + } + override suspend fun deleteRule(ruleId: Int) { ruleDataSource.deleteRule(ruleId) } diff --git a/data/src/main/java/hous/release/data/service/RuleService.kt b/data/src/main/java/hous/release/data/service/RuleService.kt index 1180c6d9..24e421e8 100644 --- a/data/src/main/java/hous/release/data/service/RuleService.kt +++ b/data/src/main/java/hous/release/data/service/RuleService.kt @@ -1,5 +1,6 @@ package hous.release.data.service +import hous.release.data.entity.request.rule.UpdateRepresentRulesRequest import hous.release.data.entity.response.BaseResponse import hous.release.data.entity.response.NoDataResponse import hous.release.data.entity.response.rule.CanAddRuleResponse @@ -55,6 +56,11 @@ interface RuleService { @Query("name") name: String ): NoDataResponse + @PUT("/v1/rules/represent") + suspend fun updateRepresentRules( + req: UpdateRepresentRulesRequest + ): NoDataResponse + @HTTP(method = "DELETE", path = "/v2/rule/{id}") suspend fun deleteRule(@Path("id") ruleId: Int): NoDataResponse } diff --git a/domain/src/main/java/hous/release/domain/repository/RuleRepository.kt b/domain/src/main/java/hous/release/domain/repository/RuleRepository.kt index 1b45e50a..27fe7879 100644 --- a/domain/src/main/java/hous/release/domain/repository/RuleRepository.kt +++ b/domain/src/main/java/hous/release/domain/repository/RuleRepository.kt @@ -22,5 +22,9 @@ interface RuleRepository { imageFiles: List ) + suspend fun updateRepresentRules( + rules: List + ) + suspend fun deleteRule(ruleId: Int) } diff --git a/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt b/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt new file mode 100644 index 00000000..01300a8c --- /dev/null +++ b/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt @@ -0,0 +1,12 @@ +package hous.release.domain.usecase.rule + +import hous.release.domain.repository.RuleRepository +import javax.inject.Inject + +class UpdateRepresentRulesUseCase @Inject constructor( + private val ruleRepository: RuleRepository +) { + suspend operator fun invoke(rules: List) { + ruleRepository.updateRepresentRules(rules) + } +} \ No newline at end of file From 6de1ab89b26f7de57efee7ba70fc9b5124f7d2ef Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:03:08 +0900 Subject: [PATCH 02/10] =?UTF-8?q?#308=20[add]=20=EB=8C=80=ED=91=9C=20?= =?UTF-8?q?=EB=A3=B0=20string=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5a1f064d..71a24949 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - + Hous- @@ -106,7 +106,8 @@ 아직 우리 집 Rules가 없어요! 다른 Rule도 추가해보세요! 똑같은 이름의 Rule이 있어요! - 사진은 5개까지만 추가할 수 있어요! + 사진은 5개 까지만 추가할 수 있어요! + 대표 rule 은 3개 까지만 추가할 수 있어요! Rules 개수 초과 우리 집 rule이 너무 많아요!\n필요하지 않은 rule을 삭제하고\n다시 시도해주세요~ 아직 우리 집 Rules가 없어요! From bfa7b45634119742ab8f1c1cef46d57538a1aebf Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:03:46 +0900 Subject: [PATCH 03/10] =?UTF-8?q?#308=20[feat]=20=EB=8C=80=ED=91=9C=20?= =?UTF-8?q?=EB=A3=B0=20Reducer,=20viewModel=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hous/release/android/di/ReducerModule.kt | 11 ++ .../our_rules/event/RepresentRulesReducer.kt | 33 ++++++ .../viewmodel/RepresentRuleViewModel.kt | 105 ++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 app/src/main/java/hous/release/android/presentation/our_rules/event/RepresentRulesReducer.kt create mode 100644 app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt diff --git a/app/src/main/java/hous/release/android/di/ReducerModule.kt b/app/src/main/java/hous/release/android/di/ReducerModule.kt index f2ba9c99..f6608b14 100644 --- a/app/src/main/java/hous/release/android/di/ReducerModule.kt +++ b/app/src/main/java/hous/release/android/di/ReducerModule.kt @@ -6,11 +6,14 @@ import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityRetainedComponent import hous.release.android.presentation.our_rules.event.AddRuleReducer import hous.release.android.presentation.our_rules.event.MainRuleReducer +import hous.release.android.presentation.our_rules.event.RepresentRulesReducer import hous.release.android.presentation.our_rules.event.UpdateRuleReducer import hous.release.android.presentation.our_rules.viewmodel.AddRuleEvent import hous.release.android.presentation.our_rules.viewmodel.AddRuleState import hous.release.android.presentation.our_rules.viewmodel.MainRulesEvent import hous.release.android.presentation.our_rules.viewmodel.MainRulesState +import hous.release.android.presentation.our_rules.viewmodel.RepresentRulesEvent +import hous.release.android.presentation.our_rules.viewmodel.RepresentRulesState import hous.release.android.presentation.our_rules.viewmodel.UpdateRuleEvent import hous.release.android.presentation.our_rules.viewmodel.UpdateRuleState import hous.release.android.util.event.Reducer @@ -30,8 +33,16 @@ abstract class ReducerModule { @UpdateRule @Binds abstract fun bindUpdateRuleReducer(updateRuleReducer: UpdateRuleReducer): Reducer + + @RepresentRules + @Binds + abstract fun bindRepresentRulesReducer(representRulesReducer: RepresentRulesReducer): Reducer } +@Retention(AnnotationRetention.BINARY) +@Qualifier +annotation class RepresentRules + @Retention(AnnotationRetention.BINARY) @Qualifier annotation class MainRules diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/event/RepresentRulesReducer.kt b/app/src/main/java/hous/release/android/presentation/our_rules/event/RepresentRulesReducer.kt new file mode 100644 index 00000000..17c89955 --- /dev/null +++ b/app/src/main/java/hous/release/android/presentation/our_rules/event/RepresentRulesReducer.kt @@ -0,0 +1,33 @@ +package hous.release.android.presentation.our_rules.event + +import hous.release.android.presentation.our_rules.model.RepresentRuleUiModel +import hous.release.android.presentation.our_rules.viewmodel.RepresentRulesEvent +import hous.release.android.presentation.our_rules.viewmodel.RepresentRulesState +import hous.release.android.util.event.Reducer +import javax.inject.Inject + +class RepresentRulesReducer @Inject constructor() : + Reducer { + override fun dispatch( + state: RepresentRulesState, + event: RepresentRulesEvent + ): RepresentRulesState { + return when (event) { + is RepresentRulesEvent.FetchRules -> { + state.copy( + originRules = event.rules.map { RepresentRuleUiModel.from(it) }, + rules = event.rules.map { RepresentRuleUiModel.from(it) } + ) + } + + is RepresentRulesEvent.UpdateRule -> { + state.copy( + rules = state.rules.map { rule -> + if (rule.id == event.id) rule.copy(isRepresent = rule.isRepresent.not()) + else rule + } + ) + } + } + } +} diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt b/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt new file mode 100644 index 00000000..d7ce84c7 --- /dev/null +++ b/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt @@ -0,0 +1,105 @@ +package hous.release.android.presentation.our_rules.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import hous.release.android.di.RepresentRules +import hous.release.android.presentation.our_rules.model.RepresentRuleUiModel +import hous.release.android.util.event.Reducer +import hous.release.domain.entity.rule.Rule +import hous.release.domain.usecase.rule.GetRulesUseCase +import hous.release.domain.usecase.rule.UpdateRepresentRulesUseCase +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.runningFold +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch +import retrofit2.HttpException +import timber.log.Timber +import javax.inject.Inject + +@HiltViewModel +class RepresentRuleViewModel @Inject constructor( + private val updateRepresentRulesUseCase: UpdateRepresentRulesUseCase, + private val getRulesUseCase: GetRulesUseCase, + @RepresentRules private val reducer: Reducer +) : ViewModel() { + + private val uiEvents = Channel() + val uiState: StateFlow = uiEvents + .receiveAsFlow() + .runningFold(RepresentRulesState(), reducer::dispatch) + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), RepresentRulesState()) + + private val _sideEffect: Channel = Channel() + val sideEffect = _sideEffect.receiveAsFlow() + + init { + viewModelScope.launch { + val rules = getRulesUseCase() + uiEvents.send(RepresentRulesEvent.FetchRules(rules)) + } + } + + val isSavable get() = uiState.value.rules == uiState.value.originRules + + fun updateRuleBy(id: Int) { + viewModelScope.launch { + if (canAddRepresentRule()) { + uiEvents.send(RepresentRulesEvent.UpdateRule(id)) + return@launch + } + _sideEffect.send(RepresentRulesSideEffect.ShowLimitRulesToast) + } + } + + fun saveRules() { + viewModelScope.launch { + _sideEffect.send(RepresentRulesSideEffect.LoadingBar(true)) + runCatching { + updateRepresentRulesUseCase( + uiState.value.rules.filter { it.isRepresent } + .map { it.id } + ) + }.onSuccess { + _sideEffect.send(RepresentRulesSideEffect.LoadingBar(false)) + _sideEffect.send(RepresentRulesSideEffect.PopBackStack) + }.onFailure { e -> + Timber.e("updateRule() - onFailure() - e: ${e.stackTraceToString()}") + if (e is HttpException) { + when (e.code()) { + LIMIT_RULES_CODE -> _sideEffect.send(RepresentRulesSideEffect.ShowLimitRulesToast) + } + } + _sideEffect.send(RepresentRulesSideEffect.LoadingBar(false)) + } + } + } + + private fun canAddRepresentRule(): Boolean { + return uiState.value.rules.filter { it.isRepresent }.size < 3 + } + + private companion object { + const val LIMIT_RULES_CODE = 403 + } +} + +sealed class RepresentRulesSideEffect { + object IDLE : RepresentRulesSideEffect() + data class LoadingBar(val isLoading: Boolean) : RepresentRulesSideEffect() + object ShowLimitRulesToast : RepresentRulesSideEffect() + object PopBackStack : RepresentRulesSideEffect() +} + +data class RepresentRulesState( + val originRules: List = emptyList(), + val rules: List = emptyList() +) + +sealed class RepresentRulesEvent { + data class FetchRules(val rules: List) : RepresentRulesEvent() + data class UpdateRule(val id: Int) : RepresentRulesEvent() +} From 68b72c01a28caaaff440a5613a76621675b6d029 Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:04:29 +0900 Subject: [PATCH 04/10] =?UTF-8?q?#308=20[feat]=20RuleScreen=20SideEffect,?= =?UTF-8?q?=20Effect=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../our_rules/graph/RuleNavGraph.kt | 67 ++++++++++++++++++- .../our_rules/screen/RepresentRuleScreen.kt | 8 +-- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/graph/RuleNavGraph.kt b/app/src/main/java/hous/release/android/presentation/our_rules/graph/RuleNavGraph.kt index 41a59888..b9e25f63 100644 --- a/app/src/main/java/hous/release/android/presentation/our_rules/graph/RuleNavGraph.kt +++ b/app/src/main/java/hous/release/android/presentation/our_rules/graph/RuleNavGraph.kt @@ -27,12 +27,15 @@ import hous.release.android.presentation.our_rules.component.dialog.UpdateRuleOu import hous.release.android.presentation.our_rules.model.DetailRuleUiModel import hous.release.android.presentation.our_rules.screen.AddRuleScreen import hous.release.android.presentation.our_rules.screen.MainRuleScreen +import hous.release.android.presentation.our_rules.screen.RepresentRuleScreen import hous.release.android.presentation.our_rules.screen.UpdateRuleScreen import hous.release.android.presentation.our_rules.screen.type.RulesScreens import hous.release.android.presentation.our_rules.viewmodel.AddRuleSideEffect import hous.release.android.presentation.our_rules.viewmodel.AddRuleViewModel import hous.release.android.presentation.our_rules.viewmodel.MainRuleSideEffect import hous.release.android.presentation.our_rules.viewmodel.MainRuleViewModel +import hous.release.android.presentation.our_rules.viewmodel.RepresentRuleViewModel +import hous.release.android.presentation.our_rules.viewmodel.RepresentRulesSideEffect import hous.release.android.presentation.our_rules.viewmodel.UpdateRuleSideEffect import hous.release.android.presentation.our_rules.viewmodel.UpdateRuleViewModel import hous.release.android.presentation.practice.findActivity @@ -105,7 +108,7 @@ private fun NavGraphBuilder.mainRuleScreen( onNavigateToRepresentRule = navController::navigateToRepresentRule, onFinish = activity::finish, refresh = viewModel::fetchMainRules, - deleteRule = viewModel::deleteRule, + deleteRule = viewModel::deleteRule ) } } @@ -305,10 +308,70 @@ private fun NavGraphBuilder.addRuleScreen(onBack: () -> Unit) { } } +@OptIn(ExperimentalLifecycleComposeApi::class) private fun NavGraphBuilder.representativeRuleScreen(onBack: () -> Unit) { composable(RulesScreens.Represent.route) { + val viewModel = hiltViewModel() + val uiState = viewModel.uiState.collectAsStateWithLifecycle() + var isLoading by remember { mutableStateOf(false) } + var isOutDialogShow by remember { mutableStateOf(false) } + + val context = LocalContext.current + + LaunchedEffect(Unit) { + viewModel.sideEffect.collect { event -> + when (event) { + is RepresentRulesSideEffect.IDLE -> Unit + + is RepresentRulesSideEffect.ShowLimitRulesToast -> { + ToastMessageUtil.showToast( + context, + context.getString(R.string.our_rule_limit_represent_rules_count) + ) + } + + is RepresentRulesSideEffect.LoadingBar -> { + isLoading = event.isLoading + } + + is RepresentRulesSideEffect.PopBackStack -> { + onBack() + } + } + } + } + + val onBackPressed = { + if (viewModel.isSavable) { + isOutDialogShow = true + } else { + onBack() + } + } + + BackHandler(viewModel.isSavable, onBackPressed) + if (isLoading) LoadingBar() + if (isOutDialogShow) { + UpdateRuleOutDialog( + onConfirm = { + isOutDialogShow = false + onBack() + }, + onDismiss = { + isOutDialogShow = false + } + ) + } + RepresentRuleScreen( + rules = uiState.value.rules, + onBack = onBackPressed, + onUpdateRule = viewModel::updateRuleBy, + isSavable = viewModel::isSavable, + onSave = viewModel::saveRules + ) } } + // Navigation fun NavController.navigateToAddRule() { navigate(RulesScreens.Add.route) @@ -324,4 +387,4 @@ fun NavController.navigateUpdateRule(detailRuleUiModel: DetailRuleUiModel) { fun NavController.navigateToRepresentRule() { navigate(RulesScreens.Represent.route) -} \ No newline at end of file +} diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/screen/RepresentRuleScreen.kt b/app/src/main/java/hous/release/android/presentation/our_rules/screen/RepresentRuleScreen.kt index ef47c5d3..3cc4a455 100644 --- a/app/src/main/java/hous/release/android/presentation/our_rules/screen/RepresentRuleScreen.kt +++ b/app/src/main/java/hous/release/android/presentation/our_rules/screen/RepresentRuleScreen.kt @@ -20,10 +20,10 @@ import hous.release.domain.entity.rule.Rule @Composable fun RepresentRuleScreen( rules: List = emptyList(), - isChanged: Boolean = false, + isSavable: () -> Boolean = { false }, onSave: () -> Unit = {}, onBack: () -> Unit = {}, - onRuleClick: (Int) -> Unit = {} + onUpdateRule: (Int) -> Unit = {} ) { Column( modifier = Modifier.fillMaxSize() @@ -31,7 +31,7 @@ fun RepresentRuleScreen( RuleToolbar( title = stringResource(id = R.string.our_rule_represent_rule_title), trailingTitle = stringResource(id = R.string.our_rule_save_new_rule), - isButtonActive = isChanged, + isButtonActive = isSavable(), onBack = onBack, onAddButton = onSave ) @@ -39,7 +39,7 @@ fun RepresentRuleScreen( RepresentRuleList( modifier = Modifier.padding(horizontal = 16.dp), rules = rules, - onClick = onRuleClick + onClick = onUpdateRule ) } } From 190a1b6f5bf38733f45f631afaa6eee03ef44cae Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:40:12 +0900 Subject: [PATCH 05/10] =?UTF-8?q?#308=20[fix]=20=EB=8C=80=ED=91=9C?= =?UTF-8?q?=EB=A3=B0=20=EC=88=98=EC=A0=95=20@Body=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/src/main/java/hous/release/data/service/RuleService.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/hous/release/data/service/RuleService.kt b/data/src/main/java/hous/release/data/service/RuleService.kt index 24e421e8..ac77758a 100644 --- a/data/src/main/java/hous/release/data/service/RuleService.kt +++ b/data/src/main/java/hous/release/data/service/RuleService.kt @@ -7,6 +7,7 @@ import hous.release.data.entity.response.rule.CanAddRuleResponse import hous.release.data.entity.response.rule.DetailRuleResponse import hous.release.data.entity.response.rule.RulesResponse import okhttp3.MultipartBody +import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.HTTP import retrofit2.http.Multipart @@ -58,7 +59,7 @@ interface RuleService { @PUT("/v1/rules/represent") suspend fun updateRepresentRules( - req: UpdateRepresentRulesRequest + @Body req: UpdateRepresentRulesRequest ): NoDataResponse @HTTP(method = "DELETE", path = "/v2/rule/{id}") From 88980e5315de00c4520022043b6d77084f4ff521 Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:41:02 +0900 Subject: [PATCH 06/10] =?UTF-8?q?#308=20[fix]=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5,=20=EB=8C=80=ED=91=9C=20=EB=A3=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../our_rules/viewmodel/RepresentRuleViewModel.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt b/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt index d7ce84c7..0ac2c89f 100644 --- a/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt +++ b/app/src/main/java/hous/release/android/presentation/our_rules/viewmodel/RepresentRuleViewModel.kt @@ -43,11 +43,11 @@ class RepresentRuleViewModel @Inject constructor( } } - val isSavable get() = uiState.value.rules == uiState.value.originRules + val isSavable get() = uiState.value.rules != uiState.value.originRules fun updateRuleBy(id: Int) { viewModelScope.launch { - if (canAddRepresentRule()) { + if (canUpdateRuleBy(id)) { uiEvents.send(RepresentRulesEvent.UpdateRule(id)) return@launch } @@ -78,8 +78,10 @@ class RepresentRuleViewModel @Inject constructor( } } - private fun canAddRepresentRule(): Boolean { - return uiState.value.rules.filter { it.isRepresent }.size < 3 + private fun canUpdateRuleBy(id: Int): Boolean { + val isRepresent = uiState.value.rules.find { it.id == id }?.isRepresent ?: false + if (isRepresent) return true + return uiState.value.rules.count { it.isRepresent } + 1 <= 3 } private companion object { From 407b8d007f216b913c5c9def922f983303994a2f Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:49:01 +0900 Subject: [PATCH 07/10] #308 [fix] HousDot --- .../main/java/hous/release/designsystem/component/HousDot.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/designsystem/src/main/java/hous/release/designsystem/component/HousDot.kt b/designsystem/src/main/java/hous/release/designsystem/component/HousDot.kt index e4483aa5..71176b16 100644 --- a/designsystem/src/main/java/hous/release/designsystem/component/HousDot.kt +++ b/designsystem/src/main/java/hous/release/designsystem/component/HousDot.kt @@ -23,8 +23,8 @@ enum class HousDotType { companion object { fun from(isNew: Boolean = false, isRepresent: Boolean = false): HousDotType { return when { - isNew -> NEW isRepresent -> REPRESENTATIVE + isNew -> NEW else -> NORMAL } } @@ -70,6 +70,6 @@ private fun HousDashPreview2() { @Composable private fun HousDashPreview3() { HousTheme { - HousDot(HousDotType.from(isRepresent = true)) + HousDot(HousDotType.from(isRepresent = true, isNew = true)) } } From db58146c82d7b4c58c753881fe8f470c2a978d82 Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 17:49:26 +0900 Subject: [PATCH 08/10] =?UTF-8?q?#308=20[ui]=20MainRuleList=20Preview=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../our_rules/component/main/MainRuleList.kt | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/component/main/MainRuleList.kt b/app/src/main/java/hous/release/android/presentation/our_rules/component/main/MainRuleList.kt index bdaa37d5..f18cfc32 100644 --- a/app/src/main/java/hous/release/android/presentation/our_rules/component/main/MainRuleList.kt +++ b/app/src/main/java/hous/release/android/presentation/our_rules/component/main/MainRuleList.kt @@ -97,9 +97,9 @@ private fun MainRuleContentPreview() { } } -@Preview(name = "main rule Item", showBackground = true) +@Preview(name = "general rule Item", showBackground = true) @Composable -private fun MainRulePreview() { +private fun Preview1() { HousTheme { Surface { MainRuleItem() @@ -107,9 +107,21 @@ private fun MainRulePreview() { } } -@Preview(name = "new main rule Item", showBackground = true) +@Preview(name = "Represent rule Item", showBackground = true) @Composable -private fun NewMainRulePreview() { +private fun Preview2() { + HousTheme { + Surface { + MainRuleItem( + mainRule = Rule().copy(isRepresent = true) + ) + } + } +} + +@Preview(name = "new rule Item", showBackground = true) +@Composable +private fun Preview3() { HousTheme { Surface { MainRuleItem( @@ -118,3 +130,15 @@ private fun NewMainRulePreview() { } } } + +@Preview(name = "Represent and New rule Item", showBackground = true) +@Composable +private fun Preview4() { + HousTheme { + Surface { + MainRuleItem( + mainRule = Rule().copy(isNew = true, isRepresent = true) + ) + } + } +} From 57e468e7b57bc759a4bc498b4a8bbe7d26732a67 Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 18:07:05 +0900 Subject: [PATCH 09/10] =?UTF-8?q?#308=20[ui]=20PhotoGrid=20X=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=9C=84=EC=B9=98=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/our_rules/component/update/PhotoGrid.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/hous/release/android/presentation/our_rules/component/update/PhotoGrid.kt b/app/src/main/java/hous/release/android/presentation/our_rules/component/update/PhotoGrid.kt index e8588c41..56bda65a 100644 --- a/app/src/main/java/hous/release/android/presentation/our_rules/component/update/PhotoGrid.kt +++ b/app/src/main/java/hous/release/android/presentation/our_rules/component/update/PhotoGrid.kt @@ -117,8 +117,8 @@ fun PhotoItem( private fun Modifier.deleteButtonLayout() = this.layout { measurable, constraints -> val placeable = measurable.measure(constraints) - val placeableY = (placeable.height * 0.38f).toInt() - val placeableX = (placeable.width * 0.38f).toInt() + val placeableY = (placeable.height * 0.36f).toInt() + val placeableX = (placeable.width * 0.36f).toInt() layout(placeable.width, placeable.height) { placeable.place( x = placeableX, From c11af11f8cf875322bee7e1c22e91ac2169f18f4 Mon Sep 17 00:00:00 2001 From: murjune Date: Sun, 3 Sep 2023 18:12:50 +0900 Subject: [PATCH 10/10] #308 [chore] ktlint --- .../release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt b/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt index 01300a8c..7a61a0c8 100644 --- a/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt +++ b/domain/src/main/java/hous/release/domain/usecase/rule/UpdateRepresentRulesUseCase.kt @@ -9,4 +9,4 @@ class UpdateRepresentRulesUseCase @Inject constructor( suspend operator fun invoke(rules: List) { ruleRepository.updateRepresentRules(rules) } -} \ No newline at end of file +}