Refactor playback launch logic and navigation

Refactor launchPlaybackWithDownloadPreference to use StreamLaunchStore for launching streams and update related navigation logic.
This commit is contained in:
AdityasahuX07 2026-04-25 15:36:42 +05:30 committed by GitHub
parent 727b48bbc8
commit 5b5a8b6906
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -656,6 +656,11 @@ private fun MainAppContent(
AppDeepLinkRepository.markConsumed(deepLink) AppDeepLinkRepository.markConsumed(deepLink)
} }
null -> Unit
}
}
}
fun launchPlaybackWithDownloadPreference( fun launchPlaybackWithDownloadPreference(
type: String, type: String,
videoId: String, videoId: String,
@ -717,46 +722,14 @@ private fun MainAppContent(
return return
} }
} }
}
}
fun launchPlaybackWithDownloadPreference( val streamLaunchId = StreamLaunchStore.put(
type: String, StreamLaunch(
videoId: String, type = type,
parentMetaId: String,
parentMetaType: String,
title: String,
logo: String?,
poster: String?,
background: String?,
seasonNumber: Int?,
episodeNumber: Int?,
episodeTitle: String?,
episodeThumbnail: String?,
pauseDescription: String?,
resumePositionMs: Long?,
resumeProgressFraction: Float?,
manualSelection: Boolean,
startFromBeginning: Boolean,
) {
val targetResumePositionMs = if (startFromBeginning) 0L else (resumePositionMs ?: 0L)
val targetResumeProgressFraction = if (startFromBeginning) null else resumeProgressFraction
if (!manualSelection) {
val downloadedItem = DownloadsRepository.findPlayableDownload(
parentMetaId = parentMetaId,
seasonNumber = seasonNumber,
episodeNumber = episodeNumber,
videoId = videoId, videoId = videoId,
) parentMetaId = parentMetaId,
val localSourceUrl = downloadedItem?.localFileUri parentMetaType = parentMetaType,
if (!localSourceUrl.isNullOrBlank()) {
val launchId = PlayerLaunchStore.put(
PlayerLaunch(
title = title, title = title,
sourceUrl = localSourceUrl,
sourceHeaders = emptyMap(),
sourceResponseHeaders = emptyMap(),
logo = logo, logo = logo,
poster = poster, poster = poster,
background = background, background = background,
@ -764,40 +737,38 @@ private fun MainAppContent(
episodeNumber = episodeNumber, episodeNumber = episodeNumber,
episodeTitle = episodeTitle, episodeTitle = episodeTitle,
episodeThumbnail = episodeThumbnail, episodeThumbnail = episodeThumbnail,
streamTitle = downloadedItem.streamTitle.ifBlank { title },
streamSubtitle = downloadedItem.streamSubtitle,
pauseDescription = pauseDescription, pauseDescription = pauseDescription,
providerName = downloadedItem.providerName.ifBlank { "Downloaded" }, resumePositionMs = if (startFromBeginning) 0L else resumePositionMs,
providerAddonId = downloadedItem.providerAddonId, resumeProgressFraction = targetResumeProgressFraction,
contentType = type, manualSelection = manualSelection,
startFromBeginning = startFromBeginning,
),
)
navController.navigate(
StreamRoute(launchId = streamLaunchId),
)
}
val onPlay: (String, String, String, String, String, String?, String?, String?, Int?, Int?, String?, String?, String?, Long?) -> Unit =
{ type, videoId, parentMetaId, parentMetaType, title, logo, poster, background, seasonNumber, episodeNumber, episodeTitle, episodeThumbnail, pauseDescription, resumePositionMs ->
launchPlaybackWithDownloadPreference(
type = type,
videoId = videoId, videoId = videoId,
parentMetaId = parentMetaId, parentMetaId = parentMetaId,
parentMetaType = parentMetaType, parentMetaType = parentMetaType,
initialPositionMs = targetResumePositionMs, title = title,
initialProgressFraction = targetResumeProgressFraction, logo = logo,
), poster = poster,
) background = background,
navController.navigate(PlayerRoute(launchId = launchId)) seasonNumber = seasonNumber,
return episodeNumber = episodeNumber,
} episodeTitle = episodeTitle,
} episodeThumbnail = episodeThumbnail,
pauseDescription = pauseDescription,
val librarySectionSubtitle = if (libraryUiState.sourceMode == LibrarySourceMode.TRAKT) { resumePositionMs = resumePositionMs,
stringResource(Res.string.compose_catalog_subtitle_trakt_library) resumeProgressFraction = null,
} else { manualSelection = false,
stringResource(Res.string.compose_catalog_subtitle_library) startFromBeginning = false,
}
val onLibrarySectionViewAllClick: (LibrarySection) -> Unit = { section ->
navController.navigate(
CatalogRoute(
title = section.displayTitle,
subtitle = librarySectionSubtitle,
manifestUrl = INTERNAL_LIBRARY_MANIFEST_URL,
type = section.items.firstOrNull()?.type ?: "movie",
catalogId = section.type,
supportsPagination = false,
),
) )
} }
@ -837,15 +808,17 @@ private fun MainAppContent(
) )
} }
val librarySectionSubtitle = if (libraryUiState.sourceMode == LibrarySourceMode.TRAKT) {
stringResource(Res.string.compose_catalog_subtitle_trakt_library)
} else {
stringResource(Res.string.compose_catalog_subtitle_library)
}
val onLibrarySectionViewAllClick: (LibrarySection) -> Unit = { section -> val onLibrarySectionViewAllClick: (LibrarySection) -> Unit = { section ->
navController.navigate( navController.navigate(
CatalogRoute( CatalogRoute(
title = section.displayTitle, title = section.displayTitle,
subtitle = if (libraryUiState.sourceMode == LibrarySourceMode.TRAKT) { subtitle = librarySectionSubtitle,
"Trakt Library"
} else {
"Library"
},
manifestUrl = INTERNAL_LIBRARY_MANIFEST_URL, manifestUrl = INTERNAL_LIBRARY_MANIFEST_URL,
type = section.items.firstOrNull()?.type ?: "movie", type = section.items.firstOrNull()?.type ?: "movie",
catalogId = section.type, catalogId = section.type,
@ -986,7 +959,7 @@ private fun MainAppContent(
}, },
onLibraryPosterLongClick = { item -> onLibraryPosterLongClick = { item ->
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
selectedPosterForActions = item.toMetaPreview() // reuse existing sheet selectedPosterForActions = item.toMetaPreview()
}, },
onLibrarySectionViewAllClick = onLibrarySectionViewAllClick, onLibrarySectionViewAllClick = onLibrarySectionViewAllClick,
onContinueWatchingClick = onContinueWatchingClick, onContinueWatchingClick = onContinueWatchingClick,
@ -1689,34 +1662,15 @@ private fun MainAppContent(
) )
} == true, } == true,
onDismiss = { selectedPosterForActions = null }, onDismiss = { selectedPosterForActions = null },
// TAP → direct save/remove (watchlist or local library)
onToggleLibrary = { onToggleLibrary = {
selectedPosterForActions?.let { preview -> selectedPosterForActions?.let { preview ->
val libraryItem = preview.toLibraryItem(savedAtEpochMs = 0L) val libraryItem = preview.toLibraryItem(savedAtEpochMs = 0L)
if (!isTraktConnected) {
LibraryRepository.toggleSaved(libraryItem) LibraryRepository.toggleSaved(libraryItem)
} else {
// Tap = directly toggle watchlist (first tab)
coroutineScope.launch {
runCatching {
val snapshot = LibraryRepository.getMembershipSnapshot(libraryItem)
val tabs = LibraryRepository.traktListTabs()
val watchlistKey = tabs.firstOrNull()?.key
if (watchlistKey != null) {
val currentlyIn = snapshot[watchlistKey] == true
val desired = tabs.associate { tab ->
tab.key to if (tab.key == watchlistKey) !currentlyIn else (snapshot[tab.key] == true)
}
}.onFailure { error ->
pickerError = error.message ?: getString(Res.string.trakt_lists_load_failed)
}
}.onFailure {
LibraryRepository.toggleSaved(libraryItem)
}
}
}
} }
}, },
onOpenListPicker = if (isTraktConnected) { // LONG PRESS → open Trakt list picker (only when Trakt is connected)
onToggleLibraryLongClick = if (isTraktConnected) {
{ {
selectedPosterForActions?.let { preview -> selectedPosterForActions?.let { preview ->
val libraryItem = preview.toLibraryItem(savedAtEpochMs = 0L) val libraryItem = preview.toLibraryItem(savedAtEpochMs = 0L)
@ -1736,7 +1690,7 @@ private fun MainAppContent(
tab.key to (snapshot[tab.key] == true) tab.key to (snapshot[tab.key] == true)
} }
}.onFailure { error -> }.onFailure { error ->
pickerError = error.message ?: "Failed to load Trakt lists" pickerError = error.message ?: getString(Res.string.trakt_lists_load_failed)
} }
pickerPending = false pickerPending = false
} }
@ -1807,24 +1761,6 @@ private fun MainAppContent(
pickerError = null pickerError = null
} }
}, },
onSave = {
val item = pickerItem ?: return@TraktListPickerDialog
coroutineScope.launch {
pickerPending = true
pickerError = null
runCatching {
LibraryRepository.applyMembershipChanges(
item = item,
desiredMembership = pickerMembership,
)
}.onSuccess {
showLibraryListPicker = false
pickerItem = null
pickerError = null
}.onFailure { error ->
pickerError = error.message ?: "Failed to update Trakt lists"
}
},
onSave = { onSave = {
val item = pickerItem ?: return@TraktListPickerDialog val item = pickerItem ?: return@TraktListPickerDialog
coroutineScope.launch { coroutineScope.launch {
@ -1940,6 +1876,7 @@ private fun AppTabHost(
onPosterClick: ((MetaPreview) -> Unit)? = null, onPosterClick: ((MetaPreview) -> Unit)? = null,
onPosterLongClick: ((MetaPreview) -> Unit)? = null, onPosterLongClick: ((MetaPreview) -> Unit)? = null,
onLibraryPosterClick: ((LibraryItem) -> Unit)? = null, onLibraryPosterClick: ((LibraryItem) -> Unit)? = null,
onLibraryPosterLongClick: ((LibraryItem) -> Unit)? = null,
onLibrarySectionViewAllClick: ((LibrarySection) -> Unit)? = null, onLibrarySectionViewAllClick: ((LibrarySection) -> Unit)? = null,
onContinueWatchingClick: ((ContinueWatchingItem) -> Unit)? = null, onContinueWatchingClick: ((ContinueWatchingItem) -> Unit)? = null,
onContinueWatchingLongPress: ((ContinueWatchingItem) -> Unit)? = null, onContinueWatchingLongPress: ((ContinueWatchingItem) -> Unit)? = null,
@ -1956,7 +1893,6 @@ private fun AppTabHost(
onCollectionsSettingsClick: () -> Unit = {}, onCollectionsSettingsClick: () -> Unit = {},
onFolderClick: ((collectionId: String, folderId: String) -> Unit)? = null, onFolderClick: ((collectionId: String, folderId: String) -> Unit)? = null,
onInitialHomeContentRendered: () -> Unit = {}, onInitialHomeContentRendered: () -> Unit = {},
onLibraryPosterLongClick: ((LibraryItem) -> Unit)? = null,
) { ) {
val tabStateHolder = rememberSaveableStateHolder() val tabStateHolder = rememberSaveableStateHolder()