From 169c1eba54682ea3abf80bc50cfe33563b4544cb Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 18:16:32 +0900 Subject: [PATCH 01/14] =?UTF-8?q?remove:=20feat>=EC=BA=98=EB=A6=B0?= =?UTF-8?q?=EB=8D=94=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hamyeonham/challenge/ChallengeFragment.kt | 21 --------- .../calendar/ChallengeCalendarAdapter.kt | 36 --------------- .../calendar/ChallengeStatusViewHolder.kt | 44 ------------------- 3 files changed, 101 deletions(-) delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeCalendarAdapter.kt delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeStatusViewHolder.kt diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt index bbd10f727..e380acd14 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt @@ -16,11 +16,9 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle -import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.hmh.hamyeonham.challenge.appadd.AppAddActivity -import com.hmh.hamyeonham.challenge.calendar.ChallengeCalendarAdapter import com.hmh.hamyeonham.challenge.goals.ChallengeUsageGoalsAdapter import com.hmh.hamyeonham.challenge.model.Apps import com.hmh.hamyeonham.challenge.model.NewChallenge @@ -37,7 +35,6 @@ import com.hmh.hamyeonham.common.view.dp import com.hmh.hamyeonham.common.view.setOnSingleClickListener import com.hmh.hamyeonham.common.view.viewBinding import com.hmh.hamyeonham.core.designsystem.R -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus import com.hmh.hamyeonham.core.viewmodel.CalendarToggleState import com.hmh.hamyeonham.core.viewmodel.MainState import com.hmh.hamyeonham.core.viewmodel.MainViewModel @@ -103,10 +100,6 @@ class ChallengeFragment : Fragment() { activityViewModel.usageStatusAndGoals.flowWithLifecycle(viewLifeCycle).onEach { updateUsageStatusAndGoals(it) }.launchIn(viewLifeCycleScope) - - activityViewModel.challengeStatusList.flowWithLifecycle(viewLifeCycle).onEach { - bindChallengeCalendar(it) - }.launchIn(viewLifeCycleScope) } private fun bindChallengeInfo(it: MainState) { @@ -187,7 +180,6 @@ class ChallengeFragment : Fragment() { initAppAddButton() initChallengeCreateButton() initChallengeGoalsRecyclerView() - initChallengeCalendarRecyclerView() initChallengeCalendar() } @@ -204,11 +196,6 @@ class ChallengeFragment : Fragment() { challengeGoalsAdapter?.submitList(challengeUsageGoalList) } - private fun bindChallengeCalendar(challengeList: List) { - val challengeAdapter = binding.rvChallengeCalendar.adapter as? ChallengeCalendarAdapter - challengeAdapter?.updateList(challengeList) - } - private fun bindChallengeDate(todayIndexAsDate: Int, startDate: LocalDate) { binding.run { tvChallengeStartDate.text = getString( @@ -223,14 +210,6 @@ class ChallengeFragment : Fragment() { } } - private fun initChallengeCalendarRecyclerView() { - binding.rvChallengeCalendar.run { - layoutManager = GridLayoutManager(requireContext(), 7) - adapter = ChallengeCalendarAdapter(context) - } - initChallengeCalendar() - } - private fun initChallengeCalendar() { val period = activityViewModel.mainState.value.period val isPeriodOverTwoWeeks = period > 14 diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeCalendarAdapter.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeCalendarAdapter.kt deleted file mode 100644 index 3797c44fa..000000000 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeCalendarAdapter.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.hmh.hamyeonham.challenge.calendar - -import android.content.Context -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus -import com.hmh.hamyeonham.feature.challenge.databinding.ItemChallengeStatusBinding - -class ChallengeCalendarAdapter(private val context: Context) : - RecyclerView.Adapter() { - - private val items = mutableListOf() - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChallengeStatusViewHolder { - return ChallengeStatusViewHolder( - ItemChallengeStatusBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false, - ), context - ) - } - - override fun onBindViewHolder(holder: ChallengeStatusViewHolder, position: Int) { - holder.bind(items[position], position) - } - - override fun getItemCount(): Int = items.size - - fun updateList(newItems: List) { - items.clear() - items.addAll(newItems) - notifyDataSetChanged() // 애니메이션 없이 갱신 - } -} diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeStatusViewHolder.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeStatusViewHolder.kt deleted file mode 100644 index 756317c14..000000000 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/calendar/ChallengeStatusViewHolder.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.hmh.hamyeonham.challenge.calendar - -import android.content.Context -import androidx.core.content.ContextCompat -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus -import com.hmh.hamyeonham.feature.challenge.R -import com.hmh.hamyeonham.feature.challenge.databinding.ItemChallengeStatusBinding - -class ChallengeStatusViewHolder( - private val binding: ItemChallengeStatusBinding, private val context: Context -) : RecyclerView.ViewHolder(binding.root) { - fun bind(challenge: ChallengeStatus, position: Int) { - binding.apply { - val date = (position + 1).toString() - tvDate.text = date - ivChallengeStatus.setImageResource(getDrawableResource(challenge)) - tvDate.setTextColor(getColor(challenge)) - ivTodayMark.isVisible = challenge == ChallengeStatus.TODAY - } - } - - private fun getColor(challenge: ChallengeStatus?): Int { - val colorId = when (challenge) { - ChallengeStatus.UNEARNED -> com.hmh.hamyeonham.core.designsystem.R.color.gray2 - ChallengeStatus.EARNED -> com.hmh.hamyeonham.core.designsystem.R.color.gray2 - ChallengeStatus.FAILURE -> com.hmh.hamyeonham.core.designsystem.R.color.gray2 - ChallengeStatus.TODAY -> com.hmh.hamyeonham.core.designsystem.R.color.white_text - else -> com.hmh.hamyeonham.core.designsystem.R.color.gray3 - } - return ContextCompat.getColor(context, colorId) - } - - private fun getDrawableResource(challenge: ChallengeStatus?): Int { - return when (challenge) { - ChallengeStatus.UNEARNED -> R.drawable.ic_challenge_success_42 - ChallengeStatus.EARNED -> R.drawable.ic_challenge_success_42 - ChallengeStatus.FAILURE -> R.drawable.ic_challenge_fail_42 - ChallengeStatus.TODAY -> R.drawable.ic_challenge_today_42 - else -> R.drawable.ic_challenge_none_42 - } - } -} \ No newline at end of file From 53e2506c57adeccc6fc3a93bdad2655f8a2a5f1d Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 18:32:37 +0900 Subject: [PATCH 02/14] =?UTF-8?q?remove:=20feat>=EC=BA=98=EB=A6=B0?= =?UTF-8?q?=EB=8D=94=20=EA=B4=80=EB=A0=A8=20xml,=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/viewmodel/MainViewModel.kt | 26 ----- .../hamyeonham/challenge/ChallengeFragment.kt | 91 ----------------- .../challenge/ChallengeViewModel.kt | 14 --- .../main/res/layout/fragment_challenge.xml | 97 +------------------ 4 files changed, 3 insertions(+), 225 deletions(-) diff --git a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt index a467dc51d..9e1386f8b 100644 --- a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt +++ b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt @@ -31,10 +31,6 @@ import retrofit2.HttpException import timber.log.Timber import javax.inject.Inject -enum class CalendarToggleState { - EXPANDED, COLLAPSED, -} - @HiltViewModel class MainViewModel @Inject constructor( private val challengeRepository: ChallengeRepository, @@ -85,12 +81,6 @@ class MainViewModel @Inject constructor( } } - fun reloadChallengeStatus() { - viewModelScope.launch(Dispatchers.Main) { - getChallengeStatus() - } - } - fun reloadUsageStatsList() { viewModelScope.launch(Dispatchers.Main) { getTodayTimeAndSetUsageStatsList() @@ -116,22 +106,6 @@ class MainViewModel @Inject constructor( } } - fun updateChallengeListWithToggleState(calendarToggleState: CalendarToggleState) { - val challengeStatusList = challengeStatusList.value - _challengeList.value = when (calendarToggleState) { - CalendarToggleState.EXPANDED -> { - rawChallengeList - } - - CalendarToggleState.COLLAPSED -> { - if (challengeStatusList.size == 14) - challengeStatusList.take(14) - else - challengeStatusList.take(7) - } - } - } - private fun updateState(transform: suspend MainState.() -> MainState) { viewModelScope.launch(Dispatchers.Main) { val currentState = mainState.value diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt index e380acd14..d46e2e448 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt @@ -10,8 +10,6 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat -import androidx.core.view.isInvisible -import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels @@ -21,8 +19,6 @@ import androidx.recyclerview.widget.RecyclerView import com.hmh.hamyeonham.challenge.appadd.AppAddActivity import com.hmh.hamyeonham.challenge.goals.ChallengeUsageGoalsAdapter import com.hmh.hamyeonham.challenge.model.Apps -import com.hmh.hamyeonham.challenge.model.NewChallenge -import com.hmh.hamyeonham.challenge.newchallenge.NewChallengeActivity import com.hmh.hamyeonham.common.amplitude.AmplitudeUtils import com.hmh.hamyeonham.common.context.getAppNameFromPackageName import com.hmh.hamyeonham.common.dialog.TwoButtonCommonDialog @@ -35,15 +31,12 @@ import com.hmh.hamyeonham.common.view.dp import com.hmh.hamyeonham.common.view.setOnSingleClickListener import com.hmh.hamyeonham.common.view.viewBinding import com.hmh.hamyeonham.core.designsystem.R -import com.hmh.hamyeonham.core.viewmodel.CalendarToggleState -import com.hmh.hamyeonham.core.viewmodel.MainState import com.hmh.hamyeonham.core.viewmodel.MainViewModel import com.hmh.hamyeonham.feature.challenge.databinding.FragmentChallengeBinding import com.hmh.hamyeonham.usagestats.model.UsageStatusAndGoal import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.datetime.LocalDate import javax.inject.Inject @AndroidEntryPoint @@ -57,19 +50,6 @@ class ChallengeFragment : Fragment() { addSelectedApps(result) } } - private val newChallengeResultLauncher: ActivityResultLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == Activity.RESULT_OK) { - val period = result.data?.getIntExtra(NewChallengeActivity.PERIOD, 0) - val goalTime = result.data?.getLongExtra(NewChallengeActivity.GOALTIME, 0) - activityViewModel.generateNewChallenge( - NewChallenge( - period = period ?: 0, - goalTime = goalTime ?: 0, - ), - ) - } - } @Inject lateinit var navigationProvider: NavigationProvider @@ -93,20 +73,11 @@ class ChallengeFragment : Fragment() { } private fun collectMainStateAndProcess() { - activityViewModel.mainState.flowWithLifecycle(viewLifeCycle).onEach { - bindChallengeInfo(it) - }.launchIn(viewLifeCycleScope) - activityViewModel.usageStatusAndGoals.flowWithLifecycle(viewLifeCycle).onEach { updateUsageStatusAndGoals(it) }.launchIn(viewLifeCycleScope) } - private fun bindChallengeInfo(it: MainState) { - setChallengeCalendarVisibility(it.isChallengeExist) - bindChallengeDate(it.todayIndexAsDate, it.startDate) - } - private fun updateUsageStatusAndGoals(usageStatusAndGoals: UsageStatusAndGoal) { viewModel.updateUsageStatusAndGoals(usageStatusAndGoals) } @@ -114,7 +85,6 @@ class ChallengeFragment : Fragment() { private fun collectChallengeStateAndProcess() { viewModel.challengeState.flowWithLifecycle(viewLifeCycle).onEach { handleModifierButtonState(it.modifierState) - handleCalendarToggleState(it.calendarToggleState) bindUsageGoals(it.usageGoalsAndModifiers) }.launchIn(viewLifeCycleScope) } @@ -167,28 +137,10 @@ class ChallengeFragment : Fragment() { } } - private fun initChallengeCreateButton() { - binding.btnChallengeCreate.setOnClickListener { - AmplitudeUtils.trackEventWithProperties("click_newchallenge_button") - val intent = Intent(requireContext(), NewChallengeActivity::class.java) - newChallengeResultLauncher.launch(intent) - } - } - private fun initViews() { initModifierButton() initAppAddButton() - initChallengeCreateButton() initChallengeGoalsRecyclerView() - initChallengeCalendar() - } - - private fun setChallengeCalendarVisibility(isChallengeExist: Boolean) { - binding.btnChallengeCreate.isInvisible = isChallengeExist - binding.tvChallengeCreateTitle.isInvisible = isChallengeExist - binding.tvChallengeDay.isInvisible = !isChallengeExist - binding.tvChallengeStartDate.isInvisible = !isChallengeExist - binding.rvChallengeCalendar.isInvisible = !isChallengeExist } private fun bindUsageGoals(challengeUsageGoalList: List) { @@ -196,49 +148,6 @@ class ChallengeFragment : Fragment() { challengeGoalsAdapter?.submitList(challengeUsageGoalList) } - private fun bindChallengeDate(todayIndexAsDate: Int, startDate: LocalDate) { - binding.run { - tvChallengeStartDate.text = getString( - com.hmh.hamyeonham.feature.challenge.R.string.challenge_start_date, - startDate.monthNumber, - startDate.dayOfMonth, - ) - tvChallengeDay.text = getString( - com.hmh.hamyeonham.feature.challenge.R.string.challenge_day, - todayIndexAsDate, - ) - } - } - - private fun initChallengeCalendar() { - val period = activityViewModel.mainState.value.period - val isPeriodOverTwoWeeks = period > 14 - binding.tvCalendarToggle.run { - isVisible = isPeriodOverTwoWeeks - if (!isPeriodOverTwoWeeks) return - setOnClickListener { - viewModel.toggleCalendarState() - } - text = - getString(com.hmh.hamyeonham.feature.challenge.R.string.tv_calendar_toggle_expand) - } - } - - private fun handleCalendarToggleState(calendarToggleState: CalendarToggleState) { - activityViewModel.updateChallengeListWithToggleState(calendarToggleState) - when (calendarToggleState) { - CalendarToggleState.COLLAPSED -> { - binding.tvCalendarToggle.text = - getString(com.hmh.hamyeonham.feature.challenge.R.string.tv_calendar_toggle_expand) - } - - CalendarToggleState.EXPANDED -> { - binding.tvCalendarToggle.text = - getString(com.hmh.hamyeonham.feature.challenge.R.string.tv_calendar_toggle_collapse) - } - } - } - private fun addSelectedApps(result: ActivityResult) { val selectedApps = result.data?.getStringArrayExtra(AppAddActivity.SELECTED_APPS)?.toList() ?: return diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeViewModel.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeViewModel.kt index 621a1905c..b3897150b 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeViewModel.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeViewModel.kt @@ -7,7 +7,6 @@ import com.hmh.hamyeonham.challenge.usecase.AddUsageGoalsUseCase import com.hmh.hamyeonham.challenge.usecase.DeleteUsageGoalUseCase import com.hmh.hamyeonham.common.amplitude.AmplitudeUtils import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal -import com.hmh.hamyeonham.core.viewmodel.CalendarToggleState import com.hmh.hamyeonham.usagestats.model.UsageStatusAndGoal import com.hmh.hamyeonham.usagestats.usecase.CheckAndDeleteDeletedAppUsageUseCase import com.hmh.hamyeonham.usagestats.usecase.DeletedAppUsageStoreUseCase @@ -18,7 +17,6 @@ import kotlinx.coroutines.launch import javax.inject.Inject data class ChallengeState( - val calendarToggleState: CalendarToggleState = CalendarToggleState.COLLAPSED, val usageGoals: List = emptyList(), val modifierState: ModifierState = ModifierState.DONE, val usageStatusAndGoals: UsageStatusAndGoal = UsageStatusAndGoal(), @@ -93,16 +91,4 @@ class ChallengeViewModel @Inject constructor( ) } } - - fun toggleCalendarState() { - when (challengeState.value.calendarToggleState) { - CalendarToggleState.COLLAPSED -> { - updateChallengeState { copy(calendarToggleState = CalendarToggleState.EXPANDED) } - } - - CalendarToggleState.EXPANDED -> { - updateChallengeState { copy(calendarToggleState = CalendarToggleState.COLLAPSED) } - } - } - } } diff --git a/feature/challenge/src/main/res/layout/fragment_challenge.xml b/feature/challenge/src/main/res/layout/fragment_challenge.xml index fd6dd4d36..8da182d77 100644 --- a/feature/challenge/src/main/res/layout/fragment_challenge.xml +++ b/feature/challenge/src/main/res/layout/fragment_challenge.xml @@ -32,81 +32,6 @@ - - - - - - - - - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/cl_top_appbar"> + app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintTop_toBottomOf="@id/tv_modifier_button" /> Date: Mon, 18 Aug 2025 18:44:21 +0900 Subject: [PATCH 03/14] =?UTF-8?q?remove:=20feat>NewChallengeActivity=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/src/main/AndroidManifest.xml | 3 - .../challenge/ChallengeViewModel.kt | 2 +- .../newchallenge/NewChallengeActivity.kt | 90 ------------------- 3 files changed, 1 insertion(+), 94 deletions(-) delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeActivity.kt diff --git a/feature/challenge/src/main/AndroidManifest.xml b/feature/challenge/src/main/AndroidManifest.xml index a2b21cd56..d59b352d0 100644 --- a/feature/challenge/src/main/AndroidManifest.xml +++ b/feature/challenge/src/main/AndroidManifest.xml @@ -2,9 +2,6 @@ - () - - companion object { - const val PERIOD = "period" - const val GOALTIME = "goal time" - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(binding.root) - initViews() - collectNewChallengeState() - } - - private fun initViews() { - binding.run { - vpNewChallenge.adapter = NewChallengeViewPagerAdapter(this@NewChallengeActivity) - vpNewChallenge.isUserInputEnabled = false - - btNewChallenge.setOnClickListener { - handleNextClicked() - if (vpNewChallenge.adapter?.itemCount == FRAGMENT.PERIODSELECTION.position) { - val properties = JSONObject().put("period", viewModel.state.value.goalDate) - AmplitudeUtils.trackEventWithProperties( - "click_newchallenge_totaltime", - properties - ) - } - } - ivBack.setOnClickListener { finish() } - } - } - - private fun handleNextClicked() { - binding.vpNewChallenge.run { - when (currentItem) { - FRAGMENT.PERIODSELECTION.position -> currentItem = FRAGMENT.TIMESELECTION.position - FRAGMENT.TIMESELECTION.position -> showChallengeCreatedDialog() - } - } - } - - private fun collectNewChallengeState() { - viewModel.state.flowWithLifecycle(lifecycle).onEach { - binding.btNewChallenge.isEnabled = it.isNextButtonActive - }.launchIn(lifecycleScope) - } - - private fun showChallengeCreatedDialog() { - OneButtonCommonDialog.newInstance( - title = getString(R.string.dialog_title_challengecreated), - description = getString(R.string.dialog_description_challengecreated), - iconRes = R.drawable.ic_challengecreated_120, - confirmButtonText = getString(R.string.dialog_button_challengecreated), - setBlueButton = true - ).apply { - setConfirmButtonClickListener { - finishWithResults() - } - }.showAllowingStateLoss(supportFragmentManager, OneButtonCommonDialog.TAG) - } - - private fun finishWithResults() { - val intent = Intent().apply { - putExtra(PERIOD, viewModel.state.value.goalDate) - putExtra(GOALTIME, viewModel.state.value.goalTime) - } - setResult(RESULT_OK, intent) - finish() - } -} From a43b4b574aafc30ba88e1d2a0a3f484eb5c84683 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 18:46:43 +0900 Subject: [PATCH 04/14] =?UTF-8?q?remove:=20feat>newChallengeFragment=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../newchallenge/NewChallengeViewModel.kt | 50 ------------ .../NewChallengeViewPagerAdapter.kt | 24 ------ .../PeriodSelectionFragment.kt | 79 ------------------- .../timeselection/TimeSelectionFragment.kt | 54 ------------- 4 files changed, 207 deletions(-) delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewModel.kt delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewPagerAdapter.kt delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/periodselection/PeriodSelectionFragment.kt delete mode 100644 feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/timeselection/TimeSelectionFragment.kt diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewModel.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewModel.kt deleted file mode 100644 index 58ab31941..000000000 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewModel.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.hmh.hamyeonham.challenge.newchallenge - -import androidx.lifecycle.ViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow - -data class NewChallengeState( - val goalDate: Int = NOTINITIALIZED, - val goalTime: Long = DEFAULTSCREENTIME, - val isNextButtonActive: Boolean = false, -) { - companion object { - val NOTINITIALIZED: Int = 0 - val DEFAULTSCREENTIME: Long = 3600000 - } -} - -class NewChallengeViewModel : ViewModel() { - private val _state = MutableStateFlow(NewChallengeState()) - val state = _state.asStateFlow() - - private fun updateState(transform: NewChallengeState.() -> NewChallengeState) { - val currentState = state.value - val newState = currentState.transform() - _state.value = newState - } - - fun updateNextButtonActivatedState(isNextButtonActive: Boolean) { - updateState { copy(isNextButtonActive = isNextButtonActive) } - } - - fun selectDate(date: Int) { - updateState { - copy(goalDate = date) - } - } - - fun unSelectDate() { - updateState { - copy(goalDate = NewChallengeState.NOTINITIALIZED) - } - } - - fun setGoalHour(goalTime: Long) { - updateState { - copy(goalTime = goalTime) - } - } - -} \ No newline at end of file diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewPagerAdapter.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewPagerAdapter.kt deleted file mode 100644 index a5d359f82..000000000 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/NewChallengeViewPagerAdapter.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.hmh.hamyeonham.challenge.newchallenge - -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.viewpager2.adapter.FragmentStateAdapter -import com.hmh.hamyeonham.challenge.newchallenge.periodselection.PeriodSelectionFragment -import com.hmh.hamyeonham.challenge.newchallenge.timeselection.TimeSelectionFragment - -enum class FRAGMENT(val position: Int) { - PERIODSELECTION(0), - TIMESELECTION(1) -} - -class NewChallengeViewPagerAdapter(fragmentActivity: FragmentActivity) : - FragmentStateAdapter(fragmentActivity) { - override fun getItemCount(): Int = 2 - - override fun createFragment(position: Int): Fragment { - return when (position) { - FRAGMENT.PERIODSELECTION.position -> PeriodSelectionFragment() - else -> TimeSelectionFragment() - } - } -} diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/periodselection/PeriodSelectionFragment.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/periodselection/PeriodSelectionFragment.kt deleted file mode 100644 index 6c4f27e52..000000000 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/periodselection/PeriodSelectionFragment.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.hmh.hamyeonham.challenge.newchallenge.periodselection - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.appcompat.widget.AppCompatButton -import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels -import com.hmh.hamyeonham.challenge.newchallenge.NewChallengeViewModel -import com.hmh.hamyeonham.common.primitive.extractDigits -import com.hmh.hamyeonham.common.view.viewBinding -import com.hmh.hamyeonham.feature.challenge.databinding.FragmentPeriodSelectionBinding - -class PeriodSelectionFragment : Fragment() { - - private val binding by viewBinding(FragmentPeriodSelectionBinding::bind) - private val viewModel by activityViewModels() - private val selectedButtons = mutableSetOf() - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - return FragmentPeriodSelectionBinding.inflate(inflater, container, false).root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - initViews() - } - - private fun initViews() { - initQuestionButton() - } - - private fun initQuestionButton() { - val periodSelectionFragmentButtonList = listOf( - binding.btnNewChallengeSevenDays, - binding.btnNewChallengeFourteenDays, - binding.btnNewChallengeTwentyDays, - binding.btnNewChallengeThirtyDays, - ) - - periodSelectionFragmentButtonList.forEachIndexed { _, button -> - button.setOnClickListener { - toggleButtonSelection(button) - } - } - } - - private fun toggleButtonSelection(button: AppCompatButton) { - button.isSelected = !button.isSelected - updateSelectedButtons(button) - updateUserResponse(button) - } - - private fun updateSelectedButtons(newSelectedButton: AppCompatButton) { - selectedButtons.filter { it != newSelectedButton }.forEach { it.isSelected = false } - selectedButtons.clear() - - if (newSelectedButton.isSelected) { - selectedButtons.add(newSelectedButton) - } else { - selectedButtons.remove(newSelectedButton) - } - viewModel.updateNextButtonActivatedState(selectedButtons.isNotEmpty()) - } - - private fun updateUserResponse(newSelectedButton: AppCompatButton) { - if (newSelectedButton.isSelected) { - val period = newSelectedButton.text.toString().extractDigits() - viewModel.selectDate(period) - } else { - viewModel.unSelectDate() - } - } -} \ No newline at end of file diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/timeselection/TimeSelectionFragment.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/timeselection/TimeSelectionFragment.kt deleted file mode 100644 index c6f0d9d80..000000000 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/newchallenge/timeselection/TimeSelectionFragment.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.hmh.hamyeonham.challenge.newchallenge.timeselection - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.NumberPicker -import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels -import com.hmh.hamyeonham.challenge.newchallenge.NewChallengeViewModel -import com.hmh.hamyeonham.common.amplitude.AmplitudeUtils -import com.hmh.hamyeonham.common.time.hourToMs -import com.hmh.hamyeonham.common.view.setupScreentimeGoalRange -import com.hmh.hamyeonham.common.view.viewBinding -import com.hmh.hamyeonham.feature.challenge.databinding.FragmentTimeSelectionBinding - -class TimeSelectionFragment : Fragment() { - private val binding by viewBinding(FragmentTimeSelectionBinding::bind) - private val viewModel by activityViewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - AmplitudeUtils.trackEventWithProperties("view_newchallenge_totaltime") - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - return FragmentTimeSelectionBinding.inflate(inflater, container, false).root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setNumberPicker() - } - - private fun setNumberPicker() { - binding.run { - npNewChallengeScreentimeGoal.setupScreentimeGoalRange(MINTOTAL, MAXTOTAL) - npNewChallengeScreentimeGoal.descendantFocusability = - NumberPicker.FOCUS_BLOCK_DESCENDANTS - npNewChallengeScreentimeGoal.setOnValueChangedListener { _, _, newTime -> - viewModel.setGoalHour(newTime.hourToMs()) - } - } - } - - companion object { - val MINTOTAL = 1 - val MAXTOTAL = 6 - } -} From c91d724486bdc04230cf78d0286b57f0fffa2f7c Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 18:50:44 +0900 Subject: [PATCH 05/14] =?UTF-8?q?remove:=20feat>=EC=B1=8C=EB=A6=B0?= =?UTF-8?q?=EC=A7=80=20=EA=B4=80=EB=A0=A8=20xml=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/layout/activity_new_challenge.xml | 53 --------- .../res/layout/fragment_period_selection.xml | 104 ------------------ .../res/layout/fragment_time_selection.xml | 57 ---------- .../main/res/layout/item_challenge_status.xml | 48 -------- .../src/main/res/layout/item_point.xml | 46 -------- 5 files changed, 308 deletions(-) delete mode 100644 feature/challenge/src/main/res/layout/activity_new_challenge.xml delete mode 100644 feature/challenge/src/main/res/layout/fragment_period_selection.xml delete mode 100644 feature/challenge/src/main/res/layout/fragment_time_selection.xml delete mode 100644 feature/challenge/src/main/res/layout/item_challenge_status.xml delete mode 100644 feature/challenge/src/main/res/layout/item_point.xml diff --git a/feature/challenge/src/main/res/layout/activity_new_challenge.xml b/feature/challenge/src/main/res/layout/activity_new_challenge.xml deleted file mode 100644 index 5b87bc538..000000000 --- a/feature/challenge/src/main/res/layout/activity_new_challenge.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/feature/challenge/src/main/res/layout/fragment_period_selection.xml b/feature/challenge/src/main/res/layout/fragment_period_selection.xml deleted file mode 100644 index 6bd1240c6..000000000 --- a/feature/challenge/src/main/res/layout/fragment_period_selection.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/feature/challenge/src/main/res/layout/fragment_time_selection.xml b/feature/challenge/src/main/res/layout/fragment_time_selection.xml deleted file mode 100644 index f72862125..000000000 --- a/feature/challenge/src/main/res/layout/fragment_time_selection.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - diff --git a/feature/challenge/src/main/res/layout/item_challenge_status.xml b/feature/challenge/src/main/res/layout/item_challenge_status.xml deleted file mode 100644 index 0f7226cf0..000000000 --- a/feature/challenge/src/main/res/layout/item_challenge_status.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - diff --git a/feature/challenge/src/main/res/layout/item_point.xml b/feature/challenge/src/main/res/layout/item_point.xml deleted file mode 100644 index 14e81f58e..000000000 --- a/feature/challenge/src/main/res/layout/item_point.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - \ No newline at end of file From db5e4123ac519c4e54553733001a6d92e8c88d70 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:03:43 +0900 Subject: [PATCH 06/14] =?UTF-8?q?remove:=20feat>=EC=B1=8C=EB=A6=B0?= =?UTF-8?q?=EC=A7=80=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20AppUsageGoal=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95(=EC=95=B1=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=EB=A7=8C=20=EB=82=A8=EA=B2=A8=EB=91=A0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ChallengeFragment.kt => AppUsageGoalsFragment.kt} | 10 +++++----- ...allengeViewModel.kt => AppUsageGoalsViewModel.kt} | 0 .../challenge/appadd/AppAddViewPagerAdapter.kt | 4 ++-- ...GoalTimeFragment.kt => SetAppGoalTimeFragment.kt} | 2 +- ...eUsageGoalsAdapter.kt => AppUsageGoalsAdapter.kt} | 12 ++++++------ ...lengeViewHolder.kt => AppUsageGoalsViewHolder.kt} | 4 ++-- .../src/main/res/layout/fragment_challenge.xml | 4 ++-- .../com/hmh/hamyeonham/feature/main/MainAdapter.kt | 4 ++-- feature/main/src/main/res/navigation/nav_graph.xml | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) rename feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/{ChallengeFragment.kt => AppUsageGoalsFragment.kt} (96%) rename feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/{ChallengeViewModel.kt => AppUsageGoalsViewModel.kt} (100%) rename feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/{SetGoalTimeFragment.kt => SetAppGoalTimeFragment.kt} (97%) rename feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/{ChallengeUsageGoalsAdapter.kt => AppUsageGoalsAdapter.kt} (73%) rename feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/{ChallengeViewHolder.kt => AppUsageGoalsViewHolder.kt} (95%) diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsFragment.kt similarity index 96% rename from feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt rename to feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsFragment.kt index d46e2e448..1d29002c0 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeFragment.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsFragment.kt @@ -17,7 +17,7 @@ import androidx.lifecycle.flowWithLifecycle import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.hmh.hamyeonham.challenge.appadd.AppAddActivity -import com.hmh.hamyeonham.challenge.goals.ChallengeUsageGoalsAdapter +import com.hmh.hamyeonham.challenge.goals.AppUsageGoalsAdapter import com.hmh.hamyeonham.challenge.model.Apps import com.hmh.hamyeonham.common.amplitude.AmplitudeUtils import com.hmh.hamyeonham.common.context.getAppNameFromPackageName @@ -40,7 +40,7 @@ import kotlinx.coroutines.flow.onEach import javax.inject.Inject @AndroidEntryPoint -class ChallengeFragment : Fragment() { +class AppUsageGoalsFragment : Fragment() { private val binding by viewBinding(FragmentChallengeBinding::bind) private val activityViewModel by activityViewModels() private val viewModel by viewModels() @@ -130,7 +130,7 @@ class ChallengeFragment : Fragment() { } private fun initAppAddButton() { - binding.btGoalAdd.setOnSingleClickListener { + binding.btAppAdd.setOnSingleClickListener { AmplitudeUtils.trackEventWithProperties("click_add_button") val intent = Intent(requireContext(), AppAddActivity::class.java) appSelectionResultLauncher.launch(intent) @@ -144,7 +144,7 @@ class ChallengeFragment : Fragment() { } private fun bindUsageGoals(challengeUsageGoalList: List) { - val challengeGoalsAdapter = binding.rvAppUsageGoals.adapter as? ChallengeUsageGoalsAdapter + val challengeGoalsAdapter = binding.rvAppUsageGoals.adapter as? AppUsageGoalsAdapter challengeGoalsAdapter?.submitList(challengeUsageGoalList) } @@ -158,7 +158,7 @@ class ChallengeFragment : Fragment() { private fun initChallengeGoalsRecyclerView() { binding.rvAppUsageGoals.run { - adapter = ChallengeUsageGoalsAdapter( + adapter = AppUsageGoalsAdapter( onAppItemClicked = { challengeGoal -> when (viewModel.challengeState.value.modifierState) { ModifierState.EDIT -> { diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeViewModel.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsViewModel.kt similarity index 100% rename from feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/ChallengeViewModel.kt rename to feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsViewModel.kt diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/AppAddViewPagerAdapter.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/AppAddViewPagerAdapter.kt index dbb91b58c..dacac3f8f 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/AppAddViewPagerAdapter.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/AppAddViewPagerAdapter.kt @@ -4,7 +4,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.viewpager2.adapter.FragmentStateAdapter import com.hmh.hamyeonham.challenge.appadd.appselection.AppSelectionFragment -import com.hmh.hamyeonham.challenge.appadd.time.SetGoalTimeFragment +import com.hmh.hamyeonham.challenge.appadd.time.SetAppGoalTimeFragment class AppAddViewPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) { @@ -13,7 +13,7 @@ class AppAddViewPagerAdapter(fragmentActivity: FragmentActivity) : override fun createFragment(position: Int): Fragment { return when (position) { 0 -> AppSelectionFragment() - else -> SetGoalTimeFragment() + else -> SetAppGoalTimeFragment() } } } diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/SetGoalTimeFragment.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/SetAppGoalTimeFragment.kt similarity index 97% rename from feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/SetGoalTimeFragment.kt rename to feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/SetAppGoalTimeFragment.kt index 5b78227d7..a02dce9d6 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/SetGoalTimeFragment.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/appadd/time/SetAppGoalTimeFragment.kt @@ -14,7 +14,7 @@ import com.hmh.hamyeonham.feature.challenge.databinding.FragmentSetGoalTimeBindi import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class SetGoalTimeFragment : Fragment() { +class SetAppGoalTimeFragment : Fragment() { private val binding by viewBinding(FragmentSetGoalTimeBinding::bind) private val viewModel by activityViewModels() diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/ChallengeUsageGoalsAdapter.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/AppUsageGoalsAdapter.kt similarity index 73% rename from feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/ChallengeUsageGoalsAdapter.kt rename to feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/AppUsageGoalsAdapter.kt index b55c38a37..b05d9f396 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/ChallengeUsageGoalsAdapter.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/AppUsageGoalsAdapter.kt @@ -7,9 +7,9 @@ import com.hmh.hamyeonham.challenge.ChallengeUsageGoal import com.hmh.hamyeonham.common.view.ItemDiffCallback import com.hmh.hamyeonham.feature.challenge.databinding.ItemUsageGoalBinding -class ChallengeUsageGoalsAdapter( +class AppUsageGoalsAdapter( private val onAppItemClicked: (ChallengeUsageGoal) -> Unit -) : ListAdapter( +) : ListAdapter( ItemDiffCallback( onItemsTheSame = { oldItem, newItem -> oldItem.usageStatusAndGoal.packageName == newItem.usageStatusAndGoal.packageName @@ -23,8 +23,8 @@ class ChallengeUsageGoalsAdapter( override fun onCreateViewHolder( parent: ViewGroup, viewType: Int - ): ChallengeViewHolder { - return ChallengeViewHolder.UsageGoalsViewHolder( + ): AppUsageGoalsViewHolder { + return AppUsageGoalsViewHolder.UsageGoalsViewHolder( ItemUsageGoalBinding.inflate( LayoutInflater.from(parent.context), parent, @@ -34,7 +34,7 @@ class ChallengeUsageGoalsAdapter( ) } - override fun onBindViewHolder(holder: ChallengeViewHolder, position: Int) { - (holder as? ChallengeViewHolder.UsageGoalsViewHolder)?.bind(getItem(position)) + override fun onBindViewHolder(holder: AppUsageGoalsViewHolder, position: Int) { + (holder as? AppUsageGoalsViewHolder.UsageGoalsViewHolder)?.bind(getItem(position)) } } diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/ChallengeViewHolder.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/AppUsageGoalsViewHolder.kt similarity index 95% rename from feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/ChallengeViewHolder.kt rename to feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/AppUsageGoalsViewHolder.kt index 405a84179..a5ec27be1 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/ChallengeViewHolder.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/goals/AppUsageGoalsViewHolder.kt @@ -12,11 +12,11 @@ import com.hmh.hamyeonham.feature.challenge.R import com.hmh.hamyeonham.feature.challenge.databinding.ItemUsageGoalBinding -sealed class ChallengeViewHolder(binding: ViewBinding) : RecyclerView.ViewHolder(binding.root) { +sealed class AppUsageGoalsViewHolder(binding: ViewBinding) : RecyclerView.ViewHolder(binding.root) { class UsageGoalsViewHolder( private val binding: ItemUsageGoalBinding, private val onAppItemClicked: (ChallengeUsageGoal) -> Unit - ) : ChallengeViewHolder(binding) { + ) : AppUsageGoalsViewHolder(binding) { private var item: ChallengeUsageGoal? = null init { diff --git a/feature/challenge/src/main/res/layout/fragment_challenge.xml b/feature/challenge/src/main/res/layout/fragment_challenge.xml index 8da182d77..f9231abd2 100644 --- a/feature/challenge/src/main/res/layout/fragment_challenge.xml +++ b/feature/challenge/src/main/res/layout/fragment_challenge.xml @@ -75,13 +75,13 @@ android:layout_height="wrap_content" android:layout_marginBottom="14dp" android:nestedScrollingEnabled="false" - app:layout_constraintBottom_toTopOf="@id/bt_goal_add" + app:layout_constraintBottom_toTopOf="@id/bt_app_add" app:layout_constraintEnd_toEndOf="@id/tv_modifier_button" app:layout_constraintStart_toStartOf="@id/tv_app_lock" app:layout_constraintTop_toBottomOf="@id/tv_modifier_button" /> ChallengeFragment() + MainScreen.CHALLENGE -> AppUsageGoalsFragment() MainScreen.HOME -> HomeFragment() MainScreen.MY_PAGE -> MyPageFragment() } diff --git a/feature/main/src/main/res/navigation/nav_graph.xml b/feature/main/src/main/res/navigation/nav_graph.xml index 6a61970c3..a12e93e6f 100644 --- a/feature/main/src/main/res/navigation/nav_graph.xml +++ b/feature/main/src/main/res/navigation/nav_graph.xml @@ -5,7 +5,7 @@ Date: Mon, 18 Aug 2025 23:28:21 +0900 Subject: [PATCH 07/14] =?UTF-8?q?remove:=20network=20>=20=20=EC=B1=8C?= =?UTF-8?q?=EB=A6=B0=EC=A7=80=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/network/challenge/AppCodeRequest.kt | 10 -- .../network/challenge/ChallengeService.kt | 24 ----- .../network/challenge/model/AppsRequest.kt | 19 ---- .../model/ChallengeFinishResponse.kt | 11 --- .../challenge/model/ChallengeResponse.kt | 28 ------ .../model/ChallengeWithUsageRequest.kt | 26 ----- .../model/ChallengeWithUsageResponse.kt | 21 ---- .../challenge/model/NewChallengeRequest.kt | 13 --- .../core/network/di/ChallengeModule.kt | 19 ---- .../core/network/di/UsageGoalModule.kt | 19 ---- .../usagegoal/DailyChallengeService.kt | 22 ----- .../usagegoal/model/UsageGoalResponse.kt | 22 ----- .../core/viewmodel/MainViewModel.kt | 41 -------- .../data/challenge/mapper/AppMapper.kt | 26 ----- .../data/challenge/mapper/ChallengeMapper.kt | 42 -------- .../challenge/mapper/ChallengeStatusMapper.kt | 20 ---- .../challenge/mapper/NewChallengeMapper.kt | 19 ---- .../repository/DefaultChallengeRepository.kt | 96 +------------------ .../remote/UsageGoalsRemoteDataSource.kt | 15 --- .../repository/DefaultUsageGoalsRepository.kt | 41 ++++---- .../repository/ChallengeRepository.kt | 7 -- .../challenge/usecase/NewChallengeUseCase.kt | 13 --- .../hamyeonham/feature/main/MainActivity.kt | 3 +- 23 files changed, 28 insertions(+), 529 deletions(-) delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/AppCodeRequest.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/ChallengeService.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/AppsRequest.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeFinishResponse.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeResponse.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageRequest.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageResponse.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/NewChallengeRequest.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/di/ChallengeModule.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/di/UsageGoalModule.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/DailyChallengeService.kt delete mode 100644 core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/model/UsageGoalResponse.kt delete mode 100644 data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/AppMapper.kt delete mode 100644 data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeMapper.kt delete mode 100644 data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeStatusMapper.kt delete mode 100644 data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/NewChallengeMapper.kt delete mode 100644 data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/remote/UsageGoalsRemoteDataSource.kt delete mode 100644 domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/NewChallengeUseCase.kt diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/AppCodeRequest.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/AppCodeRequest.kt deleted file mode 100644 index a19318222..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/AppCodeRequest.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class AppCodeRequest( - @SerialName("appCode") - private val appCode: String? = null -) diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/ChallengeService.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/ChallengeService.kt deleted file mode 100644 index 9306a8f71..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/ChallengeService.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge - -import com.hmh.hamyeonham.core.network.challenge.model.AppsRequest -import com.hmh.hamyeonham.core.network.challenge.model.ChallengeResponse -import com.hmh.hamyeonham.core.network.challenge.model.NewChallengeRequest -import com.hmh.hamyeonham.core.network.model.BaseResponse -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.HTTP -import retrofit2.http.POST - -interface ChallengeService { - @GET("api/v2/challenge") - suspend fun getChallengeData(): BaseResponse - - @POST("api/v2/challenge") - suspend fun postNewChallenge(@Body request: NewChallengeRequest): BaseResponse - - @POST("api/v1/challenge/app") - suspend fun postApps(@Body request: AppsRequest): BaseResponse - - @HTTP(method = "DELETE", path = "api/v1/challenge/app", hasBody = true) - suspend fun deleteApps(@Body request: AppCodeRequest): BaseResponse -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/AppsRequest.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/AppsRequest.kt deleted file mode 100644 index 93af95a39..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/AppsRequest.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class AppsRequest( - @SerialName("apps") - val apps: List? = null -) { - @Serializable - data class App( - @SerialName("appCode") - val appCode: String? = null, - @SerialName("goalTime") - val goalTime: Long? = null - ) -} - diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeFinishResponse.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeFinishResponse.kt deleted file mode 100644 index 4ed740772..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeFinishResponse.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge.model - - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class ChallengeFinishResponse( - @SerialName("statuses") - val statuses: List? = null -) \ No newline at end of file diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeResponse.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeResponse.kt deleted file mode 100644 index 24e4a7a07..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeResponse.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class ChallengeResponse( - @SerialName("apps") - val apps: List, - @SerialName("goalTime") - val goalTime: Long, - @SerialName("period") - val period: Int, - @SerialName("statuses") - val statuses: List, - @SerialName("todayIndex") - val todayIndex: Int, - @SerialName("startDate") - val startDate: String -) { - @Serializable - data class AppGoal( - @SerialName("appCode") - val appCode: String, - @SerialName("goalTime") - val goalTime: Long, - ) -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageRequest.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageRequest.kt deleted file mode 100644 index 0617cf199..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageRequest.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class ChallengeWithUsageRequest( - @SerialName("finishedDailyChallenges") - val finishedDailyChallenges: List -) { - @Serializable - data class DailyChallenges( - @SerialName("challengePeriodIndex") - val challengePeriodIndex: Int, - @SerialName("apps") - val apps: List - ) { - @Serializable - data class AppUsage( - @SerialName("appCode") - val appCode: String, - @SerialName("usageTime") - val usageTime: Long - ) - } -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageResponse.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageResponse.kt deleted file mode 100644 index 96351a35a..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/ChallengeWithUsageResponse.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge.model - - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class ChallengeWithUsageResponse( - @SerialName("data") - val `data`: Data? = null, - @SerialName("message") - val message: String? = null, - @SerialName("status") - val status: Int? = null -) { - @Serializable - data class Data( - @SerialName("statuses") - val statuses: List? = null - ) -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/NewChallengeRequest.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/NewChallengeRequest.kt deleted file mode 100644 index d4631e601..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/challenge/model/NewChallengeRequest.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.hmh.hamyeonham.core.network.challenge.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class NewChallengeRequest( - @SerialName("period") - val period: Int, - @SerialName("goalTime") - val goalTime: Long -) - diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/di/ChallengeModule.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/di/ChallengeModule.kt deleted file mode 100644 index 773fac610..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/di/ChallengeModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hmh.hamyeonham.core.network.di - -import com.hmh.hamyeonham.common.qualifier.Secured -import com.hmh.hamyeonham.core.network.challenge.ChallengeService -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import retrofit2.Retrofit -import retrofit2.create -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -object ChallengeModule { - @Provides - @Singleton - fun provideChallengeApi(@Secured retrofit: Retrofit): ChallengeService = retrofit.create() -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/di/UsageGoalModule.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/di/UsageGoalModule.kt deleted file mode 100644 index f6e4882ef..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/di/UsageGoalModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hmh.hamyeonham.core.network.di - -import com.hmh.hamyeonham.common.qualifier.Secured -import com.hmh.hamyeonham.core.network.usagegoal.DailyChallengeService -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import retrofit2.Retrofit -import retrofit2.create -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -object UsageGoalModule { - @Provides - @Singleton - fun provideUsageGoalApi(@Secured retrofit: Retrofit): DailyChallengeService = retrofit.create() -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/DailyChallengeService.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/DailyChallengeService.kt deleted file mode 100644 index 5a2f3d40e..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/DailyChallengeService.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.hmh.hamyeonham.core.network.usagegoal - -import com.hmh.hamyeonham.core.network.challenge.model.ChallengeFinishResponse -import com.hmh.hamyeonham.core.network.challenge.model.ChallengeWithUsageRequest -import com.hmh.hamyeonham.core.network.model.BaseResponse -import com.hmh.hamyeonham.core.network.usagegoal.model.UsageGoalResponse -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.PATCH -import retrofit2.http.POST - -interface DailyChallengeService { - @GET("api/v2/challenge/home") - suspend fun getUsageGoal(): BaseResponse - - @PATCH("api/v2/challenge/daily/failure") - suspend fun updateDailyChallengeFailed(): BaseResponse - - @POST("api/v2/challenge/daily/finish") - suspend fun postChallengeWithUsage(@Body request: ChallengeWithUsageRequest): BaseResponse - -} diff --git a/core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/model/UsageGoalResponse.kt b/core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/model/UsageGoalResponse.kt deleted file mode 100644 index 066fee032..000000000 --- a/core/network/src/main/java/com/hmh/hamyeonham/core/network/usagegoal/model/UsageGoalResponse.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.hmh.hamyeonham.core.network.usagegoal.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class UsageGoalResponse( - @SerialName("status") - val status: String? = null, - @SerialName("goalTime") - val goalTime: Long? = null, - @SerialName("apps") - val apps: List? = null, -) { - @Serializable - data class AppGoal( - @SerialName("appCode") - val appCode: String? = null, - @SerialName("goalTime") - val goalTime: Long? = null, - ) -} diff --git a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt index 9e1386f8b..2fbbe003b 100644 --- a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt +++ b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt @@ -3,15 +3,11 @@ package com.hmh.hamyeonham.core.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.hmh.hamyeonham.challenge.model.Challenge -import com.hmh.hamyeonham.challenge.model.NewChallenge -import com.hmh.hamyeonham.challenge.repository.ChallengeRepository -import com.hmh.hamyeonham.challenge.usecase.NewChallengeUseCase import com.hmh.hamyeonham.common.time.getCurrentDayStartEndEpochMillis import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import com.hmh.hamyeonham.domain.main.MainRepository -import com.hmh.hamyeonham.lock.SetIsUnLockUseCase import com.hmh.hamyeonham.lock.UpdateIsUnLockUseCase import com.hmh.hamyeonham.usagestats.model.UsageStatusAndGoal import com.hmh.hamyeonham.usagestats.usecase.GetUsageStatsListUseCase @@ -27,20 +23,16 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import retrofit2.HttpException import timber.log.Timber import javax.inject.Inject @HiltViewModel class MainViewModel @Inject constructor( - private val challengeRepository: ChallengeRepository, private val usageGoalsRepository: UsageGoalsRepository, private val userInfoRepository: UserInfoRepository, private val mainRepository: MainRepository, private val getUsageStatsListUseCase: GetUsageStatsListUseCase, - private val setIsUnLockUseCase: SetIsUnLockUseCase, private val updateIsUnLockUseCase: UpdateIsUnLockUseCase, - private val newChallengeUseCase: NewChallengeUseCase, ) : ViewModel() { private val _mainState = MutableStateFlow(MainState()) @@ -75,7 +67,6 @@ class MainViewModel @Inject constructor( viewModelScope.launch(Dispatchers.Main) { updateGoals() - getChallengeStatus() getUserInfo() getUsageGoalAndStatList() } @@ -87,25 +78,6 @@ class MainViewModel @Inject constructor( } } - fun updateDailyChallengeFailed() { - viewModelScope.launch { - setIsUnLockUseCase(true).onSuccess { - getChallengeStatus() - }.onFailure { e -> - Timber.e(e) - sendEffect(MainEffect.NetworkError) - } - } - } - - fun generateNewChallenge(newChallenge: NewChallenge) { - viewModelScope.launch(Dispatchers.Main) { - newChallengeUseCase(newChallenge).onSuccess { - getChallengeStatus() - } - } - } - private fun updateState(transform: suspend MainState.() -> MainState) { viewModelScope.launch(Dispatchers.Main) { val currentState = mainState.value @@ -127,19 +99,6 @@ class MainViewModel @Inject constructor( } } - private suspend fun getChallengeStatus() { - challengeRepository.getChallengeData() - .onSuccess { - setChallengeStatus(it) - }.onFailure { - if (it is HttpException) { - sendEffect(MainEffect.NetworkError) - } else { - sendEffect(MainEffect.NetworkError) - } - } - } - private fun getUsageGoalAndStatList() { viewModelScope.launch { usageGoalsRepository.getUsageGoals().collect { diff --git a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/AppMapper.kt b/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/AppMapper.kt deleted file mode 100644 index 72858dd48..000000000 --- a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/AppMapper.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.hmh.hamyeonham.data.challenge.mapper - -import com.hmh.hamyeonham.challenge.model.Apps -import com.hmh.hamyeonham.core.network.challenge.model.AppsRequest - -fun AppsRequest.toApps(): Apps { - return Apps( - apps = apps?.map { - Apps.App( - appCode = it.appCode ?: "", - goalTime = it.goalTime ?: 0 - ) - } ?: emptyList() - ) -} - -fun Apps.toAppsRequest(): AppsRequest { - return AppsRequest( - apps = apps.map { - AppsRequest.App( - appCode = it.appCode, - goalTime = it.goalTime - ) - } - ) -} diff --git a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeMapper.kt b/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeMapper.kt deleted file mode 100644 index 4f4d12379..000000000 --- a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeMapper.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.hmh.hamyeonham.data.challenge.mapper - -import com.hmh.hamyeonham.challenge.model.Challenge -import com.hmh.hamyeonham.challenge.model.ChallengeWithUsageInput -import com.hmh.hamyeonham.core.database.model.UsageEntity -import com.hmh.hamyeonham.core.network.challenge.model.ChallengeResponse -import com.hmh.hamyeonham.core.network.challenge.model.ChallengeWithUsageRequest - -internal fun ChallengeResponse.toChallengeStatus(): Challenge { - return Challenge( - apps.map { - Challenge.AppGoal(it.appCode, it.goalTime) - }, - statuses.toStatusList(todayIndex), - goalTime, - period, - todayIndex, - ) -} - -internal fun List.toRequestChallengeWithUsage(): ChallengeWithUsageRequest { - return ChallengeWithUsageRequest( - finishedDailyChallenges = map { - ChallengeWithUsageRequest.DailyChallenges( - challengePeriodIndex = it.challengePeriodIndex, - apps = it.apps.map { app -> - ChallengeWithUsageRequest.DailyChallenges.AppUsage( - appCode = app.packageName, - usageTime = app.usageTime - ) - } - ) - } - ) -} - -internal fun UsageEntity.toUsage(): ChallengeWithUsageInput.Usage { - return ChallengeWithUsageInput.Usage( - packageName = packageName, - usageTime = usageTime - ) -} \ No newline at end of file diff --git a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeStatusMapper.kt b/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeStatusMapper.kt deleted file mode 100644 index f0961b81f..000000000 --- a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/ChallengeStatusMapper.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.hmh.hamyeonham.data.challenge.mapper - -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus - -internal fun List.toStatusList(todayIndex: Int): List { - // 원본 리스트를 ChallengeStatus.Status 리스트로 변환 - return this.map { - when (it) { - ChallengeStatus.NONE.name -> ChallengeStatus.NONE - ChallengeStatus.UNEARNED.name -> ChallengeStatus.UNEARNED - ChallengeStatus.EARNED.name -> ChallengeStatus.EARNED - ChallengeStatus.FAILURE.name -> ChallengeStatus.FAILURE - else -> ChallengeStatus.NONE - } - }.toMutableList().also { - // todayIndex가 유효한 경우 today 인덱스에 TODAY 상태를 설정 - if (todayIndex > -1) - it[todayIndex] = ChallengeStatus.TODAY - } -} diff --git a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/NewChallengeMapper.kt b/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/NewChallengeMapper.kt deleted file mode 100644 index b59ab9170..000000000 --- a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/mapper/NewChallengeMapper.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hmh.hamyeonham.data.challenge.mapper - -import com.hmh.hamyeonham.challenge.model.NewChallenge -import com.hmh.hamyeonham.core.network.challenge.model.NewChallengeRequest - -fun NewChallengeRequest.toNewChallenge(): NewChallenge { - return NewChallenge( - period = period, - goalTime = goalTime - ) -} - -fun NewChallenge.toNewChallengeRequest(): NewChallengeRequest { - return NewChallengeRequest( - period = period, - goalTime = goalTime - ) -} - diff --git a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/repository/DefaultChallengeRepository.kt b/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/repository/DefaultChallengeRepository.kt index 69ee2561b..3d9673427 100644 --- a/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/repository/DefaultChallengeRepository.kt +++ b/data/challenge/src/main/java/com/hmh/hamyeonham/data/challenge/repository/DefaultChallengeRepository.kt @@ -1,124 +1,38 @@ package com.hmh.hamyeonham.data.challenge.repository import com.hmh.hamyeonham.challenge.model.Apps -import com.hmh.hamyeonham.challenge.model.Challenge -import com.hmh.hamyeonham.challenge.model.ChallengeWithUsageInput -import com.hmh.hamyeonham.challenge.model.NewChallenge import com.hmh.hamyeonham.challenge.repository.ChallengeRepository -import com.hmh.hamyeonham.common.time.currentDate -import com.hmh.hamyeonham.common.time.getDayStartEndEpochMillis -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus -import com.hmh.hamyeonham.core.network.challenge.AppCodeRequest -import com.hmh.hamyeonham.core.network.challenge.ChallengeService -import com.hmh.hamyeonham.core.network.usagegoal.DailyChallengeService import com.hmh.hamyeonham.data.challenge.datasource.ChallengeLocalDatasource -import com.hmh.hamyeonham.data.challenge.mapper.toAppsRequest -import com.hmh.hamyeonham.data.challenge.mapper.toChallengeStatus -import com.hmh.hamyeonham.data.challenge.mapper.toNewChallengeRequest -import com.hmh.hamyeonham.data.challenge.mapper.toRequestChallengeWithUsage -import com.hmh.hamyeonham.usagestats.usecase.GetUsageStatsListUseCase -import kotlinx.datetime.DateTimeUnit -import kotlinx.datetime.LocalDate -import kotlinx.datetime.plus -import kotlinx.datetime.toLocalDate +import timber.log.Timber import javax.inject.Inject class DefaultChallengeRepository @Inject constructor( - private val challengeService: ChallengeService, - private val dailyChallengeService: DailyChallengeService, - private val getUsageStatsListUseCase: GetUsageStatsListUseCase, private val challengeLocalDatasource: ChallengeLocalDatasource, ) : ChallengeRepository { - override suspend fun getChallengeData(): Result { + override suspend fun updateDailyChallengeFailed(): Result { return runCatching { - val challenge = challengeService.getChallengeData().data.toChallengeStatus() - - val challengeWithIndex = challenge.challengeList.mapIndexedNotNull { index, challengeStatus -> - if (challengeStatus != ChallengeStatus.NONE || challenge.todayIndex <= index) { - null - } else { - val dateIndexDifference = index - challenge.todayIndex - val challengeDate = currentDate.plus(dateIndexDifference, DateTimeUnit.DAY) - ChallengeRepository.ChallengeDateWithIndex( - date = challengeDate.toString(), - index = index - ) - } - } - - if (challengeWithIndex.isNotEmpty()) { - val challengeStatus = uploadSavedChallenge(challengeWithIndex).getOrThrow() - challenge.copy(challengeList = challengeStatus ?: challenge.challengeList) - } else { - challenge - } + Timber.d("Update daily challenge failed") } } - override suspend fun updateDailyChallengeFailed(): Result { - return runCatching { dailyChallengeService.updateDailyChallengeFailed().data } - } - override suspend fun deleteAllChallengeWithUsage(): Result { return runCatching { challengeLocalDatasource.deleteAll() } } - override suspend fun insertChallengeWithUsage(challengeWithUsageInput: ChallengeWithUsageInput): Result { - return runCatching {} - } - override suspend fun deleteChallengeWithUsage(challengeDate: String): Result { return runCatching { challengeLocalDatasource.deleteChallengeWithUsage(challengeDate) } } - private suspend fun uploadSavedChallenge(challengeDateWithIndex: List): Result?> { - val challengeWithUsages = getChallengeWithUsage(challengeDateWithIndex).getOrThrow() - return runCatching { - val request = challengeWithUsages.toRequestChallengeWithUsage() - val response = dailyChallengeService.postChallengeWithUsage(request).data - response.statuses?.map { ChallengeStatus.fromString(it) } - } - } - override suspend fun postApps(request: Apps): Result { - return runCatching { challengeService.postApps(request.toAppsRequest()) } + return runCatching { Timber.d("Post apps: $request") } } override suspend fun deleteApps(appCode: String): Result { - return runCatching { challengeService.deleteApps(AppCodeRequest(appCode)) } - } - - override suspend fun generateNewChallenge(request: NewChallenge): Result { - return runCatching { challengeService.postNewChallenge(request.toNewChallengeRequest()) } - } - - private suspend fun getChallengeWithUsage( - challengeDateWithIndex: List - ): Result> { - return runCatching { - challengeDateWithIndex.map { (challengeDate, index) -> - val (startTime, endTime) = getDayStartEndEpochMillis(LocalDate.parse(challengeDate)) - val appUsageList = getUsageStatsListUseCase( - startTime = startTime, - endTime = endTime, - ) - ChallengeWithUsageInput( - challengePeriodIndex = index, - apps = appUsageList.apps.map { - ChallengeWithUsageInput.Usage( - packageName = it.packageName, - usageTime = it.usageTime - ) - }, - ) - } - - - } + return runCatching { Timber.d("Delete app with code: $appCode") } } } \ No newline at end of file diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/remote/UsageGoalsRemoteDataSource.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/remote/UsageGoalsRemoteDataSource.kt deleted file mode 100644 index 39476cb23..000000000 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/remote/UsageGoalsRemoteDataSource.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.hmh.hamyeonham.usagestats.datasource.remote - -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal -import com.hmh.hamyeonham.core.network.challenge.ChallengeService -import com.hmh.hamyeonham.usagestats.mapper.toUsageGoalList -import javax.inject.Inject - -class UsageGoalsRemoteDataSource @Inject constructor( - private val challengeService: ChallengeService, -) { - - suspend fun getUsageGoals(): Result { - return runCatching { challengeService.getChallengeData().data.toUsageGoalList() } - } -} diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt index fef1778e7..0fd0664c5 100644 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt +++ b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt @@ -7,13 +7,12 @@ import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import com.hmh.hamyeonham.usagestats.datasource.local.UsageGoalsLocalDataSource -import com.hmh.hamyeonham.usagestats.datasource.remote.UsageGoalsRemoteDataSource import com.hmh.hamyeonham.usagestats.mapper.toUsageGoalEntityList import kotlinx.coroutines.flow.Flow +import timber.log.Timber import javax.inject.Inject class DefaultUsageGoalsRepository @Inject constructor( - private val usageGoalsRemoteDataSource: UsageGoalsRemoteDataSource, private val usageGoalsLocalDataSource: UsageGoalsLocalDataSource, private val usageGoalsDao: UsageGoalsDao, private val usageTotalGoalDao: UsageTotalGoalDao, @@ -21,24 +20,26 @@ class DefaultUsageGoalsRepository @Inject constructor( override suspend fun updateUsageGoal(): Result { return runCatching { - usageGoalsRemoteDataSource.getUsageGoals().fold( - onSuccess = { usageGoals -> - val totalGoalTime = usageGoals.totalGoalTime - usageTotalGoalDao.insertUsageTotalGoal( - UsageTotalGoalEntity( - totalGoalTime = totalGoalTime, - status = usageGoals.status.name - ) - ) - - // 각 앱 목표 시간 저장 - usageGoalsDao.insertUsageGoalList(usageGoals.toUsageGoalEntityList()) - usageGoals.status.name != ChallengeStatus.FAILURE.name - }, - onFailure = { - false - } - ) +// usageGoalsRemoteDataSource.getUsageGoals().fold( +// onSuccess = { usageGoals -> +// val totalGoalTime = usageGoals.totalGoalTime +// usageTotalGoalDao.insertUsageTotalGoal( +// UsageTotalGoalEntity( +// totalGoalTime = totalGoalTime, +// status = usageGoals.status.name +// ) +// ) +// +// // 각 앱 목표 시간 저장 +// usageGoalsDao.insertUsageGoalList(usageGoals.toUsageGoalEntityList()) +// usageGoals.status.name != ChallengeStatus.FAILURE.name +// }, +// onFailure = { +// false +// } +// ) + Timber.d("Updating usage goals in local data source") + return Result.success(true) } } diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt index 039a88385..292505030 100644 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt +++ b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt @@ -6,16 +6,9 @@ import com.hmh.hamyeonham.challenge.model.ChallengeWithUsageInput import com.hmh.hamyeonham.challenge.model.NewChallenge interface ChallengeRepository { - data class ChallengeDateWithIndex( - val date: String, - val index: Int - ) - suspend fun getChallengeData(): Result suspend fun postApps(request: Apps): Result suspend fun deleteApps(appCode: String): Result - suspend fun generateNewChallenge(request: NewChallenge): Result suspend fun updateDailyChallengeFailed(): Result - suspend fun insertChallengeWithUsage(challengeWithUsageInput: ChallengeWithUsageInput): Result suspend fun deleteChallengeWithUsage(challengeDate: String): Result suspend fun deleteAllChallengeWithUsage(): Result } diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/NewChallengeUseCase.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/NewChallengeUseCase.kt deleted file mode 100644 index f8bb04265..000000000 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/NewChallengeUseCase.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.hmh.hamyeonham.challenge.usecase - -import com.hmh.hamyeonham.challenge.model.NewChallenge -import com.hmh.hamyeonham.challenge.repository.ChallengeRepository -import javax.inject.Inject - -class NewChallengeUseCase @Inject constructor( - private val challengeRepository: ChallengeRepository -) { - suspend operator fun invoke(newChallenge: NewChallenge): Result { - return challengeRepository.generateNewChallenge(newChallenge) - } -} diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/MainActivity.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/MainActivity.kt index 9b2520175..373218771 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/MainActivity.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/MainActivity.kt @@ -21,6 +21,7 @@ import com.hmh.hamyeonham.feature.main.databinding.ActivityMainBinding import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint @@ -103,7 +104,7 @@ class MainActivity : AppCompatActivity() { dismissButtonText = getString(com.hmh.hamyeonham.core.designsystem.R.string.all_cancel), ).apply { setConfirmButtonClickListener { - viewModel.updateDailyChallengeFailed() + Timber.d("Unlock package: $packageName") } setDismissButtonClickListener { intent.removeExtra(NavigationProvider.UN_LOCK_PACKAGE_NAME) From 2816bfed7d4ea8425f88de57f7e21e74af8c0444 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:28:41 +0900 Subject: [PATCH 08/14] =?UTF-8?q?remove:=20usageGoalMapper=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usagestats/mapper/UsageGoalMapper.kt | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt index c32dbfd90..a151a1006 100644 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt +++ b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt @@ -1,21 +1,7 @@ package com.hmh.hamyeonham.usagestats.mapper import com.hmh.hamyeonham.core.database.model.UsageGoalEntity -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal -import com.hmh.hamyeonham.core.network.challenge.model.ChallengeResponse - -internal fun ChallengeResponse.toUsageGoalList(): UsageGoal { - val status = - if (todayIndex > -1) ChallengeStatus.fromString(statuses[todayIndex]) else ChallengeStatus.NONE - return UsageGoal( - status = status, - totalGoalTime = goalTime, - appGoals = apps.map { it.toApp() } - ) -} - -internal fun ChallengeResponse.AppGoal.toApp() = UsageGoal.App(appCode, goalTime) internal fun UsageGoalEntity.toUsageAppGoal() = UsageGoal.App(packageName, goalTime) From 12d93c1fe6d222a2c6f48296dd1a4214e13fbbd1 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:43:29 +0900 Subject: [PATCH 09/14] =?UTF-8?q?remove:=20ChallengeStatus=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/{UsageGoal.kt => AppUsageGoal.kt} | 4 +-- .../domain/usagegoal/model/ChallengeStatus.kt | 21 ----------- .../repository/UsageGoalsRepository.kt | 8 ++--- .../hmh/hamyeonham/core/lock/AppLockManger.kt | 26 +++----------- .../hmh/hamyeonham/core/viewmodel/HomeItem.kt | 1 - .../hamyeonham/core/viewmodel/MainState.kt | 21 +++-------- .../core/viewmodel/MainViewModel.kt | 36 ++----------------- .../local/UsageGoalsLocalDataSource.kt | 15 +++----- .../usagestats/mapper/UsageGoalMapper.kt | 8 ++--- .../repository/DefaultUsageGoalsRepository.kt | 15 ++++---- .../hamyeonham/challenge/model/Challenge.kt | 21 +++-------- .../model/ChallengeWithUsageInput.kt | 11 ------ .../challenge/model/NewChallenge.kt | 6 ---- .../repository/ChallengeRepository.kt | 3 -- .../challenge/usecase/AddUsageGoalsUseCase.kt | 4 +-- .../usagestats/model/UsageStatusAndGoal.kt | 4 +-- .../usecase/GetTotalUsageGoalUseCase.kt | 4 +-- .../usecase/GetTotalUsageStatsUseCase.kt | 6 ++-- .../usecase/GetUsageGoalsUseCase.kt | 4 +-- .../usecase/GetUsageStatsListUseCase.kt | 13 ++----- .../challenge/AppUsageGoalsViewModel.kt | 4 +-- .../main/home/UsageStaticsTotalViewHolder.kt | 8 ++--- 22 files changed, 57 insertions(+), 186 deletions(-) rename core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/{UsageGoal.kt => AppUsageGoal.kt} (64%) delete mode 100644 core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/ChallengeStatus.kt delete mode 100644 domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/ChallengeWithUsageInput.kt delete mode 100644 domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/NewChallenge.kt diff --git a/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/UsageGoal.kt b/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/AppUsageGoal.kt similarity index 64% rename from core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/UsageGoal.kt rename to core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/AppUsageGoal.kt index 826f3710a..924c7c0d9 100644 --- a/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/UsageGoal.kt +++ b/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/AppUsageGoal.kt @@ -1,8 +1,6 @@ package com.hmh.hamyeonham.core.domain.usagegoal.model -data class UsageGoal( - val totalGoalTime:Long = 0, - val status: ChallengeStatus = ChallengeStatus.NONE, +data class AppUsageGoal( val appGoals: List = emptyList() ) { data class App( diff --git a/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/ChallengeStatus.kt b/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/ChallengeStatus.kt deleted file mode 100644 index 9fb2a3c43..000000000 --- a/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/model/ChallengeStatus.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.hmh.hamyeonham.core.domain.usagegoal.model - -enum class ChallengeStatus { - NONE, - UNEARNED, - EARNED, - FAILURE, - TODAY; - companion object { - fun fromString(value: String): ChallengeStatus { - return when (value) { - NONE.name -> NONE - UNEARNED.name -> UNEARNED - EARNED.name -> EARNED - FAILURE.name -> FAILURE - TODAY.name -> TODAY - else -> NONE - } - } - } -} \ No newline at end of file diff --git a/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/repository/UsageGoalsRepository.kt b/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/repository/UsageGoalsRepository.kt index 06dd3f287..fbd784100 100644 --- a/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/repository/UsageGoalsRepository.kt +++ b/core/domain/src/main/java/com/hmh/hamyeonham/core/domain/usagegoal/repository/UsageGoalsRepository.kt @@ -1,12 +1,12 @@ package com.hmh.hamyeonham.core.domain.usagegoal.repository -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import kotlinx.coroutines.flow.Flow interface UsageGoalsRepository { suspend fun updateUsageGoal(): Result - suspend fun getUsageGoals(): Flow - suspend fun addUsageGoal(usageGoal: UsageGoal.App) - suspend fun addUsageGoalList(usageGoalList: List) + suspend fun getUsageGoals(): Flow + suspend fun addUsageGoal(appUsageGoal: AppUsageGoal.App) + suspend fun addUsageGoalList(appUsageGoalList: List) suspend fun deleteUsageGoal(packageName: String) } diff --git a/core/service/src/main/java/com/hmh/hamyeonham/core/lock/AppLockManger.kt b/core/service/src/main/java/com/hmh/hamyeonham/core/lock/AppLockManger.kt index 4eaf46c19..d5f34c9dd 100644 --- a/core/service/src/main/java/com/hmh/hamyeonham/core/lock/AppLockManger.kt +++ b/core/service/src/main/java/com/hmh/hamyeonham/core/lock/AppLockManger.kt @@ -7,10 +7,8 @@ import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.lifecycleScope import com.hmh.hamyeonham.common.navigation.NavigationProvider import com.hmh.hamyeonham.common.time.getCurrentDayStartEndEpochMillis -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.lock.GetIsUnLockUseCase -import com.hmh.hamyeonham.usagestats.usecase.GetTotalUsageGoalUseCase -import com.hmh.hamyeonham.usagestats.usecase.GetTotalUsageStatsUseCase import com.hmh.hamyeonham.usagestats.usecase.GetUsageGoalsUseCase import com.hmh.hamyeonham.usagestats.usecase.GetUsageStatFromPackageUseCase import dagger.hilt.android.qualifiers.ApplicationContext @@ -31,8 +29,6 @@ class AppLockManger @Inject constructor( private val getUsageGoalsUseCase: GetUsageGoalsUseCase, private val getUsageIsLockUseCase: GetIsUnLockUseCase, private val navigationProvider: NavigationProvider, - private val getTotalUsageStatsUseCase: GetTotalUsageStatsUseCase, - private val getTotalUsageGoalUseCase: GetTotalUsageGoalUseCase, ) { private var checkUsageJob: Job? = null private var timerJob: Job? = null @@ -52,41 +48,31 @@ class AppLockManger @Inject constructor( endTime = endTime, packageName = packageName ) - val totalUsageStats = getTotalUsageStatsUseCase( - startTime = startTime, - endTime = endTime, - ) + Log.d("Usage", "packageName: $packageName, usage: $usageStats") val usageGoals = getUsageGoalsUseCase().firstOrNull() ?: return@launch val currentAppGoal = usageGoals.appGoals.find { it.packageName == packageName } ?: return@launch - val totalUsageGoal = getTotalUsageGoalUseCase() checkLockApp( usageStats = usageStats, currentAppGoal = currentAppGoal, packageName = packageName, - totalUsageStats = totalUsageStats, - totalUsageGoal = totalUsageGoal ) } } private suspend fun checkLockApp( usageStats: Long, - currentAppGoal: UsageGoal.App, + currentAppGoal: AppUsageGoal.App, packageName: String, - totalUsageStats: Long, - totalUsageGoal: UsageGoal ) { - if (usageStats >= currentAppGoal.goalTime || totalUsageStats >= totalUsageGoal.totalGoalTime) { + if (usageStats >= currentAppGoal.goalTime) { moveToLock(packageName) } else { releaseTimerJob() val appRemainingTime = currentAppGoal.goalTime - usageStats - val totalRemainingTime = totalUsageGoal.totalGoalTime - totalUsageStats startTimer( appRemainingTime = appRemainingTime, - totalRemainingTime = totalRemainingTime, packageName = packageName ) } @@ -94,12 +80,10 @@ class AppLockManger @Inject constructor( private fun startTimer( appRemainingTime: Long, - totalRemainingTime: Long, packageName: String ) { - val remainingTime = minOf(appRemainingTime, totalRemainingTime) timerJob = ProcessLifecycleOwner.get().lifecycleScope.launch { - delay(remainingTime) + delay(appRemainingTime) moveToLock(packageName) } } diff --git a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/HomeItem.kt b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/HomeItem.kt index 9a386d473..17c9abe3f 100644 --- a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/HomeItem.kt +++ b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/HomeItem.kt @@ -7,7 +7,6 @@ import com.hmh.hamyeonham.usagestats.model.UsageStatusAndGoal sealed class HomeItem { data class TotalModel( val userName: String, - val challengeSuccess: Boolean, val totalGoalTime: Long, val totalTimeInForeground: Long, ) : HomeItem() { diff --git a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainState.kt b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainState.kt index 8e83f9c20..e407fb34c 100644 --- a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainState.kt +++ b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainState.kt @@ -1,22 +1,11 @@ package com.hmh.hamyeonham.core.viewmodel -import com.hmh.hamyeonham.challenge.model.Challenge -import com.hmh.hamyeonham.common.time.getCurrentDateOfDefaultTimeZone -import com.hmh.hamyeonham.common.time.minusDaysFromDate -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal -import kotlinx.datetime.LocalDate +import com.hmh.hamyeonham.challenge.model.AppGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal data class MainState( - val appGoals: List = emptyList(), - val totalGoalTimeInHour: Int = 0, - val period: Int = 0, - val todayIndex: Int = 0, - val usageGoals: UsageGoal = UsageGoal(), + val appGoals: List = emptyList(), + val appUsageGoals: AppUsageGoal = AppUsageGoal(), val name: String = "", - val challengeSuccess: Boolean = true, var permissionGranted: Boolean = true, -) { - val startDate: LocalDate = minusDaysFromDate(getCurrentDateOfDefaultTimeZone(), todayIndex) - val isChallengeExist: Boolean = todayIndex != -1 - val todayIndexAsDate: Int = todayIndex + 1 -} \ No newline at end of file +) \ No newline at end of file diff --git a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt index 2fbbe003b..871f566a6 100644 --- a/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt +++ b/core/viewmodel/main/src/main/java/com/hmh/hamyeonham/core/viewmodel/MainViewModel.kt @@ -2,10 +2,8 @@ package com.hmh.hamyeonham.core.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.hmh.hamyeonham.challenge.model.Challenge import com.hmh.hamyeonham.common.time.getCurrentDayStartEndEpochMillis -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import com.hmh.hamyeonham.domain.main.MainRepository import com.hmh.hamyeonham.lock.UpdateIsUnLockUseCase @@ -50,12 +48,6 @@ class MainViewModel @Inject constructor( combineHomeItems(bannerModel, usageStatusAndGoals) }.stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) - - private var rawChallengeList: List = emptyList() - private val _challengeList = MutableStateFlow>(emptyList()) - val challengeStatusList = _challengeList.asStateFlow() - - private val _effect = MutableSharedFlow() val effect = _effect.asSharedFlow() @@ -66,7 +58,6 @@ class MainViewModel @Inject constructor( } viewModelScope.launch(Dispatchers.Main) { - updateGoals() getUserInfo() getUsageGoalAndStatList() } @@ -92,13 +83,6 @@ class MainViewModel @Inject constructor( } } - private suspend fun updateGoals() { - usageGoalsRepository.updateUsageGoal() - .onSuccess { - updateState { copy(challengeSuccess = it) } - } - } - private fun getUsageGoalAndStatList() { viewModelScope.launch { usageGoalsRepository.getUsageGoals().collect { @@ -122,23 +106,10 @@ class MainViewModel @Inject constructor( } } - private fun setUsageGaols(usageGoals: UsageGoal) { + private fun setUsageGaols(appUsageGoals: AppUsageGoal) { updateState { - copy(usageGoals = usageGoals) - } - } - - private fun setChallengeStatus(challenge: Challenge) { - updateState { - copy( - appGoals = challenge.appGoals, - totalGoalTimeInHour = challenge.goalTimeInHours, - period = challenge.period, - todayIndex = challenge.todayIndex, - ) + copy(appUsageGoals = appUsageGoals) } - rawChallengeList = challenge.challengeList - _challengeList.value = challenge.challengeList } private fun updateUserInfo(userInfo: UserInfo) { @@ -173,7 +144,6 @@ class MainViewModel @Inject constructor( items.add( HomeItem.TotalModel( userName = mainState.value.name, - challengeSuccess = mainState.value.challengeSuccess, totalGoalTime = usageStatusAndGoal.totalGoalTime, totalTimeInForeground = usageStatusAndGoal.totalTimeInForeground, ) diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt index 06daf71b4..6a5e2c9da 100644 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt +++ b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt @@ -3,8 +3,7 @@ package com.hmh.hamyeonham.usagestats.datasource.local import com.hmh.hamyeonham.core.database.dao.UsageGoalsDao import com.hmh.hamyeonham.core.database.dao.UsageTotalGoalDao import com.hmh.hamyeonham.core.database.model.UsageGoalEntity -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.usagestats.mapper.toUsageAppGoal import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -14,17 +13,13 @@ import javax.inject.Inject class UsageGoalsLocalDataSource @Inject constructor( private val usageGoalsDao: UsageGoalsDao, - private val usageTotalGoalDao: UsageTotalGoalDao, ) { @OptIn(ExperimentalCoroutinesApi::class) - suspend fun getUsageGoal(): Flow { + fun getUsageGoal(): Flow { return usageGoalsDao.getUsageGoal() .flatMapConcat { goalsList -> flow { - val totalGoal = usageTotalGoalDao.getUsageTotalGoal() - val result = UsageGoal( - totalGoalTime = totalGoal?.totalGoalTime ?: 0, - status = ChallengeStatus.fromString(totalGoal?.status.orEmpty()), + val result = AppUsageGoal( appGoals = goalsList.map { it.toUsageAppGoal() } ) emit(result) @@ -32,7 +27,7 @@ class UsageGoalsLocalDataSource @Inject constructor( } } - suspend fun addUsageAppGoal(usageAppGoal: UsageGoal.App) { + suspend fun addUsageAppGoal(usageAppGoal: AppUsageGoal.App) { usageGoalsDao.insertUsageGoal( UsageGoalEntity( usageAppGoal.packageName, @@ -41,7 +36,7 @@ class UsageGoalsLocalDataSource @Inject constructor( ) } - suspend fun addUsageGoalList(usageAppGoalList: List) { + suspend fun addUsageGoalList(usageAppGoalList: List) { usageGoalsDao.insertUsageGoalList(usageAppGoalList.map { UsageGoalEntity( it.packageName, diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt index a151a1006..b1124c2c9 100644 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt +++ b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/mapper/UsageGoalMapper.kt @@ -1,10 +1,10 @@ package com.hmh.hamyeonham.usagestats.mapper import com.hmh.hamyeonham.core.database.model.UsageGoalEntity -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal -internal fun UsageGoalEntity.toUsageAppGoal() = UsageGoal.App(packageName, goalTime) +internal fun UsageGoalEntity.toUsageAppGoal() = AppUsageGoal.App(packageName, goalTime) -internal fun UsageGoal.App.toUsageGoalEntity() = UsageGoalEntity(packageName, goalTime) +internal fun AppUsageGoal.App.toUsageGoalEntity() = UsageGoalEntity(packageName, goalTime) -internal fun UsageGoal.toUsageGoalEntityList() = appGoals.map { it.toUsageGoalEntity() } +internal fun AppUsageGoal.toUsageGoalEntityList() = appGoals.map { it.toUsageGoalEntity() } diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt index 0fd0664c5..a3732fefa 100644 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt +++ b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/repository/DefaultUsageGoalsRepository.kt @@ -2,12 +2,9 @@ package com.hmh.hamyeonham.usagestats.repository import com.hmh.hamyeonham.core.database.dao.UsageGoalsDao import com.hmh.hamyeonham.core.database.dao.UsageTotalGoalDao -import com.hmh.hamyeonham.core.database.model.UsageTotalGoalEntity -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import com.hmh.hamyeonham.usagestats.datasource.local.UsageGoalsLocalDataSource -import com.hmh.hamyeonham.usagestats.mapper.toUsageGoalEntityList import kotlinx.coroutines.flow.Flow import timber.log.Timber import javax.inject.Inject @@ -43,16 +40,16 @@ class DefaultUsageGoalsRepository @Inject constructor( } } - override suspend fun getUsageGoals(): Flow { + override suspend fun getUsageGoals(): Flow { return usageGoalsLocalDataSource.getUsageGoal() } - override suspend fun addUsageGoal(usageGoal: UsageGoal.App) { - usageGoalsLocalDataSource.addUsageAppGoal(usageGoal) + override suspend fun addUsageGoal(appUsageGoal: AppUsageGoal.App) { + usageGoalsLocalDataSource.addUsageAppGoal(appUsageGoal) } - override suspend fun addUsageGoalList(usageGoalList: List) { - usageGoalsLocalDataSource.addUsageGoalList(usageGoalList) + override suspend fun addUsageGoalList(appUsageGoalList: List) { + usageGoalsLocalDataSource.addUsageGoalList(appUsageGoalList) } override suspend fun deleteUsageGoal(packageName: String) { diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/Challenge.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/Challenge.kt index 1d3caa497..460e6442f 100644 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/Challenge.kt +++ b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/Challenge.kt @@ -1,19 +1,6 @@ package com.hmh.hamyeonham.challenge.model -import com.hmh.hamyeonham.core.domain.usagegoal.model.ChallengeStatus - -data class Challenge( - val appGoals: List = emptyList(), - val challengeList: List = emptyList(), - val goalTime: Long = 0, - val period: Int = 0, - val todayIndex: Int = 0, -) { - data class AppGoal( - val appCode: String, - val appGoalTime: Long, - ) - - val goalTimeInHours: Int - get() = (goalTime / 1000 / 60 / 60).toInt() -} +data class AppGoal( + val appCode: String, + val appGoalTime: Long, +) diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/ChallengeWithUsageInput.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/ChallengeWithUsageInput.kt deleted file mode 100644 index f4b31da13..000000000 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/ChallengeWithUsageInput.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.hmh.hamyeonham.challenge.model - -data class ChallengeWithUsageInput( - val challengePeriodIndex: Int, - val apps: List -) { - data class Usage( - val packageName: String, - val usageTime: Long - ) -} diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/NewChallenge.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/NewChallenge.kt deleted file mode 100644 index 23f5969ab..000000000 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/model/NewChallenge.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.hmh.hamyeonham.challenge.model - -data class NewChallenge( - val period: Int, - val goalTime: Long -) \ No newline at end of file diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt index 292505030..f322893a9 100644 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt +++ b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/repository/ChallengeRepository.kt @@ -1,9 +1,6 @@ package com.hmh.hamyeonham.challenge.repository import com.hmh.hamyeonham.challenge.model.Apps -import com.hmh.hamyeonham.challenge.model.Challenge -import com.hmh.hamyeonham.challenge.model.ChallengeWithUsageInput -import com.hmh.hamyeonham.challenge.model.NewChallenge interface ChallengeRepository { suspend fun postApps(request: Apps): Result diff --git a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/AddUsageGoalsUseCase.kt b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/AddUsageGoalsUseCase.kt index 2e39b100e..507317104 100644 --- a/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/AddUsageGoalsUseCase.kt +++ b/domain/challenge/src/main/java/com/hmh/hamyeonham/challenge/usecase/AddUsageGoalsUseCase.kt @@ -2,7 +2,7 @@ package com.hmh.hamyeonham.challenge.usecase import com.hmh.hamyeonham.challenge.model.Apps import com.hmh.hamyeonham.challenge.repository.ChallengeRepository -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import javax.inject.Inject @@ -14,7 +14,7 @@ class AddUsageGoalsUseCase @Inject constructor( challengeRepository.postApps(apps).onSuccess { usageGoalsRepository.addUsageGoalList( apps.apps.map { - UsageGoal.App(it.appCode, it.goalTime) + AppUsageGoal.App(it.appCode, it.goalTime) } ) } diff --git a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/model/UsageStatusAndGoal.kt b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/model/UsageStatusAndGoal.kt index 0dc7d496c..777538395 100644 --- a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/model/UsageStatusAndGoal.kt +++ b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/model/UsageStatusAndGoal.kt @@ -1,6 +1,6 @@ package com.hmh.hamyeonham.usagestats.model -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal data class UsageStatusAndGoal( val totalTimeInForeground: Long = 0, @@ -30,7 +30,7 @@ data class UsageStatusAndGoal( } companion object { - fun List.toApps(): List { + fun List.toApps(): List { return map { App( packageName = it.packageName, diff --git a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageGoalUseCase.kt b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageGoalUseCase.kt index 9c37bc654..0e8ae21aa 100644 --- a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageGoalUseCase.kt +++ b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageGoalUseCase.kt @@ -1,6 +1,6 @@ package com.hmh.hamyeonham.usagestats.usecase -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import kotlinx.coroutines.flow.first import javax.inject.Inject @@ -8,7 +8,7 @@ import javax.inject.Inject class GetTotalUsageGoalUseCase @Inject constructor( private val usageGoalsRepository: UsageGoalsRepository, ) { - suspend operator fun invoke(): UsageGoal { + suspend operator fun invoke(): AppUsageGoal { return usageGoalsRepository.getUsageGoals().first() } } diff --git a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageStatsUseCase.kt b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageStatsUseCase.kt index d1a680e19..d9b191a85 100644 --- a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageStatsUseCase.kt +++ b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetTotalUsageStatsUseCase.kt @@ -1,6 +1,6 @@ package com.hmh.hamyeonham.usagestats.usecase -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import com.hmh.hamyeonham.usagestats.model.UsageStatus import com.hmh.hamyeonham.usagestats.model.sumUsageStats @@ -41,7 +41,7 @@ class GetTotalUsageStatsUseCase @Inject constructor( return usageStatsRepository.getUsageStatForPackages(startTime, endTime, packageNames) } - private fun getPackageNamesFromUsageGoals(usageGoals: UsageGoal): List { - return usageGoals.appGoals.map { it.packageName } + private fun getPackageNamesFromUsageGoals(appUsageGoals: AppUsageGoal): List { + return appUsageGoals.appGoals.map { it.packageName } } } diff --git a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageGoalsUseCase.kt b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageGoalsUseCase.kt index a77741256..1569c8298 100644 --- a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageGoalsUseCase.kt +++ b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageGoalsUseCase.kt @@ -1,6 +1,6 @@ package com.hmh.hamyeonham.usagestats.usecase -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject @@ -8,7 +8,7 @@ import javax.inject.Inject class GetUsageGoalsUseCase @Inject constructor( private val usageGoalsRepository: UsageGoalsRepository, ) { - suspend operator fun invoke(): Flow { + suspend operator fun invoke(): Flow { return usageGoalsRepository.getUsageGoals() } } diff --git a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageStatsListUseCase.kt b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageStatsListUseCase.kt index f8985f9f9..5e95df703 100644 --- a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageStatsListUseCase.kt +++ b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/GetUsageStatsListUseCase.kt @@ -1,6 +1,6 @@ package com.hmh.hamyeonham.usagestats.usecase -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.core.domain.usagegoal.repository.UsageGoalsRepository import com.hmh.hamyeonham.usagestats.model.UsageStatus import com.hmh.hamyeonham.usagestats.model.UsageStatusAndGoal @@ -31,7 +31,6 @@ class GetUsageStatsListUseCase @Inject constructor( val usageStatusAndGoal = UsageStatusAndGoal( totalTimeInForeground = totalUsage, - totalGoalTime = usageGoal.totalGoalTime, apps = usageGoal.appGoals.map { UsageStatusAndGoal.App( packageName = it.packageName, @@ -45,12 +44,6 @@ class GetUsageStatsListUseCase @Inject constructor( } } - private fun getUsageGoalForPackage( - usageGoalsForSelectedPackages: UsageGoal, - ): Long { - return usageGoalsForSelectedPackages.totalGoalTime - } - private suspend fun getUsageStatsAndGoalsForSelectedPackages( startTime: Long, endTime: Long, @@ -59,6 +52,6 @@ class GetUsageStatsListUseCase @Inject constructor( return usageStatsRepository.getUsageStatForPackages(startTime, endTime, selectedPackages) } - private fun getSelectedPackageList(usageGoalList: UsageGoal): List = - usageGoalList.appGoals.map { it.packageName }.distinct() + private fun getSelectedPackageList(appUsageGoalList: AppUsageGoal): List = + appUsageGoalList.appGoals.map { it.packageName }.distinct() } diff --git a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsViewModel.kt b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsViewModel.kt index 1acb7c81b..f8fa85f46 100644 --- a/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsViewModel.kt +++ b/feature/challenge/src/main/java/com/hmh/hamyeonham/challenge/AppUsageGoalsViewModel.kt @@ -6,7 +6,7 @@ import com.hmh.hamyeonham.challenge.model.Apps import com.hmh.hamyeonham.challenge.usecase.AddUsageGoalsUseCase import com.hmh.hamyeonham.challenge.usecase.DeleteUsageGoalUseCase import com.hmh.hamyeonham.common.amplitude.AmplitudeUtils -import com.hmh.hamyeonham.core.domain.usagegoal.model.UsageGoal +import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.usagestats.model.UsageStatusAndGoal import com.hmh.hamyeonham.usagestats.usecase.CheckAndDeleteDeletedAppUsageUseCase import com.hmh.hamyeonham.usagestats.usecase.DeletedAppUsageStoreUseCase @@ -17,7 +17,7 @@ import kotlinx.coroutines.launch import javax.inject.Inject data class ChallengeState( - val usageGoals: List = emptyList(), + val appUsageGoals: List = emptyList(), val modifierState: ModifierState = ModifierState.DONE, val usageStatusAndGoals: UsageStatusAndGoal = UsageStatusAndGoal(), ) { diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt index bc4f75106..bd620cc3d 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt @@ -53,10 +53,10 @@ class UsageStaticsTotalViewHolder( private fun bindBlackHoleInfo(totalModel: HomeItem.TotalModel) { val blackHoleInfo = when { // 챌린지 성공한 경우 - totalModel.challengeSuccess -> { - BlackHoleInfo.createByPercentage(totalModel.totalPercentage) - ?: BlackHoleInfo.LEVEL0 - } +// totalModel.challengeSuccess -> { +// BlackHoleInfo.createByPercentage(totalModel.totalPercentage) +// ?: BlackHoleInfo.LEVEL0 +// } // 챌린지 실패한 경우 else -> { BlackHoleInfo.LEVEL5 From a91c33b17fab7d2903f88dcf494d85960a95cc6c Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:49:07 +0900 Subject: [PATCH 10/14] =?UTF-8?q?remove:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20s?= =?UTF-8?q?tring=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../local/UsageGoalsLocalDataSource.kt | 1 - .../challenge/src/main/res/values/strings.xml | 30 ------------------- .../main/home/UsageStaticsTotalViewHolder.kt | 6 +--- .../res/layout/item_usagestatic_total.xml | 18 +++++------ feature/main/src/main/res/values/strings.xml | 1 - 5 files changed, 10 insertions(+), 46 deletions(-) diff --git a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt index 6a5e2c9da..569e59e07 100644 --- a/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt +++ b/data/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/datasource/local/UsageGoalsLocalDataSource.kt @@ -1,7 +1,6 @@ package com.hmh.hamyeonham.usagestats.datasource.local import com.hmh.hamyeonham.core.database.dao.UsageGoalsDao -import com.hmh.hamyeonham.core.database.dao.UsageTotalGoalDao import com.hmh.hamyeonham.core.database.model.UsageGoalEntity import com.hmh.hamyeonham.core.domain.usagegoal.model.AppUsageGoal import com.hmh.hamyeonham.usagestats.mapper.toUsageAppGoal diff --git a/feature/challenge/src/main/res/values/strings.xml b/feature/challenge/src/main/res/values/strings.xml index f5dddc465..1adc20ca8 100644 --- a/feature/challenge/src/main/res/values/strings.xml +++ b/feature/challenge/src/main/res/values/strings.xml @@ -1,44 +1,14 @@ - 챌린지 - 총 목표 이용 시간 - %d월 %d일 시작부터 - %d일차 잠금 앱 잠금 추가할 앱을 검색해 주세요 선택 완료 - 별을 향한 새로운\n챌린지를 생성해 주세요 - 챌린지 생성하기 시간 달력 배경 이미지 - 오늘 날짜 마커 이미 - 챌린지 상태 달력 배경 이미지 쓰레기통 이미지 5분 넘게 사용한 앱은 삭제할 수 없어요 - +%sP - %s일 챌린지 - %s일차 보상 - 포인트를 다 받은 후 챌린지를 생성하세요 - 이동 - - 다음 - 챌린지 기간을 선택해 주세요 - 첫 챌린지로 가볍게 도전하기 좋은 7일을 추천해요 - 7일 - 14일 - 20일 - 30일 - - 총 목표 사용 시간을\n설정해 주세요 - 목표 사용 시간은 최대 6시간까지 설정할 수 있어요 - 접기 "\u25B2" - 펼치기 "\u25BC" - - 새로운 챌린지 생성 완료! - 별조각을 모아\n블랙홀 탈출에 성공하세요 - 새 챌린지 출발! diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt index bd620cc3d..037dac8d7 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt @@ -35,11 +35,7 @@ class UsageStaticsTotalViewHolder( secondStr = getString(context, R.string.all_left), color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, ) - tvTotalGoal.text = - context.getString( - R.string.total_goal_time_format, - convertMillisecondToString(totalModel.totalGoalTime) - ) + tvTotalUsage.text = context.getString( R.string.total_used, diff --git a/feature/main/src/main/res/layout/item_usagestatic_total.xml b/feature/main/src/main/res/layout/item_usagestatic_total.xml index 14ce26487..384890543 100644 --- a/feature/main/src/main/res/layout/item_usagestatic_total.xml +++ b/feature/main/src/main/res/layout/item_usagestatic_total.xml @@ -50,15 +50,15 @@ app:layout_constraintBottom_toBottomOf="@id/lav_blackhole" app:layout_constraintStart_toStartOf="@id/pb_total_usage" /> - + + + + + + + + + 내 이용시간 마이페이지 HMH - 목표 사용 시간 %s 중 %s 사용 남음 image of app icon From 6632afca3d8923db577e9eb2b8c566e69890b325 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:51:38 +0900 Subject: [PATCH 11/14] =?UTF-8?q?remove:=20=ED=99=88=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EB=AA=A9=ED=91=9C=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=A4=91=20=EB=82=A8=EC=9D=80=20=EC=8B=9C=EA=B0=84=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/home/UsageStaticsViewHolder.kt | 12 +++++----- .../src/main/res/layout/item_usagestatic.xml | 22 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt index a498b57cd..d2741bfc0 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt @@ -40,12 +40,12 @@ class UsageStaticsViewHolder( binding.run { pbAppUsage.progress = usageStatusAndGoal.usedPercentage tvGoalTime.text = convertTimeToString(usageStatusAndGoal.goalTimeInMinute) - tvAppTimeLeft.text = - context.getSecondStrColoredString( - firstStr = convertTimeToString(usageStatusAndGoal.timeLeftInMinute), - secondStr = getString(context, R.string.all_left), - color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, - ) +// tvAppTimeLeft.text = +// context.getSecondStrColoredString( +// firstStr = convertTimeToString(usageStatusAndGoal.timeLeftInMinute), +// secondStr = getString(context, R.string.all_left), +// color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, +// ) } } } diff --git a/feature/main/src/main/res/layout/item_usagestatic.xml b/feature/main/src/main/res/layout/item_usagestatic.xml index 5c6e40ace..5d4b30566 100644 --- a/feature/main/src/main/res/layout/item_usagestatic.xml +++ b/feature/main/src/main/res/layout/item_usagestatic.xml @@ -53,16 +53,16 @@ app:layout_constraintBottom_toBottomOf="@id/iv_appicon" app:layout_constraintStart_toStartOf="@id/tv_appname" /> - + + + + + + + + + + + From 0159fc37b3de3cb9f803c219d2eab4e3750f9729 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:52:38 +0900 Subject: [PATCH 12/14] =?UTF-8?q?remove:=20=ED=99=88=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EB=AA=A9=ED=91=9C=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=A4=91=20=EB=82=A8=EC=9D=80=20=EC=8B=9C=EA=B0=84=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/home/UsageStaticsTotalViewHolder.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt index 037dac8d7..ce65412f7 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt @@ -26,15 +26,15 @@ class UsageStaticsTotalViewHolder( private fun bindUsageStaticsInfo(totalModel: HomeItem.TotalModel) { binding.run { - val totalTimeLeft = - if (totalModel.totalGoalTime > totalModel.totalTimeInForeground) totalModel.totalGoalTime - totalModel.totalTimeInForeground else 0 - - tvTotalTimeLeft.text = - context.getSecondStrColoredString( - firstStr = convertMillisecondToString(totalTimeLeft), - secondStr = getString(context, R.string.all_left), - color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, - ) +// val totalTimeLeft = +// if (totalModel.totalGoalTime > totalModel.totalTimeInForeground) totalModel.totalGoalTime - totalModel.totalTimeInForeground else 0 +// +// tvTotalTimeLeft.text = +// context.getSecondStrColoredString( +// firstStr = convertMillisecondToString(totalTimeLeft), +// secondStr = getString(context, R.string.all_left), +// color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, +// ) tvTotalUsage.text = context.getString( From d49a74e56ca25a560cdea5f742a20f04aa76486a Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Mon, 18 Aug 2025 23:55:49 +0900 Subject: [PATCH 13/14] =?UTF-8?q?remove:=20=EB=B0=94=ED=85=80=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20>=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EB=AA=85=20?= =?UTF-8?q?=EC=95=B1=20=EC=84=A4=EC=A0=95=EC=9C=BC=EB=A1=9C=20=EB=B0=94?= =?UTF-8?q?=EA=BF=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/challenge/src/main/res/layout/fragment_challenge.xml | 2 +- feature/main/src/main/res/menu/bottom_nav_menu.xml | 2 +- feature/main/src/main/res/values/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/challenge/src/main/res/layout/fragment_challenge.xml b/feature/challenge/src/main/res/layout/fragment_challenge.xml index f9231abd2..91f739ea6 100644 --- a/feature/challenge/src/main/res/layout/fragment_challenge.xml +++ b/feature/challenge/src/main/res/layout/fragment_challenge.xml @@ -22,7 +22,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginVertical="18dp" - android:text="@string/challenge" + android:text="@string/app_setting" android:textAppearance="?textAppearanceTitleLarge" android:textColor="?gray1" app:layout_constraintBottom_toBottomOf="parent" diff --git a/feature/main/src/main/res/menu/bottom_nav_menu.xml b/feature/main/src/main/res/menu/bottom_nav_menu.xml index d1752d3dc..4100b76cc 100644 --- a/feature/main/src/main/res/menu/bottom_nav_menu.xml +++ b/feature/main/src/main/res/menu/bottom_nav_menu.xml @@ -2,7 +2,7 @@ + android:title="@string/app_setting" /> - 챌린지 + 앱 설정 내 이용시간 마이페이지 From 8ddaa48ad6c2ed6039ec73726b030798d6e458a4 Mon Sep 17 00:00:00 2001 From: kangyuri1114 Date: Tue, 19 Aug 2025 00:15:22 +0900 Subject: [PATCH 14/14] =?UTF-8?q?remove:=20=EB=82=A8=EC=9D=80=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecase/AddUsageGoalsUseCase.kt | 0 .../main/home/UsageStaticsTotalViewHolder.kt | 18 +++++++-------- .../main/home/UsageStaticsViewHolder.kt | 12 +++++----- .../src/main/res/layout/item_usagestatic.xml | 22 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) delete mode 100644 domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/AddUsageGoalsUseCase.kt diff --git a/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/AddUsageGoalsUseCase.kt b/domain/usagestats/src/main/java/com/hmh/hamyeonham/usagestats/usecase/AddUsageGoalsUseCase.kt deleted file mode 100644 index e69de29bb..000000000 diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt index ce65412f7..037dac8d7 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsTotalViewHolder.kt @@ -26,15 +26,15 @@ class UsageStaticsTotalViewHolder( private fun bindUsageStaticsInfo(totalModel: HomeItem.TotalModel) { binding.run { -// val totalTimeLeft = -// if (totalModel.totalGoalTime > totalModel.totalTimeInForeground) totalModel.totalGoalTime - totalModel.totalTimeInForeground else 0 -// -// tvTotalTimeLeft.text = -// context.getSecondStrColoredString( -// firstStr = convertMillisecondToString(totalTimeLeft), -// secondStr = getString(context, R.string.all_left), -// color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, -// ) + val totalTimeLeft = + if (totalModel.totalGoalTime > totalModel.totalTimeInForeground) totalModel.totalGoalTime - totalModel.totalTimeInForeground else 0 + + tvTotalTimeLeft.text = + context.getSecondStrColoredString( + firstStr = convertMillisecondToString(totalTimeLeft), + secondStr = getString(context, R.string.all_left), + color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, + ) tvTotalUsage.text = context.getString( diff --git a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt index d2741bfc0..a498b57cd 100644 --- a/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt +++ b/feature/main/src/main/java/com/hmh/hamyeonham/feature/main/home/UsageStaticsViewHolder.kt @@ -40,12 +40,12 @@ class UsageStaticsViewHolder( binding.run { pbAppUsage.progress = usageStatusAndGoal.usedPercentage tvGoalTime.text = convertTimeToString(usageStatusAndGoal.goalTimeInMinute) -// tvAppTimeLeft.text = -// context.getSecondStrColoredString( -// firstStr = convertTimeToString(usageStatusAndGoal.timeLeftInMinute), -// secondStr = getString(context, R.string.all_left), -// color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, -// ) + tvAppTimeLeft.text = + context.getSecondStrColoredString( + firstStr = convertTimeToString(usageStatusAndGoal.timeLeftInMinute), + secondStr = getString(context, R.string.all_left), + color = com.hmh.hamyeonham.core.designsystem.R.color.gray1, + ) } } } diff --git a/feature/main/src/main/res/layout/item_usagestatic.xml b/feature/main/src/main/res/layout/item_usagestatic.xml index 5d4b30566..5c6e40ace 100644 --- a/feature/main/src/main/res/layout/item_usagestatic.xml +++ b/feature/main/src/main/res/layout/item_usagestatic.xml @@ -53,16 +53,16 @@ app:layout_constraintBottom_toBottomOf="@id/iv_appicon" app:layout_constraintStart_toStartOf="@id/tv_appname" /> - - - - - - - - - - - +