Skip to content

Commit

Permalink
#42 -> develop
Browse files Browse the repository at this point in the history
[�FEAT/#42]  내 쪽지 상세보기 로직 & Ui & 서버 연결
  • Loading branch information
kkk5474096 committed Jul 17, 2023
2 parents 456911d + f9b02f0 commit 9a7e6a9
Show file tree
Hide file tree
Showing 31 changed files with 860 additions and 87 deletions.
8 changes: 4 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@
android:name=".presentation.main.profile.manage.ProfileQuitForSureActivity"
android:exported="false"
android:screenOrientation="portrait" />




<activity
android:name=".presentation.main.myyello.read.MyYelloReadActivity"
android:exported="false"
android:screenOrientation="portrait" />
</application>

</manifest>
3 changes: 2 additions & 1 deletion app/src/main/java/com/yello/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.example.data.datasource.OnboardingDataSource
import com.example.data.datasource.YelloDataSource
import com.example.data.datasource.local.MockYelloDataSourceImpl
import com.example.data.datasource.remote.OnboardingDataSourceImpl
import com.example.data.datasource.remote.YelloDataSourceImpl
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -15,7 +16,7 @@ import javax.inject.Singleton
object DataSourceModule {
@Provides
@Singleton
fun provideYelloDataSource(yelloDataSource: MockYelloDataSourceImpl): YelloDataSource =
fun provideYelloDataSource(yelloDataSource: YelloDataSourceImpl): YelloDataSource =
yelloDataSource

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.example.domain.entity.Yello
import com.example.domain.enum.GenderEnum
import com.example.ui.view.setOnSingleClickListener
import com.yello.R
import com.yello.databinding.ItemMyYelloBinding
import com.yello.util.Utils

class MyYelloAdapter : RecyclerView.Adapter<MyYelloAdapter.MyYelloViewHolder>() {
class MyYelloAdapter(private val itemClick: (Yello) -> (Unit)) :
RecyclerView.Adapter<MyYelloAdapter.MyYelloViewHolder>() {
private val yelloList = mutableListOf<Yello>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyYelloViewHolder {
val binding = ItemMyYelloBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return MyYelloViewHolder(binding)
return MyYelloViewHolder(binding, itemClick)
}

override fun onBindViewHolder(holder: MyYelloViewHolder, position: Int) {
Expand All @@ -33,7 +36,8 @@ class MyYelloAdapter : RecyclerView.Adapter<MyYelloAdapter.MyYelloViewHolder>()
}

class MyYelloViewHolder(
private val binding: ItemMyYelloBinding
private val binding: ItemMyYelloBinding,
private val itemClick: (Yello) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(item: Yello) {
binding.ivReadYelloPoint.isVisible = !item.isRead && !item.isHintUsed
Expand Down Expand Up @@ -81,23 +85,14 @@ class MyYelloAdapter : RecyclerView.Adapter<MyYelloAdapter.MyYelloViewHolder>()
binding.tvKeyword.text = item.vote.keyword
binding.tvKeywordFoot.text = item.vote.keywordFoot
if (item.nameHint >= 0) {
binding.tvSendName.text = setChosungText(item.senderName, item.nameHint)
binding.tvSendName.text = Utils.setChosungText(item.senderName, item.nameHint)
}
binding.clSendName.isVisible = item.nameHint != -1
}
}

private fun setChosungText(name: String, number: Int): String {
val firstChosung = name[number]
val chosungUnicode = Character.UnicodeBlock.of(firstChosung.toInt())
return if (chosungUnicode == Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO
|| chosungUnicode == Character.UnicodeBlock.HANGUL_JAMO
|| chosungUnicode == Character.UnicodeBlock.HANGUL_SYLLABLES
) {
val chosungIndex = (firstChosung.toInt() - 0xAC00) / 28 / 21
val chosung = Character.toChars(chosungIndex + 0x1100)[0]
chosung.toString() // 출력: "ㄱ"
} else ""
binding.root.setOnSingleClickListener {
itemClick(item)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.example.ui.fragment.toast
import com.example.ui.view.UiState
import com.yello.R
import com.yello.databinding.FragmentMyYelloBinding
import com.yello.presentation.main.myyello.read.MyYelloReadActivity
import com.yello.presentation.util.BaseLinearRcvItemDeco
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
Expand All @@ -32,7 +33,9 @@ class MyYelloFragment : BindingFragment<FragmentMyYelloBinding>(R.layout.fragmen

private fun initView() {
viewModel.getMyYelloList()
adapter = MyYelloAdapter()
adapter = MyYelloAdapter {
startActivity(MyYelloReadActivity.getIntent(requireContext(), it.id))
}
binding.rvMyYelloReceive.addItemDecoration(
BaseLinearRcvItemDeco(
8,
Expand All @@ -56,7 +59,6 @@ class MyYelloFragment : BindingFragment<FragmentMyYelloBinding>(R.layout.fragmen
when (it) {
is UiState.Success -> {
adapter?.addItem(it.data.yello)
binding.tvCount.text = it.data.totalCount.toString()
}

is UiState.Failure -> {
Expand All @@ -66,25 +68,27 @@ class MyYelloFragment : BindingFragment<FragmentMyYelloBinding>(R.layout.fragmen
else -> {}
}
}.launchIn(viewLifecycleOwner.lifecycleScope)

viewModel.totalCount.flowWithLifecycle(viewLifecycleOwner.lifecycle)
.onEach {
binding.tvCount.text = it.toString()
}.launchIn(viewLifecycleOwner.lifecycleScope)
}

// 페이지네이션
private fun infinityScroll() {
binding.rvMyYelloReceive.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
// 화면에 보이는 마지막 아이템의 position
val lastVisibleItemPosition =
(recyclerView.layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition()
// 어댑터에 등록된 아이템의 총 개수 -1
val itemTotalCount = adapter?.itemCount?.minus(1)
// 스크롤이 끝에 도달했는지 확인
if (lastVisibleItemPosition != -1 && itemTotalCount != -1) {
if (lastVisibleItemPosition == itemTotalCount) {
if (dy > 0) {
if (!binding.rvMyYelloReceive.canScrollVertically(1) &&
(recyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() == adapter!!.itemCount - 1
) {
viewModel.getMyYelloList()
}
}
}
})
}
})
}

override fun onDestroyView() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,49 @@
package com.yello.presentation.main.myyello

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.domain.entity.MyYello
import com.example.domain.repository.YelloRepository
import com.example.ui.view.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class MyYelloViewModel @Inject constructor(
private val repository: YelloRepository
) : ViewModel() {
private val _myYelloData = MutableStateFlow<UiState<MyYello>>(UiState.Loading)
private val _myYelloData = MutableSharedFlow<UiState<MyYello>>()
val myYelloData: SharedFlow<UiState<MyYello>> = _myYelloData.asSharedFlow()

private var currentPage = 0
private val _totalCount = MutableStateFlow<Int>(0)
val totalCount: StateFlow<Int> = _totalCount.asStateFlow()

private var currentPage = -1
private var isPagingFinish = false
private var totalPage = Int.MAX_VALUE

fun getMyYelloList() {
if (isPagingFinish) return
_myYelloData.value = UiState.Loading
_myYelloData.tryEmit(UiState.Loading)
viewModelScope.launch {
repository.getMyYelloList(++currentPage)
.onSuccess {
totalPage = Math.ceil((it.totalCount * 0.1)).toInt()
if (totalPage == currentPage) isPagingFinish = true
_myYelloData.value = when {
it.yello.isEmpty() -> UiState.Empty
else -> UiState.Success(it)
}

_myYelloData.emit(
when {
it.yello.isEmpty() -> UiState.Empty
else -> UiState.Success(it)
}
)
_totalCount.value = it.totalCount
}.onFailure {
_myYelloData.emit(UiState.Failure("옐로 리스트 서버 통신 실패"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.yello.presentation.main.myyello.read

import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.example.domain.entity.YelloDetail
import com.example.domain.enum.PointEnum
import com.example.ui.base.BindingActivity
import com.example.ui.context.toast
import com.example.ui.intent.longExtra
import com.example.ui.view.UiState
import com.example.ui.view.setOnSingleClickListener
import com.yello.R
import com.yello.databinding.ActivityMyYelloReadBinding
import com.yello.util.Utils
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class MyYelloReadActivity :
BindingActivity<ActivityMyYelloReadBinding>(R.layout.activity_my_yello_read) {
private val id by longExtra()
private val viewModel by viewModels<MyYelloReadViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initView()
initClick()
observe()
}

private fun initView() {
viewModel.getYelloDetail(id)
}

private fun initClick() {
binding.tvInitialCheck.setOnSingleClickListener {
PointUseDialog.newInstance(true, PointEnum.INITIAL.ordinal)
.show(supportFragmentManager, "dialog")
}

binding.clSendCheck.setOnSingleClickListener {
PointUseDialog.newInstance(true, PointEnum.KEYWORD.ordinal)
.show(supportFragmentManager, "dialog")
}

binding.ivBack.setOnSingleClickListener {
finish()
}
}

private fun observe() {
viewModel.yelloDetailData.flowWithLifecycle(lifecycle)
.onEach {
when (it) {
is UiState.Success -> {
binding.data = it.data
setData(it.data)
}

is UiState.Failure -> {
toast(it.msg)
}

else -> {

}
}
}.launchIn(lifecycleScope)
}

private fun setData(yello: YelloDetail) {
binding.tvSendName.isVisible = yello.nameHint != -1
binding.tvNameNotYet.isVisible = yello.nameHint == -1
if (yello.nameHint >= 0) binding.tvSendName.text =
Utils.setChosungText(yello.senderName, yello.nameHint)
binding.tvGender.text =
if (yello.senderGender.contains("MALE")) getString(R.string.my_yello_male) else getString(
R.string.my_yello_female
)
}

companion object {
fun getIntent(context: Context, id: Long) =
Intent(context, MyYelloReadActivity::class.java)
.putExtra("id", id)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.yello.presentation.main.myyello.read

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.domain.entity.YelloDetail
import com.example.domain.repository.YelloRepository
import com.example.ui.view.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class MyYelloReadViewModel @Inject constructor(
private val repository: YelloRepository
) : ViewModel() {
private val _yelloDetailData = MutableStateFlow<UiState<YelloDetail>>(UiState.Loading)
val yelloDetailData: StateFlow<UiState<YelloDetail>> = _yelloDetailData.asStateFlow()

fun getYelloDetail(id: Long) {
viewModelScope.launch {
repository.getYelloDetail(id)
.onSuccess {
_yelloDetailData.value = UiState.Success(it)
}.onFailure {
_yelloDetailData.value = UiState.Failure("옐로 상세보기 서버 통신 실패")
}
}
}
}
Loading

0 comments on commit 9a7e6a9

Please sign in to comment.