Skip to content

Commit

Permalink
[MOD/#64] Match 로직 수정 (데이터 피커로 날짜 선택시 전날로 가는 오류 존재)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyowon0204 committed Oct 11, 2024
1 parent 1ad4932 commit 14a7043
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package umc.everyones.lck.data.dto.response.about_lck

import umc.everyones.lck.domain.model.about_lck.AboutLckMatchDetailsModel
import java.time.LocalDate

data class LckMatchDetailsResponseDto(
val matchDetailList: List<LckMatchDetailsElementDto>,
val listSize: Int
val matchByDateList: List<LckMatchByDateDto>
) {
data class LckMatchByDateDto(
val matchDate: String,
val matchDetailList: List<LckMatchDetailsElementDto>,
val matchDetailSize: Int
) {
fun toAboutLckMatchByDateModel() =
AboutLckMatchDetailsModel.AboutLckMatchByDateModel(
matchDate = matchDate,
matchDetailList = matchDetailList.map { it.toAboutLckMatchDetailsElementModel() },
matchDetailSize = matchDetailSize
)
}

data class LckMatchDetailsElementDto(
val team1: TeamElementDto,
val team2: TeamElementDto,
Expand All @@ -15,18 +26,32 @@ data class LckMatchDetailsResponseDto(
val matchNumber: Int,
val matchTime: String,
val matchDate: String
){
) {
data class TeamElementDto(
val teamName: String,
val teamLogoUrl: String,
val winner: Boolean
){
) {
fun toTeamElementModel() =
AboutLckMatchDetailsModel.AboutLckMatchDetailsElementModel.TeamElementModel(teamName, teamLogoUrl, winner)
AboutLckMatchDetailsModel.AboutLckMatchDetailsElementModel.TeamElementModel(
teamName, teamLogoUrl, winner
)
}

fun toAboutLckMatchDetailsElementModel() =
AboutLckMatchDetailsModel.AboutLckMatchDetailsElementModel(team1.toTeamElementModel(),team2.toTeamElementModel(),matchFinished,season,matchNumber,matchTime,matchDate)
AboutLckMatchDetailsModel.AboutLckMatchDetailsElementModel(
team1.toTeamElementModel(),
team2.toTeamElementModel(),
matchFinished,
season,
matchNumber,
matchTime,
matchDate
)
}

fun toAboutLckMatchDetailsModel() =
AboutLckMatchDetailsModel(matchDetailList.map{it.toAboutLckMatchDetailsElementModel()}, listSize)
AboutLckMatchDetailsModel(
matchByDateList = matchByDateList.map { it.toAboutLckMatchByDateModel() }
)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package umc.everyones.lck.domain.model.about_lck


import java.time.LocalDate

data class AboutLckMatchDetailsModel(
val matchDetailList: List<AboutLckMatchDetailsElementModel>,
val listSize: Int
val matchByDateList: List<AboutLckMatchByDateModel>
) {
data class AboutLckMatchByDateModel(
val matchDate: String,
val matchDetailList: List<AboutLckMatchDetailsElementModel>,
val matchDetailSize: Int
)

data class AboutLckMatchDetailsElementModel(
val team1: TeamElementModel,
val team2: TeamElementModel,
Expand All @@ -22,4 +24,4 @@ data class AboutLckMatchDetailsModel(
val winner: Boolean
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import umc.everyones.lck.util.extension.showCustomSnackBar
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

@AndroidEntryPoint
class AboutLCKFragment : BaseFragment<FragmentAboutLckBinding>(R.layout.fragment_about_lck),
Expand All @@ -45,14 +46,20 @@ class AboutLCKFragment : BaseFragment<FragmentAboutLckBinding>(R.layout.fragment
private val viewModel: AboutLckViewModel by viewModels()

private var selectedDate: Calendar = Calendar.getInstance()

@SuppressLint("SimpleDateFormat")
override fun initObserver() {

viewLifecycleOwner.repeatOnStarted {
viewModel.matchDetails.collect { matchDetails ->
Timber.d("Collecting match details")
handleMatchDetailsResult(matchDetails)
if (matchDetails != null) {
updateMatchDetails(matchDetails)
} else {
Timber.e("Failed to fetch match details")
}
}
}

viewLifecycleOwner.repeatOnStarted {
viewModel.rankingDetails.collect { rankingDetails ->
if (rankingDetails != null) {
Expand All @@ -62,77 +69,89 @@ class AboutLCKFragment : BaseFragment<FragmentAboutLckBinding>(R.layout.fragment
}
}
}

viewLifecycleOwner.repeatOnStarted {
viewModel.temp.collect{
val temp = it.matchDetailList.groupBy { it.matchDate }
val temp1 = temp.map {Test(it.key, it.value)
}.sortedBy { it.date }
Timber.d("temp1: %s", temp1.toString())
matchVPAdapter.submitList(temp1)
scrollWithDate("")
}
}
}

override fun initView() {
viewModel.fetch()
fetchMatchDetails(getFormattedDate(selectedDate))
initMatchViewPager()
initRankingRecyclerView()
initBackButton()
initCalendarButton()
goMyPage()
}

private fun fetchMatchDetails(date: String) {
Timber.d("API 호출 - 요청 날짜: $date")
viewModel.fetchLckMatchDetails(date)
}
@SuppressLint("SimpleDateFormat")
private fun scrollWithDate(inputDate: String){
if(matchVPAdapter.currentList.isEmpty()){
return
}
val date = inputDate.replace(".","-").ifEmpty {
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val currentDate = Date(System.currentTimeMillis())
dateFormat.format(currentDate)
}
val index = matchVPAdapter.currentList.indexOfFirst { it.date == date }
if(index == -1){
showCustomSnackBar(binding.root, "해당 날짜에 예정된 경기가 없습니다")
private fun updateMatchDetails(matchDetailsModel: AboutLckMatchDetailsModel) {
val matchDataGroupedByDate = matchDetailsModel.matchByDateList.map { dateModel ->
AboutLCKFragment.Test(dateModel.matchDate, dateModel.matchDetailList)
}.sortedBy { it.date }

val filteredList = filterDuplicateData(matchDataGroupedByDate, getFormattedDate(selectedDate))

Timber.d("현재 selectedDate: ${getFormattedDate(selectedDate)}")
Timber.d("매치 데이터 날짜: %s", matchDataGroupedByDate.map { it.date })

if (filteredList != matchVPAdapter.currentList) {
matchVPAdapter.submitList(filteredList.toList()) {
scrollWithDate(getFormattedDate(selectedDate))
}
} else {
binding.vpAboutLckMatch.setCurrentItem(matchVPAdapter.currentList.indexOfFirst { it.date == date }, false)
binding.tvAboutLckDate.text = date.replace("-",".")
Timber.d("리스트가 동일하여 갱신하지 않음")
}
}

private fun handleMatchDetailsResult(matchDetails: AboutLckMatchDetailsModel?) {
if (matchDetails != null) {
val matchDataList = matchVPAdapter.getMatchDataList().toMutableList()
val mappedMatches = matchDetails.matchDetailList.map { match ->
createMatchData(match)
private fun filterDuplicateData(newData: List<Test>, selectedDate: String): List<Test> {
val currentList = matchVPAdapter.currentList

val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val selectedCalendar = Calendar.getInstance()
selectedCalendar.time = dateFormat.parse(selectedDate)!!

val previousDay = Calendar.getInstance().apply { time = selectedCalendar.time; add(Calendar.DATE, -1) }
val nextDay = Calendar.getInstance().apply { time = selectedCalendar.time; add(Calendar.DATE, 1) }

val mustIncludeDates = listOf(
dateFormat.format(previousDay.time),
selectedDate,
dateFormat.format(nextDay.time)
)
val filteredData = newData.filter { newItem ->
val isDuplicate = currentList.any { currentItem -> currentItem.date == newItem.date }

if (isDuplicate && mustIncludeDates.contains(newItem.date)) {
true
} else if (!isDuplicate) {
true
} else {
false
}
matchDataList.addAll(mappedMatches)
} else {
Timber.e("AboutLCKFragment", "Failed to fetch match details")
}
return filteredData
}

private fun createMatchData(match: AboutLckMatchDetailsModel.AboutLckMatchDetailsElementModel): MatchData {
val matchDate = match.matchDate
val matchTime = if (match.matchFinished) {
"Win | ${viewModel.getWinningTeamName(match)}"
@SuppressLint("SimpleDateFormat")
private fun scrollWithDate(inputDate: String) {
Timber.d("ViewPager 스크롤 - 입력된 날짜: $inputDate")

val currentIndex = matchVPAdapter.currentList.indexOfFirst { it.date == inputDate }
Timber.d("찾은 인덱스: $currentIndex")
Timber.d("현재 ViewPager의 currentItem: ${binding.vpAboutLckMatch.currentItem}")

if (currentIndex != binding.vpAboutLckMatch.currentItem) {
binding.vpAboutLckMatch.setCurrentItem(currentIndex, false)
binding.tvAboutLckDate.text = inputDate.replace("-", ".")
Timber.d("ViewPager가 포지션 %s로 스크롤됨", currentIndex)
} else {
match.matchTime.substring(0, 5)
Timber.d("해당 날짜의 매치 데이터를 찾을 수 없습니다: $inputDate")
}
}

return MatchData(
matchDate = matchDate,
matchTitle = viewModel.formatMatchTitle(match.season, match.matchNumber),
matchTime = matchTime,
teamLogoUrl1 = match.team1.teamLogoUrl,
teamLogoUrl2 = match.team2.teamLogoUrl,
isTeam1Winner = match.team1.winner,
isTeam2Winner = match.team2.winner,
isMatchFinished = match.matchFinished
)
private fun getFormattedDate(calendar: Calendar): String {
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
return dateFormat.format(calendar.time)
}

@SuppressLint("SimpleDateFormat")
Expand All @@ -141,11 +160,23 @@ class AboutLCKFragment : BaseFragment<FragmentAboutLckBinding>(R.layout.fragment
matchVPAdapter = MatchVPAdapter()
viewPager.adapter = matchVPAdapter

binding.vpAboutLckMatch.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback(){
binding.vpAboutLckMatch.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
binding.tvAboutLckDate.text = matchVPAdapter.currentList[position].date.replace("-",".")
Timber.d("ViewPager 페이지 선택 - 포지션: $position")

val selectedPageDate = matchVPAdapter.currentList[position].date
Timber.d("선택된 페이지 날짜: $selectedPageDate")

if (getFormattedDate(selectedDate) != selectedPageDate) {
Timber.d("selectedDate 업데이트 전: ${getFormattedDate(selectedDate)}")
updateSelectedPageDate(selectedPageDate)
Timber.d("selectedDate 업데이트 후: ${getFormattedDate(selectedDate)}")
} else {
Timber.d("동일한 날짜에 대한 API 호출 방지")
}
}
})
viewPager.offscreenPageLimit = 2

val pageMarginPx = 16 * resources.displayMetrics.densityDpi / 160
val offsetPx = 40 * resources.displayMetrics.densityDpi / 160
Expand All @@ -154,11 +185,17 @@ class AboutLCKFragment : BaseFragment<FragmentAboutLckBinding>(R.layout.fragment
page.translationX = -offsetPx * position
}

viewPager.offscreenPageLimit = 3

val recyclerViewMatches = viewPager.getChildAt(0) as RecyclerView
recyclerViewMatches.setPadding(pageMarginPx, 0, pageMarginPx, 0)
recyclerViewMatches.clipToPadding = false


}
private fun updateSelectedPageDate(selectedPageDate: String) {
val dateParts = selectedPageDate.split("-")
selectedDate.set(dateParts[0].toInt(), dateParts[1].toInt() - 1, dateParts[2].toInt())
binding.tvAboutLckDate.text = selectedPageDate.replace("-", ".")
fetchMatchDetails(selectedPageDate)
}

private fun updateRankingDetails(rankingDetails: AboutLckRankingDetailsModel) {
Expand Down Expand Up @@ -296,8 +333,8 @@ class AboutLCKFragment : BaseFragment<FragmentAboutLckBinding>(R.layout.fragment

private fun updateSelectedDate(year: Int, month: Int, day: Int) {
selectedDate.set(year, month, day)
val formattedDate = String.format("%d.%02d.%02d", selectedDate.get(Calendar.YEAR), selectedDate.get(Calendar.MONTH) + 1, selectedDate.get(Calendar.DAY_OF_MONTH))
scrollWithDate(formattedDate)
val formattedDate = getFormattedDate(selectedDate)
fetchMatchDetails(formattedDate)
}

override fun onTeamClick(team: RankingData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,32 @@ class AboutLckViewModel @Inject constructor(

private val _matchDetails = MutableStateFlow<AboutLckMatchDetailsModel?>(null)
val matchDetails: StateFlow<AboutLckMatchDetailsModel?> get() = _matchDetails
private val _title = MutableStateFlow<String>("")
val title: StateFlow<String> get() = _title

private val _rankingDetails = MutableStateFlow<AboutLckRankingDetailsModel?>(null)
val rankingDetails: StateFlow<AboutLckRankingDetailsModel?> get() = _rankingDetails


val temp = MutableSharedFlow<AboutLckMatchDetailsModel>()

fun fetch(){
/*fun fetch(){
viewModelScope.launch {
repository.fetchLckMatchDetails("2024-08-21").onSuccess {
temp.emit(it)
}.onFailure {
}
}
}*/
fun fetchLckMatchDetails(searchDate: String){
viewModelScope.launch{
val result = repository.fetchLckMatchDetails(searchDate)

result.onSuccess { response ->
_matchDetails.value = response
}.onFailure { exception ->
Timber.e(exception, "fetchLckMatchDetails API 호출 실패")
}
}
}

fun fetchLckRanking(seasonName: String, page: Int, size: Int) {
Expand All @@ -57,23 +66,5 @@ class AboutLckViewModel @Inject constructor(
}
}
}

fun formatMatchTitle(season: String, matchNumber: Int): String {
val suffix = when (matchNumber % 10) {
1 -> "st"
2 -> "nd"
3 -> "rd"
else -> "th"
}
return "$season LCK ${matchNumber}${suffix} Match"
}

fun getWinningTeamName(match: AboutLckMatchDetailsModel.AboutLckMatchDetailsElementModel): String {
return if (match.team1.winner) {
match.team1.teamName
} else {
match.team2.teamName
}
}
}

Loading

0 comments on commit 14a7043

Please sign in to comment.