Skip to content

Commit

Permalink
Merge pull request #187 from anilibria/feature/tv-features
Browse files Browse the repository at this point in the history
Feature/tv features
  • Loading branch information
RadiationX authored Apr 18, 2024
2 parents 8ce645d + b793942 commit 06eaf66
Show file tree
Hide file tree
Showing 20 changed files with 224 additions and 242 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import android.content.Intent
import android.net.http.SslError
import android.os.Bundle
import android.view.WindowManager
import android.webkit.*
import android.webkit.SslErrorHandler
import android.webkit.WebResourceResponse
import android.webkit.WebSettings
import android.webkit.WebView
import by.kirich1409.viewbindingdelegate.viewBinding
import ru.radiationx.anilibria.R
import ru.radiationx.anilibria.apptheme.AppTheme
Expand Down Expand Up @@ -81,7 +84,6 @@ class WebPlayerActivity : BaseActivity(R.layout.activity_moon) {

binding.webView.settings.apply {
cacheMode = WebSettings.LOAD_NO_CACHE
javaScriptEnabled = true
}

val webViewClient = object : WebViewClientCompat() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,10 @@ import ru.radiationx.anilibria.ui.activities.player.models.LoadingState
import ru.radiationx.anilibria.ui.activities.player.models.PlayerAction
import ru.radiationx.anilibria.ui.activities.player.models.PlayerData
import ru.radiationx.anilibria.ui.activities.player.models.PlayerDataState
import ru.radiationx.anilibria.ui.activities.player.models.PlayerRelease
import ru.radiationx.data.datasource.holders.EpisodesCheckerHolder
import ru.radiationx.data.datasource.holders.PreferencesHolder
import ru.radiationx.data.entity.common.PlayerQuality
import ru.radiationx.data.entity.domain.release.EpisodeAccess
import ru.radiationx.data.entity.domain.release.Release
import ru.radiationx.data.entity.domain.types.EpisodeId
import ru.radiationx.data.entity.domain.types.ReleaseId
import ru.radiationx.data.interactors.ReleaseInteractor
import ru.radiationx.data.repository.ReleaseRepository
import ru.radiationx.shared.ktx.coRunCatching
Expand Down Expand Up @@ -114,7 +110,7 @@ class PlayerViewModel(

fun onSettingsClick() {
launchWithData { data ->
val episode = data.episodes.find { it.id == _episodeId.value } ?: return@launchWithData
val episode = data.getEpisode(_episodeId.value) ?: return@launchWithData
val quality = preferencesHolder.playerQuality.value
val settingsState = PlayerSettingsState(
currentSpeed = preferencesHolder.playSpeed.value,
Expand Down Expand Up @@ -162,13 +158,7 @@ class PlayerViewModel(
@OptIn(DelicateCoroutinesApi::class)
fun saveEpisodeSeek(episodeId: EpisodeId, seek: Long) {
GlobalScope.launch {
val access = EpisodeAccess(
id = episodeId,
seek = seek,
isViewed = true,
lastAccess = System.currentTimeMillis()
)
episodesCheckerHolder.putEpisode(access)
releaseInteractor.setAccessSeek(episodeId, seek)
}
}

Expand Down Expand Up @@ -203,7 +193,9 @@ class PlayerViewModel(
_dataJob = viewModelScope.launch {
_dataState.update { LoadingState(loading = true) }
coRunCatching {
loadAllData(episodeId)
releaseInteractor
.loadWithFranchises(episodeId.releaseId)
.map { it.toPlayerRelease() }
}.onSuccess { releases ->
_dataState.update { it.copy(data = PlayerData(releases)) }
playEpisode(episodeId)
Expand All @@ -226,31 +218,5 @@ class PlayerViewModel(
}
}

private suspend fun loadAllData(episodeId: EpisodeId): List<PlayerRelease> {
val rootRelease = requireNotNull(releaseInteractor.getFull(episodeId.releaseId)) {
"Loaded release is null for $episodeId"
}
val rootReleaseIds = mutableListOf<ReleaseId>()
rootRelease.franchises.forEach { franchise ->
franchise.releases.forEach {
rootReleaseIds.add(it.id)
}
}
if (rootReleaseIds.isEmpty()) {
return listOf(rootRelease.toPlayerRelease())
}
val idsToLoad = rootReleaseIds.filter { it != rootRelease.id }
val franchiseReleases = releaseRepository.getFullReleasesById(idsToLoad)

val allReleasesMap = mutableMapOf<ReleaseId, Release>()
allReleasesMap[rootRelease.id] = rootRelease
franchiseReleases.forEach {
allReleasesMap[it.id] = it
}
return rootReleaseIds.mapNotNull {
allReleasesMap[it]?.toPlayerRelease()
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,16 @@ class VideoPlayerActivity : BaseActivity(R.layout.activity_videoplayer) {
binding.playerView.onInteraction()
}

private fun handleEpisode(intent: Intent, bundle: Bundle?, isNew: Boolean) {
private fun handleEpisode(intent: Intent, bundle: Bundle?, isNewIntent: Boolean) {
val intentEpisodeId = intent.getExtraNotNull<EpisodeId>(ARG_EPISODE_ID)
val savedEpisodeId = bundle?.getExtra<EpisodeId>(KEY_EPISODE_ID)
val episodeId = savedEpisodeId ?: intentEpisodeId
val episodeId = if (isNewIntent) {
intentEpisodeId
} else {
savedEpisodeId ?: intentEpisodeId
}
analytics.handleEpisode(
isNewIntent = isNew,
isNewIntent = isNewIntent,
hasBundle = bundle != null,
episodeId = episodeId
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ fun Release.toPlayerRelease() = PlayerRelease(
episodes = episodes.asReversed()
)

fun PlayerData.toDataState(episodeId: EpisodeId): PlayerDataState {
return getRelease(episodeId.releaseId).toDataState(episodeId)
fun PlayerData.toDataState(episodeId: EpisodeId): PlayerDataState? {
return getRelease(episodeId.releaseId)?.toDataState(episodeId)
}

fun PlayerRelease.toDataState(episodeId: EpisodeId) = PlayerDataState(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ data class PlayerData(
) {
val episodes: List<Episode> = releases.flatMap { it.episodes }

fun getRelease(releaseId: ReleaseId): PlayerRelease {
return requireNotNull(releases.find { it.id == releaseId }) {
"No loaded release for id ${releaseId.id} in ${releases.map { it.id.id }}"
}
fun getRelease(releaseId: ReleaseId): PlayerRelease? {
return releases.find { it.id == releaseId }
}

fun getEpisode(episodeId: EpisodeId): Episode {
return requireNotNull(episodes.find { it.id == episodeId }) {
"No loaded episode for id $episodeId"
}
fun getEpisode(episodeId: EpisodeId): Episode? {
return episodes.find { it.id == episodeId }
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ru.radiationx.anilibria.ui.widgets;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
Expand Down Expand Up @@ -92,6 +91,8 @@ public void init() {
settings.setDefaultFontSize(16);
settings.setTextZoom(100);
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowContentAccess(true);
settings.setAllowFileAccessFromFileURLs(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,20 @@ package ru.radiationx.anilibria.screen.details

import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.toList
import ru.radiationx.anilibria.common.BaseCardsViewModel
import ru.radiationx.anilibria.common.CardsDataConverter
import ru.radiationx.anilibria.common.LibriaCard
import ru.radiationx.anilibria.common.LibriaCardRouter
import ru.radiationx.data.interactors.ReleaseInteractor
import ru.radiationx.data.repository.ReleaseRepository
import toothpick.InjectConstructor

@InjectConstructor
class DetailRelatedViewModel(
argExtra: DetailExtra,
private val releaseInteractor: ReleaseInteractor,
private val releaseRepository: ReleaseRepository,
private val converter: CardsDataConverter,
private val cardRouter: LibriaCardRouter,
) : BaseCardsViewModel() {
Expand All @@ -44,20 +39,9 @@ class DetailRelatedViewModel(
}

override suspend fun getLoader(requestPage: Int): List<LibriaCard> {
val release = releaseInteractor.getFull(releaseId) ?: releaseInteractor.getItem(releaseId)
val releaseCodes = DetailsViewModel.getReleasesFromDesc(release?.description.orEmpty())
if (releaseCodes.isEmpty()) {
return emptyList()
}

val singles = releaseCodes.map {
flow { emit(releaseRepository.getRelease(it)) }
}
return merge(*singles.toTypedArray()).toList()
.let { releases ->
releaseInteractor.updateItemsCache(releases)
releases.map { converter.toCard(it) }
}
val releases = releaseInteractor.loadWithFranchises(releaseId).filter { it.id != releaseId }
releaseInteractor.updateItemsCache(releases)
return releases.map { converter.toCard(it) }
}

override fun hasMoreCards(newCards: List<LibriaCard>, allCards: List<LibriaCard>): Boolean =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,9 @@ class DetailsViewModel(
) : BaseRowsViewModel() {

companion object {
private val linkPattern = Regex("\\/release\\/([^.]+?)\\.html")

const val RELEASE_ROW_ID = 1L
const val RELATED_ROW_ID = 2L
const val RECOMMENDS_ROW_ID = 3L

fun getReleasesFromDesc(description: String): List<ReleaseCode> {
return linkPattern
.findAll(description)
.map { it.groupValues[1] }
.map { ReleaseCode(it) }
.toList()
}
}

private val releaseId = argExtra.id
Expand All @@ -65,9 +55,9 @@ class DetailsViewModel(
emit(it)
}
}
.map { it.description.orEmpty() }
.distinctUntilChanged()
.map { getReleasesFromDesc(it) }
.map { release ->
release.getFranchisesIds().filter { it != release.id }
}
.distinctUntilChanged()
.onEach {
updateAvailableRow(RELATED_ROW_ID, it.isNotEmpty())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package ru.radiationx.anilibria.screen.player

import kotlinx.coroutines.flow.MutableStateFlow
import ru.radiationx.data.entity.domain.release.Release
import ru.radiationx.data.entity.domain.types.EpisodeId
import ru.radiationx.shared.ktx.EventFlow
import toothpick.InjectConstructor

@InjectConstructor
class PlayerController {

val data = MutableStateFlow<List<Release>?>(null)

val selectEpisodeRelay = EventFlow<EpisodeId>()

fun reset() {
data.value = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ class PlayerFragment : BasePlayerFragment() {
override fun onSpeedClick() = viewModel.onSpeedClick()
override fun onEpisodesClick() = viewModel.onEpisodesClick(getPosition())
}
progressBarManager.initialDelay = 0
progressBarManager.show()

subscribeTo(viewModel.videoData.filterNotNull()) {
progressBarManager.hide()
playerGlue?.apply {
title = it.title
subtitle = it.subtitle
Expand Down
Loading

0 comments on commit 06eaf66

Please sign in to comment.