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

#176 [ui] 루틴 추가하기 - 리스트 뷰 #177

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
</intent-filter>
</activity>

<activity
android:name=".ui.addroutine.list.AddListActivity"
android:exported="false"
android:screenOrientation="portrait" />

Copy link
Contributor

Choose a reason for hiding this comment

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

AddRoutineActivty는 어떤가요? AddList는 조금 모호한 클래스명같습니다!

<activity
android:name=".ui.happyroutine.list.HappyAddListActivity"
android:exported="false"
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/com/sopetit/softie/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import com.sopetit.softie.data.repositoryImpl.MemberHappinessRoutineRepositoryIm
import com.sopetit.softie.data.repositoryImpl.MemberRepositoryImpl
import com.sopetit.softie.data.repositoryImpl.RefreshTokenRepositoryImpl
import com.sopetit.softie.data.repositoryImpl.VersionRepositoryImpl
import com.sopetit.softie.domain.repository.AddRoutineRepository
import com.sopetit.softie.domain.repository.AuthRepository
import com.sopetit.softie.domain.repository.DailyRoutineRepository
import com.sopetit.softie.domain.repository.DollRepository
import com.sopetit.softie.domain.repository.HappinessRoutineRepository
import com.sopetit.softie.domain.repository.MemberHappinessRoutineRepository
import com.sopetit.softie.domain.repository.MemberRepository
import com.sopetit.softie.domain.repository.MockAddRoutineRepository
import com.sopetit.softie.domain.repository.RefreshTokenRepository
import com.sopetit.softie.domain.repository.VersionRepository
import dagger.Binds
Expand Down Expand Up @@ -55,6 +57,12 @@ abstract class RepositoryModule {
memberHappinessRoutineRepositoryImpl: MemberHappinessRoutineRepositoryImpl
): MemberHappinessRoutineRepository

@Binds
@Singleton
abstract fun bindAddRoutineRepository(
mockAddRoutineRepository: MockAddRoutineRepository
): AddRoutineRepository

@Binds
@Singleton
abstract fun bindToAuthRepository(
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/com/sopetit/softie/domain/entity/MakerCard.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.sopetit.softie.domain.entity

data class MakerCard(
val artistId: Int,
val artistImageUrl: String,
val subTitle: String,
val title: String,
val hashtag: List<Hashtag>
) {
data class Hashtag(
val hashtagId: Int,
val content: String,
)
}
12 changes: 12 additions & 0 deletions app/src/main/java/com/sopetit/softie/domain/entity/RoutineTheme.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sopetit.softie.domain.entity

data class RoutineTheme(
val themes: List<Themes>
) {
data class Themes(
val themeId: Int,
val modifier: String,
val name: String,
val description: String,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sopetit.softie.domain.repository

import com.sopetit.softie.domain.entity.MakerCard
import com.sopetit.softie.domain.entity.RoutineTheme

interface AddRoutineRepository {
suspend fun getMakerCard(): Result<List<MakerCard>>
suspend fun getRoutineTheme(): Result<RoutineTheme>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.sopetit.softie.domain.repository

import com.sopetit.softie.domain.entity.MakerCard
import com.sopetit.softie.domain.entity.RoutineTheme
import javax.inject.Inject

class MockAddRoutineRepository @Inject constructor() : AddRoutineRepository {
override suspend fun getMakerCard(): Result<List<MakerCard>> {
return Result.success(
listOf(
MakerCard(
artistId = 1,
artistImageUrl = "https://img.etoday.co.kr/pto_db/2024/04/600/20240426132100_2017673_647_863.jpeg",
subTitle = "하이브의 주인은 누구?",
title = "뉴진스가 돌아왔다",
hashtag = listOf(
MakerCard.Hashtag(hashtagId = 1, content = "#민희진"),
MakerCard.Hashtag(hashtagId = 2, content = "#방시혁"),
MakerCard.Hashtag(hashtagId = 2, content = "#하이브")
)
),
MakerCard(
artistId = 2,
artistImageUrl = "https://cdn.hankyung.com/photo/202211/BF.23427209.1.jpg",
subTitle = "더이상 웹툰작가로는 못산다",
title = "침착맨의 시크릿",
hashtag = listOf(
MakerCard.Hashtag(hashtagId = 3, content = "#침착침착"),
MakerCard.Hashtag(hashtagId = 4, content = "#이말년")
)
),
MakerCard(
artistId = 3,
artistImageUrl = "https://res.heraldm.com/content/image/2024/05/06/20240506050023_0.jpg",
subTitle = "선재업고 얼마나 뛸 수 있어?",
title = "변우석의 성공담",
hashtag = listOf(
MakerCard.Hashtag(hashtagId = 5, content = "#류선재"),
MakerCard.Hashtag(hashtagId = 6, content = "#드라마")
)
)
)
)
}

override suspend fun getRoutineTheme(): Result<RoutineTheme> {
return Result.success(
RoutineTheme(
themes = listOf(
RoutineTheme.Themes(
themeId = 1,
modifier = "사람들과 어울리는",
name = "관계 쌓기",
description = "설명"
),
RoutineTheme.Themes(
themeId = 2,
modifier = "나를 돌보는",
name = "마음 챙김",
description = "설명2"
),
RoutineTheme.Themes(
themeId = 3,
modifier = "경제적으로 살아가는",
name = "통통한 통장",
description = "설명2"
),
RoutineTheme.Themes(
themeId = 4,
modifier = "하루를 상쾌하게",
name = "산뜻한 일상",
description = "설명2"
),
RoutineTheme.Themes(
themeId = 5,
modifier = "더 나은 나를 위해",
name = "한 걸음 성장",
description = "설명2"
),
RoutineTheme.Themes(
themeId = 6,
modifier = "튼튼하게 건강하게",
name = "건강한 몸",
description = "설명2"
),
RoutineTheme.Themes(
themeId = 7,
modifier = "튼튼하게 건강하게",
name = "나와 친해지기",
description = "설명2"
)
)
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sopetit.softie.domain.usecase.addroutine

import com.sopetit.softie.domain.entity.MakerCard
import com.sopetit.softie.domain.repository.AddRoutineRepository
import javax.inject.Inject

class GetMakerCardUseCase @Inject constructor(
private val addRoutineRepository: AddRoutineRepository
) {
suspend operator fun invoke(): Result<List<MakerCard>> {
return addRoutineRepository.getMakerCard()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.sopetit.softie.domain.usecase.addroutine

import com.sopetit.softie.domain.entity.RoutineTheme
import com.sopetit.softie.domain.repository.AddRoutineRepository
import javax.inject.Inject

class GetRoutineThemeListUseCase @Inject constructor(
private val addRoutineRepository: AddRoutineRepository
) {
suspend operator fun invoke(): Result<RoutineTheme> {
return try {
val result = addRoutineRepository.getRoutineTheme()
result
} catch (e: Exception) {
Result.failure(e)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.sopetit.softie.ui.addroutine.list

import android.os.Bundle
import androidx.activity.viewModels
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.sopetit.softie.R
import com.sopetit.softie.databinding.ActivityAddListBinding
import com.sopetit.softie.util.VerticalItemDecoration
import com.sopetit.softie.util.binding.BindingActivity
import com.sopetit.softie.util.setSingleOnClickListener
import com.sopetit.softie.util.setStatusBarColorFromResource
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class AddListActivity : BindingActivity<ActivityAddListBinding>(R.layout.activity_add_list) {
private lateinit var viewPager: ViewPager2
Copy link
Contributor

Choose a reason for hiding this comment

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

뷰페이저가 아닌 recylerView로 개발해주시면 됩니다. vertical이 아닌 horizontal로 구현하면 되고
전에 이야기 했다 싶이, 1개일 경우와 n개일 때의 카드 뷰 크기가 달라집니다. (figma 확인해보세요!)
-> 1개일 경우, recyclerView를 invisible 하고 개별 컴포넌트 하나를 visible 처리
or 1개일 경우, recyclerView item 너비를 조정하는 코드를 추가하는 방법이 어떤가 싶습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

리사이클러뷰로 다시 짜보겠습니다...

private val makerCardPagerAdapter = MakerCardPagerAdapter()
private val viewModel by viewModels<AddListViewModel>()
private var routineThemeListAdapter: RoutineThemeListAdapter? = null
private lateinit var itemDeco: RecyclerView.ItemDecoration

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.viewModel = viewModel
viewPager = binding.vpAddListMakerCard
setStatusBarColorFromResource(R.color.background)

startMakerHelpModal()
setBackEnter()
setInitBinding()
setHappyDetailCardPagerAdapter()
setCurrentCard()
setRoutineThemeListAdapter()
setItemDeco()
setupObservers()
}

private fun startMakerHelpModal() {
binding.ivAddListMakerHelp.setSingleOnClickListener {
MakerHelpDialogFragment().show(supportFragmentManager, "MakerHelpDialog")
}
}

private fun setBackEnter() {
binding.ivAddListBackArrow.setSingleOnClickListener {
finish()
}
}

private fun setInitBinding() {
viewModel.getMakerCard()
viewModel.getRoutineTheme()
}

private fun setHappyDetailCardPagerAdapter() {
with(binding) {
vpAddListMakerCard.adapter = makerCardPagerAdapter
}
}

private fun setCurrentCard() {
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
val currentMakerId = getCurrentSelectedMakerId()
viewModel.setMakerId(currentMakerId)
}
})
}

private fun getCurrentSelectedMakerId(): Int {
val currentItem = binding.vpAddListMakerCard.currentItem
val itemId = makerCardPagerAdapter.getItemId(currentItem)
return itemId.toInt()
}

private fun setRoutineThemeListAdapter() {
with(binding) {
routineThemeListAdapter = RoutineThemeListAdapter()
rvAddList.adapter = routineThemeListAdapter
}
}

private fun setItemDeco() {
itemDeco = VerticalItemDecoration(applicationContext)
binding.rvAddList.addItemDecoration(itemDeco)
}

private fun setupObservers() {
viewModel.addRoutineThemeListResponse.observe(this) { routineTheme ->
routineTheme?.let {
routineThemeListAdapter?.submitList(routineTheme.themes)
}
}

viewModel.addMakerCardResponse.observe(this) { makerCards ->
makerCards?.let {
makerCardPagerAdapter.submitList(makerCards)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.sopetit.softie.ui.addroutine.list

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopetit.softie.domain.entity.MakerCard
import com.sopetit.softie.domain.entity.RoutineTheme
import com.sopetit.softie.domain.usecase.addroutine.GetMakerCardUseCase
import com.sopetit.softie.domain.usecase.addroutine.GetRoutineThemeListUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class AddListViewModel @Inject constructor(
Copy link
Contributor

Choose a reason for hiding this comment

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

마찬가지입니다. 추후에 혼동을 줄수있는 클래스명인 것 같습니다. 길더라도 좀 더 명시적으로 짓는 것은 어떨까요?

private val getMakerCardUseCase: GetMakerCardUseCase,
private val getRoutineThemeListUseCase: GetRoutineThemeListUseCase
) : ViewModel() {
private val _addMakerCardResponse = MutableLiveData<List<MakerCard>>()
val addMakerCardResponse: LiveData<List<MakerCard>> get() = _addMakerCardResponse

private val _addRoutineThemeListResponse = MutableLiveData<RoutineTheme>()
val addRoutineThemeListResponse: LiveData<RoutineTheme> get() = _addRoutineThemeListResponse

private val _myMakerId: MutableLiveData<Int> = MutableLiveData()

fun setMakerId(makerId: Int) {
_myMakerId.value = makerId
}

fun getMakerCard() {
viewModelScope.launch {
getMakerCardUseCase()
.onSuccess { response ->
_addMakerCardResponse.value = response
}
.onFailure { throwable ->
Timber.e("$throwable")
}
}
}

fun getRoutineTheme() {
viewModelScope.launch {
val result = getRoutineThemeListUseCase()

result.onSuccess { response ->
_addRoutineThemeListResponse.value = response
}.onFailure { throwable ->
Timber.e("$throwable")
}
}
}
}
Loading
Loading