diff --git a/tvmon-app/app/src/main/java/com/example/tvmon/data/scraper/TvmonScraper.kt b/tvmon-app/app/src/main/java/com/example/tvmon/data/scraper/TvmonScraper.kt index f8a8ddd..59ac797 100644 --- a/tvmon-app/app/src/main/java/com/example/tvmon/data/scraper/TvmonScraper.kt +++ b/tvmon-app/app/src/main/java/com/example/tvmon/data/scraper/TvmonScraper.kt @@ -412,35 +412,39 @@ val episodes = mutableListOf() val seenEpisodeIds = mutableSetOf() val seriesId = seriesUrl.substringAfterLast("/").substringBefore("?") - val allEpisodeLinks = doc.select(".next-ep-list-scroll .ep-item, .ep-item, .bo_v_list li a, #bo_v_list li a, .list_body .item a, .ep-list a") + + val allEpisodeLinks = doc.select( + ".next-ep-list-scroll .ep-item, .ep-item, .bo_v_list li a, #bo_v_list li a, " + + ".list_body .item a, .ep-list a, .episode-list a, .ep-link a, " + + "a[href*='/$seriesId/'], a[href*='/${seriesId}/']" + ) for (link in allEpisodeLinks) { val href = link.attr("href") if (href.isBlank()) continue - if (!href.contains("/$seriesId/")) continue val fullUrl = resolveUrl(href) - val episodeIdMatch = Pattern.compile("/(\\d+)/(\\d+)$").matcher(href) + val episodeIdMatch = Pattern.compile("/$seriesId/(\\d+)").matcher(href) if (!episodeIdMatch.find()) continue - val episodeId = episodeIdMatch.group(2) ?: "" + val episodeId = episodeIdMatch.group(1) ?: "" if (episodeId in seenEpisodeIds) continue seenEpisodeIds.add(episodeId) - val titleEl = link.selectFirst(".ep-item-title, .item-title, strong, span") + val titleEl = link.selectFirst(".ep-item-title, .item-title, strong, span, .title") val linkText = titleEl?.text()?.trim() ?: link.text().trim() - val episodeNumMatch = Pattern.compile("(\\d+ 화|\\d+ 회|EP?\\d+|제?\\d+부?|\\d+)").matcher(linkText) + val episodeNumMatch = Pattern.compile("(\\d+)\\s*화|(\\d+)\\s*회|EP\\.?(\\d+)|제\\s*(\\d+)\\s*부").matcher(linkText) val episodeTitle = if (episodeNumMatch.find()) { - episodeNumMatch.group(1) + episodeNumMatch.group(1) ?: episodeNumMatch.group(2) ?: episodeNumMatch.group(3) ?: episodeNumMatch.group(4) ?: episodeId } else { - "Episode ${episodes.size + 1}" + episodeId } episodes.add(Episode( - number = episodeTitle ?: "Episode ${episodes.size + 1}", - title = linkText.ifBlank { episodeTitle ?: "Episode ${episodes.size + 1}" }, + number = episodeTitle, + title = linkText.ifBlank { episodeTitle }, url = fullUrl, type = "webview" )) @@ -448,7 +452,7 @@ val episodes = mutableListOf() videoLinks.add(VideoLink( type = "play_page", url = fullUrl, - title = linkText.ifBlank { episodeTitle ?: "Episode ${videoLinks.size + 1}" } + title = linkText.ifBlank { episodeTitle } )) } diff --git a/tvmon-app/app/src/main/java/com/example/tvmon/ui/detail/DetailsFragment.kt b/tvmon-app/app/src/main/java/com/example/tvmon/ui/detail/DetailsFragment.kt index 311eb89..3085098 100644 --- a/tvmon-app/app/src/main/java/com/example/tvmon/ui/detail/DetailsFragment.kt +++ b/tvmon-app/app/src/main/java/com/example/tvmon/ui/detail/DetailsFragment.kt @@ -255,10 +255,14 @@ class DetailsFragment : DetailsSupportFragment() { val row = ListRow(header, episodesRowAdapter) activity?.runOnUiThread { - if (episodesRowIndex >= 0 && episodesRowIndex < rowsAdapter.size()) { - rowsAdapter.add(episodesRowIndex, row) + if (existingRowIndex >= 0 && existingRowIndex < rowsAdapter.size()) { + rowsAdapter.add(existingRowIndex, row) } else { - rowsAdapter.add(row) + if (episodesRowIndex >= 0 && episodesRowIndex <= rowsAdapter.size()) { + rowsAdapter.add(episodesRowIndex, row) + } else { + rowsAdapter.add(row) + } } Log.w(TAG, "loadDetailInfo: Added episodes row at index $episodesRowIndex, rowsAdapter size=${rowsAdapter.size()}") } diff --git a/tvmon-app/app/src/main/java/com/example/tvmon/ui/main/MainFragment.kt b/tvmon-app/app/src/main/java/com/example/tvmon/ui/main/MainFragment.kt index 0a7c595..9febf75 100644 --- a/tvmon-app/app/src/main/java/com/example/tvmon/ui/main/MainFragment.kt +++ b/tvmon-app/app/src/main/java/com/example/tvmon/ui/main/MainFragment.kt @@ -37,6 +37,7 @@ class MainFragment : BrowseSupportFragment(), OnItemViewClickedListener, OnItemV private val categoryRowAdapters = mutableMapOf() private val handler = Handler(Looper.getMainLooper()) private var currentSelectedRowIndex = -1 + private var isDataLoaded = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -53,7 +54,11 @@ class MainFragment : BrowseSupportFragment(), OnItemViewClickedListener, OnItemV override fun onStart() { super.onStart() Log.w(TAG, "=== MainFragment onStart ===") - loadData() + if (!isDataLoaded) { + loadData() + } else { + Log.w(TAG, "Data already loaded, skipping reload") + } } override fun onDestroy() { @@ -219,6 +224,8 @@ private fun loadNextPage(categoryKey: String, page: Int) { Log.w(TAG, "=== loadCategories COMPLETE: success=$successCount, fail=$failCount ===") Log.w(TAG, "rowsAdapter size: ${rowsAdapter.size()}") + isDataLoaded = true + activity?.runOnUiThread { if (rowsAdapter.size() == 0) { Toast.makeText(requireContext(), "카테고리를 불러오지 못했습니다", Toast.LENGTH_LONG).show()