Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat/challenge]: 챌린지 기초 작업 #66

Merged
merged 19 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/designsystem/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@

<!-- Other Colors -->
<color name="white_btn">#EBECF4</color>
</resources>
</resources>
1 change: 1 addition & 0 deletions core/viewmodel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
Empty file.
1 change: 1 addition & 0 deletions core/viewmodel/main/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
19 changes: 19 additions & 0 deletions core/viewmodel/main/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
hmh("feature")
}


android {
namespace = "com.hmh.hamyeonham.core.main"
}

dependencies {

implementation(projects.domain.challenge)

implementation(projects.core.common)
testImplementation("androidx.arch.core:core-testing:2.2.0")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4")

}
Empty file.
21 changes: 21 additions & 0 deletions core/viewmodel/main/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
4 changes: 4 additions & 0 deletions core/viewmodel/main/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.hmh.hamyeonham.core

import androidx.lifecycle.ViewModel
import com.hmh.hamyeonham.challenge.model.ChallengeStatus
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject

data class MainState(
val challengeStatus: ChallengeStatus
)

@HiltViewModel
class MainViewModel @Inject constructor() : ViewModel() {
private val _mainState = MutableStateFlow(MainState(ChallengeStatus()))
val mainState = _mainState.asStateFlow()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mainState에 MainViewModel에서 사용하는 여러 dataFlow를 저장하는 건가요?


fun setChallengeStatus(challengeStatus: ChallengeStatus) {
_mainState.value = _mainState.value.copy(challengeStatus = challengeStatus)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.hmh.hamyeonham.core.main

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.hmh.hamyeonham.challenge.model.ChallengeStatus
import com.hmh.hamyeonham.core.MainViewModel
import junit.framework.TestCase.assertEquals
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestRule

class MainViewModelTest {

@get:Rule
var rule: TestRule = InstantTaskExecutorRule()

@Test
fun `setChallengeStatus가 호출될 때 mainState가 제대로 업데이트 되는지 테스트`() = runTest {
val viewModel = MainViewModel()
val testChallengeStatus = ChallengeStatus()

viewModel.setChallengeStatus(testChallengeStatus)

val updatedState = viewModel.mainState.first()
assertEquals(testChallengeStatus, updatedState.challengeStatus)
}
}
21 changes: 21 additions & 0 deletions core/viewmodel/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
1 change: 1 addition & 0 deletions domain/challenge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
7 changes: 7 additions & 0 deletions domain/challenge/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
`java-library`
kotlin("jvm")
}

dependencies {}
Empty file.
21 changes: 21 additions & 0 deletions domain/challenge/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
4 changes: 4 additions & 0 deletions domain/challenge/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hmh.hamyeonham.challenge.model


data class ChallengeStatus(
val apps: List<App> = emptyList(),
val isSuccessList: List<Boolean?> = emptyList(),
val goalTime: Int = 0,
val period: Int = 0,
) {
data class App(
val appCode: String,
val appGoalTime: Int
)
}

This file was deleted.

1 change: 1 addition & 0 deletions feature/challenge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
17 changes: 17 additions & 0 deletions feature/challenge/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
hmh("feature")
}

android {
namespace = "com.hmh.hamyeonham.feature.challenge"
}

dependencies {

implementation(projects.domain.challenge)

implementation(projects.core.common)
implementation(projects.core.designsystem)
implementation(projects.core.viewmodel.main)
}
Empty file.
21 changes: 21 additions & 0 deletions feature/challenge/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
4 changes: 4 additions & 0 deletions feature/challenge/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.hmh.hamyeonham.challenge

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.hmh.hamyeonham.common.view.ItemDiffCallback
import com.hmh.hamyeonham.feature.challenge.R
import com.hmh.hamyeonham.feature.challenge.databinding.ItemChallengeStatusBinding

