Skip to content

Commit

Permalink
refactor(episodeOptions): rewrite the sheet UI and code
Browse files Browse the repository at this point in the history
  • Loading branch information
quickdesh committed Aug 8, 2023
1 parent fe09078 commit 24280fc
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 158 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ enum class EpisodeDownloadAction {
START_NOW,
CANCEL,
DELETE,
SHOW_OPTIONS,
SHOW_QUALITIES,
}

@Composable
Expand Down Expand Up @@ -87,7 +87,7 @@ private fun NotDownloadedIndicator(
.size(IconButtonTokens.StateLayerSize)
.commonClickable(
enabled = enabled,
onLongClick = { onClick(EpisodeDownloadAction.SHOW_OPTIONS) },
onLongClick = { onClick(EpisodeDownloadAction.SHOW_QUALITIES) },
onClick = { onClick(EpisodeDownloadAction.START) },
)
.secondaryItemAlpha(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
Expand All @@ -31,7 +32,6 @@ import eu.kanade.presentation.entries.anime.DuplicateAnimeDialog
import eu.kanade.presentation.entries.anime.EpisodeOptionsDialogScreen
import eu.kanade.presentation.entries.anime.EpisodeSettingsDialog
import eu.kanade.presentation.entries.anime.components.AnimeCoverDialog
import eu.kanade.presentation.entries.anime.onDismissEpisodeOptionsDialogScreen
import eu.kanade.presentation.util.AssistContentScreen
import eu.kanade.presentation.util.Screen
import eu.kanade.presentation.util.isTabletUi
Expand Down Expand Up @@ -246,14 +246,23 @@ class AnimeScreen(
onDismissRequest = onDismissRequest,
)
}
is AnimeInfoScreenModel.Dialog.Options -> {
onDismissEpisodeOptionsDialogScreen = onDismissRequest
is AnimeInfoScreenModel.Dialog.ShowQualities -> {
EpisodeOptionsDialogScreen.onDismissDialog = onDismissRequest
val episodeTitle = if (dialog.anime.displayMode == Anime.EPISODE_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_episode,
episodeDecimalFormat.format(dialog.episode.episodeNumber.toDouble()),
)
} else {
dialog.episode.name
}
NavigatorAdaptiveSheet(
screen = EpisodeOptionsDialogScreen(
useExternalDownloader = screenModel.useExternalDownloader,
episodeTitle = episodeTitle,
episodeId = dialog.episode.id,
animeId = dialog.anime.id,
sourceId = dialog.source.id,
useExternalDownloader = screenModel.downloadPreferences.useExternalDownloader().get(),
),
onDismissRequest = onDismissRequest,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class AnimeInfoScreenModel(
val context: Context,
val animeId: Long,
private val isFromSource: Boolean,
internal val downloadPreferences: DownloadPreferences = Injekt.get(),
private val downloadPreferences: DownloadPreferences = Injekt.get(),
private val libraryPreferences: LibraryPreferences = Injekt.get(),
uiPreferences: UiPreferences = Injekt.get(),
private val trackPreferences: TrackPreferences = Injekt.get(),
Expand Down Expand Up @@ -130,6 +130,8 @@ class AnimeInfoScreenModel(
val episodeSwipeStartAction = libraryPreferences.swipeEpisodeStartAction().get()

val showNextEpisodeAirTime = trackPreferences.showNextEpisodeAiringTime().get()
val alwaysUseExternalPlayer = playerPreferences.alwaysUseExternalPlayer().get()
val useExternalDownloader = downloadPreferences.useExternalDownloader().get()

val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)
val dateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get()))
Expand All @@ -142,8 +144,6 @@ class AnimeInfoScreenModel(
internal val autoOpenTrack: Boolean
get() = successState?.trackingAvailable == true && trackPreferences.trackOnAddingToLibrary().get()

val alwaysUseExternalPlayer = playerPreferences.alwaysUseExternalPlayer().get()

/**
* Helper function to update the UI state only if it's currently in success state
*/
Expand Down Expand Up @@ -666,9 +666,9 @@ class AnimeInfoScreenModel(
EpisodeDownloadAction.DELETE -> {
deleteEpisodes(items.map { it.episode })
}
EpisodeDownloadAction.SHOW_OPTIONS -> {
EpisodeDownloadAction.SHOW_QUALITIES -> {
val episode = items.singleOrNull()?.episode ?: return
showOptionsDialog(episode)
showQualitiesDialog(episode)
}
}
}
Expand All @@ -682,7 +682,7 @@ class AnimeInfoScreenModel(

DownloadAction.UNVIEWED_ITEMS -> getUnseenEpisodes()
}
if (!episodesToDownload.isNullOrEmpty()) {
if (episodesToDownload.isNotEmpty()) {
startDownload(episodesToDownload, false)
}
}
Expand Down Expand Up @@ -958,7 +958,7 @@ class AnimeInfoScreenModel(
.map { tracks ->
loggedServices
// Map to TrackItem
.map { service -> AnimeTrackItem(tracks.find { it.syncId.toLong() == service.id }, service) }
.map { service -> AnimeTrackItem(tracks.find { it.syncId == service.id }, service) }
// Show only if the service supports this anime's source
.filter { (it.service as? EnhancedAnimeTrackService)?.accept(source!!) ?: true }
}
Expand All @@ -982,7 +982,7 @@ class AnimeInfoScreenModel(
data class ChangeCategory(val anime: Anime, val initialSelection: List<CheckboxState<Category>>) : Dialog()
data class DeleteEpisodes(val episodes: List<Episode>) : Dialog()
data class DuplicateAnime(val anime: Anime, val duplicate: Anime) : Dialog()
data class Options(val episode: Episode, val anime: Anime, val source: AnimeSource) : Dialog()
data class ShowQualities(val episode: Episode, val anime: Anime, val source: AnimeSource) : Dialog()
object ChangeAnimeSkipIntro : Dialog()
object SettingsSheet : Dialog()
object TrackSheet : Dialog()
Expand Down Expand Up @@ -1043,11 +1043,11 @@ class AnimeInfoScreenModel(
}
}

private fun showOptionsDialog(episode: Episode) {
private fun showQualitiesDialog(episode: Episode) {
mutableState.update { state ->
when (state) {
AnimeScreenState.Loading -> state
is AnimeScreenState.Success -> { state.copy(dialog = Dialog.Options(episode, state.anime, state.source)) }
is AnimeScreenState.Success -> { state.copy(dialog = Dialog.ShowQualities(episode, state.anime, state.source)) }
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.Migrations
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.core.Constants
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.EpisodeCache
Expand Down Expand Up @@ -518,11 +519,11 @@ class MainActivity : BaseActivity() {
const val INTENT_SEARCH_QUERY = "query"
const val INTENT_SEARCH_FILTER = "filter"

var externalPlayerResult: ActivityResultLauncher<Intent>? = null
private var externalPlayerResult: ActivityResultLauncher<Intent>? = null

suspend fun startPlayerActivity(context: Context, animeId: Long, episodeId: Long, extPlayer: Boolean) {
suspend fun startPlayerActivity(context: Context, animeId: Long, episodeId: Long, extPlayer: Boolean, video: Video? = null) {
if (extPlayer) {
externalPlayerResult?.launch(ExternalIntents.newIntent(context, animeId, episodeId)) ?: return
externalPlayerResult?.launch(ExternalIntents.newIntent(context, animeId, episodeId, video)) ?: return
} else {
context.startActivity(PlayerActivity.newIntent(context, animeId, episodeId))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ class ExternalIntents {
* @param animeId the id of the anime.
* @param episodeId the id of the episode.
*/
suspend fun getExternalIntent(context: Context, animeId: Long?, episodeId: Long?): Intent? {
suspend fun getExternalIntent(context: Context, animeId: Long?, episodeId: Long?, chosenVideo: Video?): Intent? {
anime = getAnime.await(animeId!!) ?: return null
source = sourceManager.get(anime.source) ?: return null
episode = getEpisodeByAnimeId.await(anime.id).find { it.id == episodeId } ?: return null

val video = EpisodeLoader.getLinks(episode, anime, source).asFlow().first()[0]
val video = chosenVideo ?: EpisodeLoader.getLinks(episode, anime, source).asFlow().first()[0]

val videoUrl = getVideoUrl(context, video) ?: return null

Expand Down Expand Up @@ -491,8 +491,8 @@ class ExternalIntents {
* @param animeId the id of the anime.
* @param episodeId the id of the episode.
*/
suspend fun newIntent(context: Context, animeId: Long?, episodeId: Long?): Intent? {
return externalIntents.getExternalIntent(context, animeId, episodeId)
suspend fun newIntent(context: Context, animeId: Long?, episodeId: Long?, video: Video?): Intent? {
return externalIntents.getExternalIntent(context, animeId, episodeId, video)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class AnimeUpdatesScreenModel(
private val getAnime: GetAnime = Injekt.get(),
private val getEpisode: GetEpisode = Injekt.get(),
private val libraryPreferences: LibraryPreferences = Injekt.get(),
internal val downloadPreferences: DownloadPreferences = Injekt.get(),
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
downloadPreferences: DownloadPreferences = Injekt.get(),
uiPreferences: UiPreferences = Injekt.get(),
) : StateScreenModel<AnimeUpdatesState>(AnimeUpdatesState()) {

Expand All @@ -70,6 +70,8 @@ class AnimeUpdatesScreenModel(
val lastUpdated by libraryPreferences.libraryUpdateLastTimestamp().asState(coroutineScope)
val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)

val useExternalDownloader = downloadPreferences.useExternalDownloader().get()

// First and last selected index in list
private val selectedPositions: Array<Int> = arrayOf(-1, -1)
private val selectedEpisodeIds: HashSet<Long> = HashSet()
Expand Down Expand Up @@ -183,9 +185,9 @@ class AnimeUpdatesScreenModel(
EpisodeDownloadAction.DELETE -> {
deleteEpisodes(items)
}
EpisodeDownloadAction.SHOW_OPTIONS -> {
EpisodeDownloadAction.SHOW_QUALITIES -> {
val update = items.singleOrNull()?.update ?: return@launch
showOptionsDialog(update)
showQualitiesDialog(update)
}
}
toggleAllSelection(false)
Expand Down Expand Up @@ -275,8 +277,8 @@ class AnimeUpdatesScreenModel(
setDialog(Dialog.DeleteConfirmation(updatesItem))
}

private fun showOptionsDialog(update: AnimeUpdatesWithRelations) {
setDialog(Dialog.Options(update.episodeId, update.animeId, update.sourceId))
private fun showQualitiesDialog(update: AnimeUpdatesWithRelations) {
setDialog(Dialog.ShowQualities(update.episodeName, update.episodeId, update.animeId, update.sourceId))
}

fun toggleSelection(
Expand Down Expand Up @@ -378,7 +380,7 @@ class AnimeUpdatesScreenModel(

sealed class Dialog {
data class DeleteConfirmation(val toDelete: List<AnimeUpdatesItem>) : Dialog()
data class Options(val episodeId: Long, val animeId: Long, val sourceId: Long) : Dialog()
data class ShowQualities(val episodeTitle: String, val episodeId: Long, val animeId: Long, val sourceId: Long) : Dialog()
}

sealed class Event {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.NavigatorAdaptiveSheet
import eu.kanade.presentation.components.TabContent
import eu.kanade.presentation.entries.anime.EpisodeOptionsDialogScreen
import eu.kanade.presentation.entries.anime.onDismissEpisodeOptionsDialogScreen
import eu.kanade.presentation.updates.UpdatesDeleteConfirmationDialog
import eu.kanade.presentation.updates.anime.AnimeUpdateScreen
import eu.kanade.tachiyomi.R
Expand Down Expand Up @@ -87,14 +86,15 @@ fun Screen.animeUpdatesTab(
isManga = false,
)
}
is AnimeUpdatesScreenModel.Dialog.Options -> {
onDismissEpisodeOptionsDialogScreen = onDismissDialog
is AnimeUpdatesScreenModel.Dialog.ShowQualities -> {
EpisodeOptionsDialogScreen.onDismissDialog = onDismissDialog
NavigatorAdaptiveSheet(
screen = EpisodeOptionsDialogScreen(
useExternalDownloader = screenModel.useExternalDownloader,
episodeTitle = dialog.episodeTitle,
episodeId = dialog.episodeId,
animeId = dialog.animeId,
sourceId = dialog.sourceId,
useExternalDownloader = screenModel.downloadPreferences.useExternalDownloader().get(),
),
onDismissRequest = onDismissDialog,
)
Expand Down

0 comments on commit 24280fc

Please sign in to comment.