Skip to content

Commit

Permalink
feat(episode-options): Add play internally option (#1364)
Browse files Browse the repository at this point in the history
  • Loading branch information
Samfun75 authored Jan 28, 2024
1 parent f0af446 commit bcc24e4
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.Input
import androidx.compose.material.icons.outlined.NavigateNext
import androidx.compose.material.icons.outlined.OpenInNew
import androidx.compose.material.icons.outlined.SystemUpdateAlt
Expand Down Expand Up @@ -256,6 +257,18 @@ private fun VideoList(
)
}
},
onIntPlayerClicked = {
scope.launch {
MainActivity.startPlayerActivity(
context,
anime.id,
episode.id,
false,
selectedVideo,
videoList,
)
}
},
)
}
}
Expand Down Expand Up @@ -289,6 +302,7 @@ private fun QualityOptions(
onExtDownloadClicked: () -> Unit = {},
onCopyClicked: () -> Unit = {},
onExtPlayerClicked: () -> Unit = {},
onIntPlayerClicked: () -> Unit = {},
) {
val closeMenu = { EpisodeOptionsDialogScreen.onDismissDialog() }

Expand Down Expand Up @@ -325,6 +339,15 @@ private fun QualityOptions(
closeMenu()
},
)

ClickableRow(
text = stringResource(MR.strings.action_play_internally),
icon = Icons.Outlined.Input,
onClick = {
onIntPlayerClicked()
closeMenu()
},
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ class MainActivity : BaseActivity() {
episodeId: Long,
extPlayer: Boolean,
video: Video? = null,
videoList: List<Video>? = null,
) {
if (extPlayer) {
val intent = try {
Expand All @@ -583,7 +584,9 @@ class MainActivity : BaseActivity() {
}
externalPlayerResult?.launch(intent) ?: return
} else {
context.startActivity(PlayerActivity.newIntent(context, animeId, episodeId))
context.startActivity(
PlayerActivity.newIntent(context, animeId, episodeId, videoList, videoList?.indexOf(video)),
)
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.model.SerializableVideo.Companion.serialize
import eu.kanade.tachiyomi.animesource.model.Track
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
Expand Down Expand Up @@ -113,10 +114,18 @@ class PlayerActivity : BaseActivity() {
internal val playerPreferences: PlayerPreferences = Injekt.get()

companion object {
fun newIntent(context: Context, animeId: Long?, episodeId: Long?): Intent {
fun newIntent(
context: Context,
animeId: Long?,
episodeId: Long?,
vidList: List<Video>? = null,
vidIndex: Int? = null,
): Intent {
return Intent(context, PlayerActivity::class.java).apply {
putExtra("animeId", animeId)
putExtra("episodeId", episodeId)
vidIndex?.let { putExtra("vidIndex", it) }
vidList?.let { putExtra("vidList", it.serialize()) }
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
}
Expand All @@ -125,6 +134,8 @@ class PlayerActivity : BaseActivity() {
override fun onNewIntent(intent: Intent) {
val animeId = intent.extras!!.getLong("animeId", -1)
val episodeId = intent.extras!!.getLong("episodeId", -1)
val vidList = intent.extras!!.getString("vidList", "")
val vidIndex = intent.extras!!.getInt("vidIndex", 0)
if (animeId == -1L || episodeId == -1L) {
finish()
return
Expand All @@ -142,7 +153,7 @@ class PlayerActivity : BaseActivity() {
it.copy(isLoadingEpisode = true)
}

val initResult = viewModel.init(animeId, episodeId)
val initResult = viewModel.init(animeId, episodeId, vidList, vidIndex)
if (!initResult.second.getOrDefault(false)) {
val exception = initResult.second.exceptionOrNull() ?: IllegalStateException(
"Unknown error",
Expand Down
26 changes: 20 additions & 6 deletions app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import eu.kanade.domain.track.anime.interactor.TrackEpisode
import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.tachiyomi.animesource.AnimeSource
import eu.kanade.tachiyomi.animesource.model.SerializableVideo.Companion.toVideoList
import eu.kanade.tachiyomi.animesource.model.Track
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
Expand Down Expand Up @@ -233,7 +234,12 @@ class PlayerViewModel @JvmOverloads constructor(
* Initializes this presenter with the given [animeId] and [initialEpisodeId]. This method will
* fetch the anime from the database and initialize the episode.
*/
suspend fun init(animeId: Long, initialEpisodeId: Long): Pair<InitResult, Result<Boolean>> {
suspend fun init(
animeId: Long,
initialEpisodeId: Long,
vidList: String,
vidIndex: Int,
): Pair<InitResult, Result<Boolean>> {
val defaultResult = InitResult(currentVideoList, 0, null)
if (!needsInit()) return Pair(defaultResult, Result.success(true))
return try {
Expand All @@ -252,13 +258,21 @@ class PlayerViewModel @JvmOverloads constructor(

val currentEp = currentEpisode ?: throw Exception("No episode loaded.")

EpisodeLoader.getLinks(currentEp.toDomainEpisode()!!, anime, source)
.takeIf { it.isNotEmpty() }
?.also { currentVideoList = it }
?: run {
if (vidList.isNotBlank()) {
currentVideoList = vidList.toVideoList().ifEmpty {
currentVideoList = null
throw Exception("Video list is empty.")
throw Exception("Video selected from empty list?")
}
qualityIndex = vidIndex
} else {
EpisodeLoader.getLinks(currentEp.toDomainEpisode()!!, anime, source)
.takeIf { it.isNotEmpty() }
?.also { currentVideoList = it }
?: run {
currentVideoList = null
throw Exception("Video list is empty.")
}
}

val result = InitResult(
videoList = currentVideoList,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import android.net.Uri
import eu.kanade.tachiyomi.network.ProgressListener
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import okhttp3.Headers
import rx.subjects.Subject

@Serializable
data class Track(val url: String, val lang: String)

open class Video(
Expand Down Expand Up @@ -90,3 +94,45 @@ open class Video(
ERROR,
}
}

@Serializable
data class SerializableVideo(
val url: String = "",
val quality: String = "",
var videoUrl: String? = null,
val headers: List<Pair<String, String>>? = null,
val subtitleTracks: List<Track> = emptyList(),
val audioTracks: List<Track> = emptyList(),
) {

companion object {
fun List<Video>.serialize(): String =
Json.encodeToString(
this.map { vid ->
SerializableVideo(
vid.url,
vid.quality,
vid.videoUrl,
headers = vid.headers?.toList(),
vid.subtitleTracks,
vid.audioTracks,
)
},
)

fun String.toVideoList(): List<Video> =
Json.decodeFromString<List<SerializableVideo>>(this)
.map { sVid ->
Video(
sVid.url,
sVid.quality,
sVid.videoUrl,
sVid.headers
?.flatMap { it.toList() }
?.let { Headers.headersOf(*it.toTypedArray()) },
sVid.subtitleTracks,
sVid.audioTracks,
)
}
}
}

0 comments on commit bcc24e4

Please sign in to comment.