class ChallengeCalendarAdapter :
ListAdapter<Boolean, ChallengeCalendarAdapter.ChallengeStatusViewHolder>(
ItemDiffCallback<Boolean>(
onItemsTheSame = { oldItem, newItem ->
oldItem == newItem
},
onContentsTheSame = { oldItem, newItem ->
oldItem == newItem
}
)
) {
class ChallengeStatusViewHolder(
private val binding: ItemChallengeStatusBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(isSuccess: Boolean?, position: Int) {
binding.apply {
val date = (position + 1).toString()
tvDate.text = date
ivChallengeStatus.setImageResource(getDrawableResource(isSuccess))
}
}

private fun getDrawableResource(isSuccess: Boolean?): Int {
return when (isSuccess) {
true -> R.drawable.ic_challenge_success
false -> R.drawable.ic_challenge_fail
else -> R.drawable.challenge_shape_background_radius8
kez-lab marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChallengeStatusViewHolder {
return ChallengeStatusViewHolder(
ItemChallengeStatusBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}

override fun onBindViewHolder(holder: ChallengeStatusViewHolder, position: Int) {
holder.bind(currentList.getOrNull(position), position)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.hmh.hamyeonham.challenge

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import com.hmh.hamyeonham.common.fragment.viewLifeCycle
import com.hmh.hamyeonham.common.fragment.viewLifeCycleScope
import com.hmh.hamyeonham.common.view.viewBinding
import com.hmh.hamyeonham.core.MainViewModel
import com.hmh.hamyeonham.feature.challenge.databinding.FragmentChallengeBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class ChallengeFragment : Fragment() {

private val binding by viewBinding(FragmentChallengeBinding::bind)
private val activityViewModel by activityViewModels<MainViewModel>()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
return FragmentChallengeBinding.inflate(inflater, container, false).root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initChallengeRecyclerView()
collectMainState()
}

private fun collectMainState() {
val challengeAdapter = binding.rvChallengeCalendar.adapter as? ChallengeCalendarAdapter
activityViewModel.mainState.flowWithLifecycle(viewLifeCycle).onEach {
challengeAdapter?.submitList(it.challengeStatus.isSuccessList)
}.launchIn(viewLifeCycleScope)

kez-lab marked this conversation as resolved.
Show resolved Hide resolved
}

private fun initChallengeRecyclerView() {
binding.rvChallengeCalendar.run {
layoutManager = GridLayoutManager(requireContext(), 7)
adapter = ChallengeCalendarAdapter()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

<solid android:color="@color/blackground" />
<corners android:radius="8dp" />

</shape>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<vector android:height="24dp" android:viewportHeight="25"
android:viewportWidth="25" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0.84,0.219h24v24h-24z"/>
<path android:fillColor="#50505E" android:fillType="evenOdd" android:pathData="M24.839,12.219C24.839,18.846 19.466,24.219 12.839,24.219C6.211,24.219 0.839,18.846 0.839,12.219C0.839,5.591 6.211,0.219 12.839,0.219C19.466,0.219 24.839,5.591 24.839,12.219ZM12.839,21.273C17.839,21.273 21.893,17.219 21.893,12.219C21.893,7.218 17.839,3.164 12.839,3.164C7.838,3.164 3.784,7.218 3.784,12.219C3.784,17.219 7.838,21.273 12.839,21.273ZM12.839,22.458C18.494,22.458 23.078,17.874 23.078,12.219C23.078,6.564 18.494,1.979 12.839,1.979C7.184,1.979 2.599,6.564 2.599,12.219C2.599,17.874 7.184,22.458 12.839,22.458ZM12.052,16.793V18.506L12.055,18.508H13.627V16.795H14.064C15.146,16.795 15.898,16.043 15.898,14.961V14.122C15.898,13.214 15.32,12.567 14.605,12.2L11.599,10.682C11.562,10.665 11.528,10.631 11.528,10.56V9.338C11.528,9.284 11.562,9.25 11.616,9.25H14.059C14.112,9.25 14.146,9.284 14.146,9.338V10.665H15.893V9.476C15.893,8.394 15.141,7.642 14.059,7.642H13.622V5.929H12.05V7.642H11.613C10.531,7.642 9.779,8.394 9.779,9.476V10.279C9.779,11.186 10.357,11.834 11.072,12.2L14.078,13.738C14.115,13.755 14.149,13.789 14.149,13.843V15.099C14.149,15.153 14.115,15.187 14.061,15.187H11.616C11.562,15.187 11.528,15.153 11.528,15.099V13.719H9.782V14.959C9.782,16.041 10.534,16.793 11.616,16.793H12.052Z"/>
</group>
</vector>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading