feat(creator-channel): 커뮤니티 목록 클릭을 연결한다
This commit is contained in:
@@ -13,7 +13,9 @@ import kr.co.vividnext.sodalive.extensions.moneyFormat
|
|||||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityImageMode
|
import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityImageMode
|
||||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityPostUiModel
|
import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityPostUiModel
|
||||||
|
|
||||||
class CreatorChannelCommunityGridAdapter : RecyclerView.Adapter<CreatorChannelCommunityGridAdapter.ViewHolder>() {
|
class CreatorChannelCommunityGridAdapter(
|
||||||
|
private val onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit = {}
|
||||||
|
) : RecyclerView.Adapter<CreatorChannelCommunityGridAdapter.ViewHolder>() {
|
||||||
|
|
||||||
private var items: List<CreatorChannelCommunityPostUiModel> = emptyList()
|
private var items: List<CreatorChannelCommunityPostUiModel> = emptyList()
|
||||||
private var itemSizePx: Int = 0
|
private var itemSizePx: Int = 0
|
||||||
@@ -31,7 +33,10 @@ class CreatorChannelCommunityGridAdapter : RecyclerView.Adapter<CreatorChannelCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(ItemCreatorChannelCommunityGridBinding.inflate(LayoutInflater.from(parent.context), parent, false))
|
return ViewHolder(
|
||||||
|
ItemCreatorChannelCommunityGridBinding.inflate(LayoutInflater.from(parent.context), parent, false),
|
||||||
|
onPostClick
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
@@ -41,10 +46,12 @@ class CreatorChannelCommunityGridAdapter : RecyclerView.Adapter<CreatorChannelCo
|
|||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
|
||||||
class ViewHolder(
|
class ViewHolder(
|
||||||
private val binding: ItemCreatorChannelCommunityGridBinding
|
private val binding: ItemCreatorChannelCommunityGridBinding,
|
||||||
|
private val onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: CreatorChannelCommunityPostUiModel, itemSizePx: Int) = with(binding) {
|
fun bind(item: CreatorChannelCommunityPostUiModel, itemSizePx: Int) = with(binding) {
|
||||||
|
root.setOnClickListener { onPostClick(item) }
|
||||||
if (itemSizePx > 0) {
|
if (itemSizePx > 0) {
|
||||||
root.layoutParams = root.layoutParams.apply {
|
root.layoutParams = root.layoutParams.apply {
|
||||||
width = itemSizePx
|
width = itemSizePx
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import kr.co.vividnext.sodalive.extensions.moneyFormat
|
|||||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityPostUiModel
|
import kr.co.vividnext.sodalive.v2.creator.channel.community.model.CreatorChannelCommunityPostUiModel
|
||||||
|
|
||||||
class CreatorChannelCommunityListAdapter(
|
class CreatorChannelCommunityListAdapter(
|
||||||
|
private val onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit = {},
|
||||||
private val onPlayClick: (CreatorChannelCommunityPostUiModel) -> Unit = {},
|
private val onPlayClick: (CreatorChannelCommunityPostUiModel) -> Unit = {},
|
||||||
private val onOwnerMoreClick: (CreatorChannelCommunityPostUiModel) -> Unit = {},
|
private val onOwnerMoreClick: (CreatorChannelCommunityPostUiModel) -> Unit = {},
|
||||||
private val isPlayingContent: (Long) -> Boolean = { false }
|
private val isPlayingContent: (Long) -> Boolean = { false }
|
||||||
@@ -32,6 +33,7 @@ class CreatorChannelCommunityListAdapter(
|
|||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(
|
return ViewHolder(
|
||||||
ItemCreatorChannelCommunityListBinding.inflate(LayoutInflater.from(parent.context), parent, false),
|
ItemCreatorChannelCommunityListBinding.inflate(LayoutInflater.from(parent.context), parent, false),
|
||||||
|
onPostClick,
|
||||||
onPlayClick,
|
onPlayClick,
|
||||||
onOwnerMoreClick,
|
onOwnerMoreClick,
|
||||||
isPlayingContent
|
isPlayingContent
|
||||||
@@ -46,12 +48,14 @@ class CreatorChannelCommunityListAdapter(
|
|||||||
|
|
||||||
class ViewHolder(
|
class ViewHolder(
|
||||||
private val binding: ItemCreatorChannelCommunityListBinding,
|
private val binding: ItemCreatorChannelCommunityListBinding,
|
||||||
|
private val onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit,
|
||||||
private val onPlayClick: (CreatorChannelCommunityPostUiModel) -> Unit,
|
private val onPlayClick: (CreatorChannelCommunityPostUiModel) -> Unit,
|
||||||
private val onOwnerMoreClick: (CreatorChannelCommunityPostUiModel) -> Unit,
|
private val onOwnerMoreClick: (CreatorChannelCommunityPostUiModel) -> Unit,
|
||||||
private val isPlayingContent: (Long) -> Boolean
|
private val isPlayingContent: (Long) -> Boolean
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: CreatorChannelCommunityPostUiModel) = with(binding) {
|
fun bind(item: CreatorChannelCommunityPostUiModel) = with(binding) {
|
||||||
|
root.setOnClickListener { onPostClick(item) }
|
||||||
ivCreatorChannelCommunityListProfile.loadUrl(item.creatorProfileUrl) {
|
ivCreatorChannelCommunityListProfile.loadUrl(item.creatorProfileUrl) {
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
placeholder(R.drawable.bg_placeholder)
|
placeholder(R.drawable.bg_placeholder)
|
||||||
|
|||||||
@@ -47,6 +47,35 @@ class CreatorChannelActivitySourceTest {
|
|||||||
assertTrue(source.contains("marginStart = if (isChatVisible && isDmVisible)"))
|
assertTrue(source.contains("marginStart = if (isChatVisible && isDmVisible)"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `커뮤니티 게시물 클릭 source는 상세 Activity newIntent로 진입하고 invalid postId를 무시한다`() {
|
||||||
|
val source = projectFile(
|
||||||
|
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt"
|
||||||
|
).readText()
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
source.contains(
|
||||||
|
"import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.CreatorChannelCommunityDetailActivity"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertTrue(source.contains("override fun onCreatorChannelCommunityPostClicked(postId: Long)"))
|
||||||
|
assertTrue(source.contains("if (postId <= 0L) return"))
|
||||||
|
assertTrue(source.contains("if (SharedPreferenceManager.token.isBlank())"))
|
||||||
|
assertTrue(source.contains("showLoginActivity()"))
|
||||||
|
assertTrue(source.contains("CreatorChannelCommunityDetailActivity.newIntent(this, postId)"))
|
||||||
|
assertTrue(source.contains("private val communityDetailLauncher = registerForActivityResult"))
|
||||||
|
assertTrue(
|
||||||
|
source.contains(
|
||||||
|
"communityDetailLauncher.launch(CreatorChannelCommunityDetailActivity.newIntent(this, postId))"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertTrue(
|
||||||
|
source.indexOf("if (SharedPreferenceManager.token.isBlank())") <
|
||||||
|
source.indexOf("communityDetailLauncher.launch(CreatorChannelCommunityDetailActivity.newIntent(this, postId))")
|
||||||
|
)
|
||||||
|
assertTrue(source.contains("refreshCreatorChannelCommunity()"))
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `follow notify source는 Phase 11 직접 팔로우 알림 액션을 연결한다`() {
|
fun `follow notify source는 Phase 11 직접 팔로우 알림 액션을 연결한다`() {
|
||||||
val source = projectFile(
|
val source = projectFile(
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ class CreatorChannelCommunityFragmentLayoutTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `커뮤니티 adapters source는 binding 상태 표시와 root click navigation 배제를 보장한다`() {
|
fun `커뮤니티 adapters source는 binding 상태 표시와 root click callback 계약을 보장한다`() {
|
||||||
val listAdapter = projectFile(
|
val listAdapter = projectFile(
|
||||||
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityListAdapter.kt"
|
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/ui/CreatorChannelCommunityListAdapter.kt"
|
||||||
).readText()
|
).readText()
|
||||||
@@ -182,7 +182,13 @@ class CreatorChannelCommunityFragmentLayoutTest {
|
|||||||
assertTrue(listAdapter.contains("isPlayingContent"))
|
assertTrue(listAdapter.contains("isPlayingContent"))
|
||||||
assertTrue(listAdapter.contains("R.drawable.ic_player_pause"))
|
assertTrue(listAdapter.contains("R.drawable.ic_player_pause"))
|
||||||
assertTrue(listAdapter.contains("R.drawable.ic_new_player_play"))
|
assertTrue(listAdapter.contains("R.drawable.ic_new_player_play"))
|
||||||
|
assertTrue(listAdapter.contains("private val onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit = {}"))
|
||||||
|
assertTrue(listAdapter.contains("root.setOnClickListener { onPostClick(item) }"))
|
||||||
|
assertTrue(listAdapter.contains("ivCreatorChannelCommunityListPlay.setOnClickListener { onPlayClick(item) }"))
|
||||||
assertTrue(listAdapter.contains("onOwnerMoreClick(item)"))
|
assertTrue(listAdapter.contains("onOwnerMoreClick(item)"))
|
||||||
|
assertTrue(listAdapter.contains("ivCreatorChannelCommunityListOwnerMore.setOnClickListener { onOwnerMoreClick(item) }"))
|
||||||
|
assertTrue(gridAdapter.contains("private val onPostClick: (CreatorChannelCommunityPostUiModel) -> Unit = {}"))
|
||||||
|
assertTrue(gridAdapter.contains("root.setOnClickListener { onPostClick(item) }"))
|
||||||
assertTrue(listAdapter.contains("tvCreatorChannelCommunityListLockedPrice.isVisible = item.isLocked"))
|
assertTrue(listAdapter.contains("tvCreatorChannelCommunityListLockedPrice.isVisible = item.isLocked"))
|
||||||
assertTrue(listAdapter.contains("layoutCreatorChannelCommunityListTopPrice.isVisible = item.showOwnerTopPrice"))
|
assertTrue(listAdapter.contains("layoutCreatorChannelCommunityListTopPrice.isVisible = item.showOwnerTopPrice"))
|
||||||
assertTrue(!listAdapter.contains("item.isLocked || item.showOwnerTopPrice"))
|
assertTrue(!listAdapter.contains("item.isLocked || item.showOwnerTopPrice"))
|
||||||
@@ -192,8 +198,17 @@ class CreatorChannelCommunityFragmentLayoutTest {
|
|||||||
assertTrue(!gridAdapter.contains("14f.dpToPx()"))
|
assertTrue(!gridAdapter.contains("14f.dpToPx()"))
|
||||||
assertTrue(!gridAdapter.contains("root.clipToOutline = true"))
|
assertTrue(!gridAdapter.contains("root.clipToOutline = true"))
|
||||||
assertTrue(!listAdapter.contains(".asBitmap()"))
|
assertTrue(!listAdapter.contains(".asBitmap()"))
|
||||||
assertTrue(!listAdapter.contains("root.setOnClickListener"))
|
}
|
||||||
assertTrue(!gridAdapter.contains("root.setOnClickListener"))
|
|
||||||
|
@Test
|
||||||
|
fun `커뮤니티 fragment source는 post click을 list grid adapter와 Host로 위임한다`() {
|
||||||
|
val fragment = projectFile(
|
||||||
|
"app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityFragment.kt"
|
||||||
|
).readText()
|
||||||
|
|
||||||
|
assertTrue(fragment.contains("onPostClick = { item -> host.onCreatorChannelCommunityPostClicked(item.postId) }"))
|
||||||
|
assertTrue(fragment.contains("private val gridAdapter = CreatorChannelCommunityGridAdapter("))
|
||||||
|
assertTrue(fragment.contains("fun onCreatorChannelCommunityPostClicked(postId: Long)"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user