mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
download button + resume watching
This commit is contained in:
parent
d763b4a7aa
commit
2c10df6231
4 changed files with 158 additions and 133 deletions
|
@ -40,22 +40,24 @@ import com.lagradost.cloudstream3.mvvm.*
|
||||||
import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
|
import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick
|
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick
|
||||||
|
import com.lagradost.cloudstream3.ui.download.EasyDownloadButton
|
||||||
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent
|
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent
|
||||||
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
|
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
|
import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
|
||||||
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper
|
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||||
|
@ -225,10 +227,11 @@ class ResultFragment : ResultTrailerPlayer() {
|
||||||
return inflater.inflate(R.layout.fragment_result_swipe, container, false)
|
return inflater.inflate(R.layout.fragment_result_swipe, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var downloadButton: EasyDownloadButton? = null
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
updateUIListener = null
|
updateUIListener = null
|
||||||
(result_episodes?.adapter as EpisodeAdapter?)?.killAdapter()
|
(result_episodes?.adapter as EpisodeAdapter?)?.killAdapter()
|
||||||
//downloadButton?.dispose() //TODO READD
|
downloadButton?.dispose()
|
||||||
//somehow this still leaks and I dont know why????
|
//somehow this still leaks and I dont know why????
|
||||||
// todo look at https://github.com/discord/OverlappingPanels/blob/70b4a7cf43c6771873b1e091029d332896d41a1a/sample_app/src/main/java/com/discord/sampleapp/MainActivity.kt
|
// todo look at https://github.com/discord/OverlappingPanels/blob/70b4a7cf43c6771873b1e091029d332896d41a1a/sample_app/src/main/java/com/discord/sampleapp/MainActivity.kt
|
||||||
PanelsChildGestureRegionObserver.Provider.get().removeGestureRegionsUpdateListener(this)
|
PanelsChildGestureRegionObserver.Provider.get().removeGestureRegionsUpdateListener(this)
|
||||||
|
@ -741,128 +744,53 @@ class ResultFragment : ResultTrailerPlayer() {
|
||||||
result_overlapping_panels?.setStartPanelLockState(if (closed) OverlappingPanelsLayout.LockState.CLOSE else OverlappingPanelsLayout.LockState.UNLOCKED)
|
result_overlapping_panels?.setStartPanelLockState(if (closed) OverlappingPanelsLayout.LockState.CLOSE else OverlappingPanelsLayout.LockState.UNLOCKED)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
observe(viewModel.resumeWatching) { resume ->
|
||||||
observe(viewModel.episodes) { episodeList ->
|
when (resume) {
|
||||||
lateFixDownloadButton(episodeList.size <= 1) // movies can have multible parts but still be *movies* this will fix this
|
is Some.Success -> {
|
||||||
var isSeriesVisible = false
|
result_resume_parent?.isVisible = true
|
||||||
var isProgressVisible = false
|
val value = resume.value
|
||||||
DataStoreHelper.getLastWatched(currentId)?.let { resume ->
|
value.progress?.let { progress ->
|
||||||
if (currentIsMovie == false) {
|
//TODO FIX
|
||||||
isSeriesVisible = true
|
result_resume_series_title?.apply {
|
||||||
|
isVisible = !value.isMovie
|
||||||
|
text =
|
||||||
|
if (value.isMovie) null else activity?.getNameFull(
|
||||||
|
value.result.name,
|
||||||
|
value.result.episode,
|
||||||
|
value.result.season
|
||||||
|
)
|
||||||
|
}
|
||||||
|
result_resume_series_progress_text.setText(progress.progressLeft)
|
||||||
|
result_resume_series_progress?.apply {
|
||||||
|
isVisible = true
|
||||||
|
this.max = progress.maxProgress
|
||||||
|
this.progress = progress.progress
|
||||||
|
}
|
||||||
|
result_resume_progress_holder?.isVisible = true
|
||||||
|
} ?: run {
|
||||||
|
result_resume_progress_holder?.isVisible = false
|
||||||
|
result_resume_series_progress?.isVisible = false
|
||||||
|
result_resume_series_title?.isVisible = false
|
||||||
|
result_resume_series_progress_text?.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
result_resume_series_button?.isVisible = !value.isMovie
|
||||||
|
|
||||||
result_resume_series_button?.setOnClickListener {
|
result_resume_series_button?.setOnClickListener {
|
||||||
episodeList.firstOrNull { it.id == resume.episodeId }?.let {
|
viewModel.handleAction(
|
||||||
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, it))
|
activity,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result_resume_series_title?.text =
|
|
||||||
if (resume.season == null)
|
|
||||||
"${getString(R.string.episode)} ${resume.episode}"
|
|
||||||
else
|
|
||||||
" \"${getString(R.string.season_short)}${resume.season}:${getString(R.string.episode_short)}${resume.episode}\""
|
|
||||||
}
|
|
||||||
|
|
||||||
getViewPos(resume.episodeId)?.let { viewPos ->
|
|
||||||
if (viewPos.position > 30_000L || currentIsMovie == false) { // first 30s will not show for movies
|
|
||||||
result_resume_series_progress?.apply {
|
|
||||||
max = (viewPos.duration / 1000).toInt()
|
|
||||||
progress = (viewPos.position / 1000).toInt()
|
|
||||||
}
|
|
||||||
result_resume_series_progress_text?.text =
|
|
||||||
getString(R.string.resume_time_left).format((viewPos.duration - viewPos.position) / (60_000))
|
|
||||||
isProgressVisible = true
|
|
||||||
} else {
|
|
||||||
isProgressVisible = false
|
|
||||||
isSeriesVisible = false
|
|
||||||
}
|
|
||||||
} ?: run {
|
|
||||||
isProgressVisible = false
|
|
||||||
isSeriesVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result_series_parent?.isVisible = isSeriesVisible
|
|
||||||
if (isSeriesVisible && activity?.currentFocus?.id == R.id.result_back && context?.isTrueTvSettings() == true) {
|
|
||||||
result_resume_series_button?.requestFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSeriesVisible) {
|
|
||||||
val down = when {
|
|
||||||
result_season_button?.isVisible == true -> result_season_button
|
|
||||||
result_episode_select?.isVisible == true -> result_episode_select
|
|
||||||
result_dub_select?.isVisible == true -> result_dub_select
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
setFocusUpAndDown(result_resume_series_button, down)
|
|
||||||
setFocusUpAndDown(result_bookmark_button, result_resume_series_button)
|
|
||||||
}
|
|
||||||
|
|
||||||
result_resume_progress_holder?.isVisible = isProgressVisible
|
|
||||||
context?.getString(
|
|
||||||
when {
|
|
||||||
currentType?.isLiveStream() == true -> R.string.play_livestream_button
|
|
||||||
isProgressVisible -> R.string.resume
|
|
||||||
else -> R.string.play_movie_button
|
|
||||||
}
|
|
||||||
)?.let {
|
|
||||||
result_play_movie?.text = it
|
|
||||||
}
|
|
||||||
//println("startAction = $startAction")
|
|
||||||
|
|
||||||
when (startAction) {
|
|
||||||
START_ACTION_RESUME_LATEST -> {
|
|
||||||
for (ep in episodeList) {
|
|
||||||
//println("WATCH STATUS::: S${ep.season} E ${ep.episode} - ${ep.getWatchProgress()}")
|
|
||||||
if (ep.getWatchProgress() > 0.90f) { // watched too much
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, ep))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
START_ACTION_LOAD_EP -> {
|
|
||||||
if (episodeList.size == 1) {
|
|
||||||
handleAction(
|
|
||||||
EpisodeClickEvent(
|
EpisodeClickEvent(
|
||||||
ACTION_PLAY_EPISODE_IN_PLAYER,
|
ACTION_PLAY_EPISODE_IN_PLAYER, value.result
|
||||||
episodeList.first()
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
var found = false
|
|
||||||
for (ep in episodeList) {
|
|
||||||
if (ep.id == startValue) { // watched too much
|
|
||||||
//println("WATCH STATUS::: START_ACTION_LOAD_EP S${ep.season} E ${ep.episode} - ${ep.getWatchProgress()}")
|
|
||||||
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, ep))
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
for (ep in episodeList) {
|
|
||||||
if (ep.episode == resumeEpisode && ep.season == resumeSeason) {
|
|
||||||
//println("WATCH STATUS::: START_ACTION_LOAD_EP S${ep.season} E ${ep.episode} - ${ep.getWatchProgress()}")
|
|
||||||
handleAction(
|
|
||||||
EpisodeClickEvent(
|
|
||||||
ACTION_PLAY_EPISODE_IN_PLAYER,
|
|
||||||
ep
|
|
||||||
)
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else -> Unit
|
is Some.None -> {
|
||||||
|
result_resume_parent?.isVisible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
arguments?.remove("startValue")
|
|
||||||
arguments?.remove("startAction")
|
|
||||||
startAction = null
|
|
||||||
startValue = null
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
observe(viewModel.episodes) { episodes ->
|
observe(viewModel.episodes) { episodes ->
|
||||||
when (episodes) {
|
when (episodes) {
|
||||||
is ResourceSome.None -> {
|
is ResourceSome.None -> {
|
||||||
|
@ -886,7 +814,7 @@ class ResultFragment : ResultTrailerPlayer() {
|
||||||
|
|
||||||
// If the season button is visible the result season button will be next focus down
|
// If the season button is visible the result season button will be next focus down
|
||||||
if (result_season_button?.isVisible == true)
|
if (result_season_button?.isVisible == true)
|
||||||
if (result_series_parent?.isVisible == true)
|
if (result_resume_parent?.isVisible == true)
|
||||||
setFocusUpAndDown(result_resume_series_button, result_season_button)
|
setFocusUpAndDown(result_resume_series_button, result_season_button)
|
||||||
else
|
else
|
||||||
setFocusUpAndDown(result_bookmark_button, result_season_button)
|
setFocusUpAndDown(result_bookmark_button, result_season_button)
|
||||||
|
@ -897,7 +825,7 @@ class ResultFragment : ResultTrailerPlayer() {
|
||||||
|
|
||||||
if (result_dub_select?.isVisible == true)
|
if (result_dub_select?.isVisible == true)
|
||||||
if (result_season_button?.isVisible != true && result_episode_select?.isVisible != true) {
|
if (result_season_button?.isVisible != true && result_episode_select?.isVisible != true) {
|
||||||
if (result_series_parent?.isVisible == true)
|
if (result_resume_parent?.isVisible == true)
|
||||||
setFocusUpAndDown(result_resume_series_button, result_dub_select)
|
setFocusUpAndDown(result_resume_series_button, result_dub_select)
|
||||||
else
|
else
|
||||||
setFocusUpAndDown(result_bookmark_button, result_dub_select)
|
setFocusUpAndDown(result_bookmark_button, result_dub_select)
|
||||||
|
@ -973,7 +901,7 @@ class ResultFragment : ResultTrailerPlayer() {
|
||||||
// If Season button is invisible then the bookmark button next focus is episode select
|
// If Season button is invisible then the bookmark button next focus is episode select
|
||||||
if (result_episode_select?.isVisible == true)
|
if (result_episode_select?.isVisible == true)
|
||||||
if (result_season_button?.isVisible != true) {
|
if (result_season_button?.isVisible != true) {
|
||||||
if (result_series_parent?.isVisible == true)
|
if (result_resume_parent?.isVisible == true)
|
||||||
setFocusUpAndDown(result_resume_series_button, result_episode_select)
|
setFocusUpAndDown(result_resume_series_button, result_episode_select)
|
||||||
else
|
else
|
||||||
setFocusUpAndDown(result_bookmark_button, result_episode_select)
|
setFocusUpAndDown(result_bookmark_button, result_episode_select)
|
||||||
|
@ -1071,11 +999,60 @@ class ResultFragment : ResultTrailerPlayer() {
|
||||||
)
|
)
|
||||||
return@setOnLongClickListener true
|
return@setOnLongClickListener true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
val file =
|
||||||
|
ioWork {
|
||||||
|
context?.let {
|
||||||
|
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
||||||
|
it,
|
||||||
|
ep.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadButton?.dispose()
|
||||||
|
downloadButton = EasyDownloadButton()
|
||||||
|
downloadButton?.setUpMoreButton(
|
||||||
|
file?.fileLength,
|
||||||
|
file?.totalBytes,
|
||||||
|
result_movie_progress_downloaded,
|
||||||
|
result_movie_download_icon,
|
||||||
|
result_movie_download_text,
|
||||||
|
result_movie_download_text_precentage,
|
||||||
|
result_download_movie,
|
||||||
|
true,
|
||||||
|
VideoDownloadHelper.DownloadEpisodeCached(
|
||||||
|
ep.name,
|
||||||
|
ep.poster,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
ep.id,
|
||||||
|
ep.id,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
)
|
||||||
|
) { click ->
|
||||||
|
//when(click.action) {
|
||||||
|
// DOWNLOAD_ACTION_LONG_CLICK -> {
|
||||||
|
// viewModel.handleAction(
|
||||||
|
// activity,
|
||||||
|
// EpisodeClickEvent(ACTION_DOWNLOAD_MIRROR, ep)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
handleDownloadClick(activity, click)
|
||||||
|
// handleDownloadClick(activity,)
|
||||||
|
}
|
||||||
|
result_movie_progress_downloaded_holder?.isVisible = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
result_movie_progress_downloaded_holder?.isVisible = false
|
||||||
result_play_movie?.isVisible = false
|
result_play_movie?.isVisible = false
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import com.lagradost.cloudstream3.utils.CastHelper.startCast
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.setKey
|
import com.lagradost.cloudstream3.utils.DataStore.setKey
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState
|
||||||
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
|
import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
|
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
|
||||||
|
@ -222,6 +223,18 @@ data class LinkProgress(
|
||||||
val subsLoaded: Int,
|
val subsLoaded: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class ResumeProgress(
|
||||||
|
val progress: Int,
|
||||||
|
val maxProgress: Int,
|
||||||
|
val progressLeft: UiText,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ResumeWatchingStatus(
|
||||||
|
val progress: ResumeProgress?,
|
||||||
|
val isMovie: Boolean,
|
||||||
|
val result: ResultEpisode,
|
||||||
|
)
|
||||||
|
|
||||||
data class LinkLoadingResult(
|
data class LinkLoadingResult(
|
||||||
val links: List<ExtractorLink>,
|
val links: List<ExtractorLink>,
|
||||||
val subs: List<SubtitleData>,
|
val subs: List<SubtitleData>,
|
||||||
|
@ -352,6 +365,10 @@ class ResultViewModel2 : ViewModel() {
|
||||||
private val _loadedLinks: MutableLiveData<Some<LinkProgress>> = MutableLiveData(Some.None)
|
private val _loadedLinks: MutableLiveData<Some<LinkProgress>> = MutableLiveData(Some.None)
|
||||||
val loadedLinks: LiveData<Some<LinkProgress>> = _loadedLinks
|
val loadedLinks: LiveData<Some<LinkProgress>> = _loadedLinks
|
||||||
|
|
||||||
|
private val _resumeWatching: MutableLiveData<Some<ResumeWatchingStatus>> =
|
||||||
|
MutableLiveData(Some.None)
|
||||||
|
val resumeWatching: LiveData<Some<ResumeWatchingStatus>> = _resumeWatching
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "RVM2"
|
const val TAG = "RVM2"
|
||||||
private const val EPISODE_RANGE_SIZE = 50
|
private const val EPISODE_RANGE_SIZE = 50
|
||||||
|
@ -646,7 +663,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
|
|
||||||
if (currentLinks.isEmpty()) {
|
if (currentLinks.isEmpty()) {
|
||||||
Coroutines.main {
|
Coroutines.main {
|
||||||
CommonActivity.showToast(
|
showToast(
|
||||||
activity,
|
activity,
|
||||||
R.string.no_links_found_toast,
|
R.string.no_links_found_toast,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
|
@ -655,7 +672,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
return@ioSafe
|
return@ioSafe
|
||||||
} else {
|
} else {
|
||||||
Coroutines.main {
|
Coroutines.main {
|
||||||
CommonActivity.showToast(
|
showToast(
|
||||||
activity,
|
activity,
|
||||||
R.string.download_started,
|
R.string.download_started,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
|
@ -950,7 +967,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
act.startActivityForResult(vlcIntent, VLC_REQUEST_CODE)
|
act.startActivityForResult(vlcIntent, VLC_REQUEST_CODE)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
CommonActivity.showToast(act, e.toString(), Toast.LENGTH_LONG)
|
showToast(act, e.toString(), Toast.LENGTH_LONG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,7 +1060,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
response.type
|
response.type
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
CommonActivity.showToast(
|
showToast(
|
||||||
activity,
|
activity,
|
||||||
R.string.download_started,
|
R.string.download_started,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
|
@ -1051,7 +1068,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ACTION_SHOW_TOAST -> {
|
ACTION_SHOW_TOAST -> {
|
||||||
CommonActivity.showToast(activity, R.string.play_episode_toast, Toast.LENGTH_SHORT)
|
showToast(activity, R.string.play_episode_toast, Toast.LENGTH_SHORT)
|
||||||
}
|
}
|
||||||
ACTION_DOWNLOAD_EPISODE -> {
|
ACTION_DOWNLOAD_EPISODE -> {
|
||||||
val response = currentResponse ?: return
|
val response = currentResponse ?: return
|
||||||
|
@ -1087,7 +1104,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
listOf(result.links[index]),
|
listOf(result.links[index]),
|
||||||
result.subs,
|
result.subs,
|
||||||
)
|
)
|
||||||
CommonActivity.showToast(
|
showToast(
|
||||||
activity,
|
activity,
|
||||||
R.string.download_started,
|
R.string.download_started,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
|
@ -1139,7 +1156,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
val link = result.links[index]
|
val link = result.links[index]
|
||||||
val clip = ClipData.newPlainText(link.name, link.url)
|
val clip = ClipData.newPlainText(link.name, link.url)
|
||||||
serviceClipboard.setPrimaryClip(clip)
|
serviceClipboard.setPrimaryClip(clip)
|
||||||
CommonActivity.showToast(act, R.string.copy_link_toast, Toast.LENGTH_SHORT)
|
showToast(act, R.string.copy_link_toast, Toast.LENGTH_SHORT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ACTION_CHROME_CAST_EPISODE -> {
|
ACTION_CHROME_CAST_EPISODE -> {
|
||||||
|
@ -1304,7 +1321,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
|
|
||||||
private fun getMovie(): ResultEpisode? {
|
private fun getMovie(): ResultEpisode? {
|
||||||
return currentEpisodes.entries.firstOrNull()?.value?.firstOrNull()?.let { ep ->
|
return currentEpisodes.entries.firstOrNull()?.value?.firstOrNull()?.let { ep ->
|
||||||
val posDur = DataStoreHelper.getViewPos(ep.id)
|
val posDur = getViewPos(ep.id)
|
||||||
ep.copy(position = posDur?.position ?: 0, duration = posDur?.duration ?: 0)
|
ep.copy(position = posDur?.position ?: 0, duration = posDur?.duration ?: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1335,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
val start = minOf(list.size, startIndex)
|
val start = minOf(list.size, startIndex)
|
||||||
val end = minOf(list.size, start + length)
|
val end = minOf(list.size, start + length)
|
||||||
list.subList(start, end).map {
|
list.subList(start, end).map {
|
||||||
val posDur = DataStoreHelper.getViewPos(it.id)
|
val posDur = getViewPos(it.id)
|
||||||
it.copy(position = posDur?.position ?: 0, duration = posDur?.duration ?: 0)
|
it.copy(position = posDur?.position ?: 0, duration = posDur?.duration ?: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1369,6 +1386,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
)
|
)
|
||||||
_movie.postValue(ResourceSome.None)
|
_movie.postValue(ResourceSome.None)
|
||||||
}
|
}
|
||||||
|
postResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postEpisodeRange(indexer: EpisodeIndexer?, range: EpisodeRange?) {
|
private fun postEpisodeRange(indexer: EpisodeIndexer?, range: EpisodeRange?) {
|
||||||
|
@ -1667,8 +1685,38 @@ class ResultViewModel2 : ViewModel() {
|
||||||
} ?: ranger?.lastOrNull()
|
} ?: ranger?.lastOrNull()
|
||||||
|
|
||||||
postEpisodeRange(min, range)
|
postEpisodeRange(min, range)
|
||||||
|
postResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun postResume() {
|
||||||
|
_resumeWatching.postValue(some(resume()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resume(): ResumeWatchingStatus? {
|
||||||
|
val correctId = currentId ?: return null
|
||||||
|
val resume = DataStoreHelper.getLastWatched(correctId)
|
||||||
|
val resumeParentId = resume?.parentId
|
||||||
|
if (resumeParentId != correctId) return null // is null or smth went wrong with getLastWatched
|
||||||
|
val resumeId = resume.episodeId ?: return null// invalid episode id
|
||||||
|
val response = currentResponse ?: return null
|
||||||
|
// kinda ugly ik
|
||||||
|
val episode =
|
||||||
|
currentEpisodes.values.flatten().firstOrNull { it.id == resumeId } ?: return null
|
||||||
|
|
||||||
|
val isMovie = response.isMovie()
|
||||||
|
|
||||||
|
val progress = getViewPos(resume.episodeId)?.let { viewPos ->
|
||||||
|
ResumeProgress(
|
||||||
|
progress = (viewPos.position / 1000).toInt(),
|
||||||
|
maxProgress = (viewPos.duration / 1000).toInt(),
|
||||||
|
txt(R.string.resume_time_left, (viewPos.duration - viewPos.position) / (60_000))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResumeWatchingStatus(progress = progress, isMovie = isMovie, result = episode)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// this instantly updates the metadata on the page
|
// this instantly updates the metadata on the page
|
||||||
private fun postPage(loadResponse: LoadResponse, apiRepository: APIRepository) {
|
private fun postPage(loadResponse: LoadResponse, apiRepository: APIRepository) {
|
||||||
_recommendations.postValue(loadResponse.recommendations ?: emptyList())
|
_recommendations.postValue(loadResponse.recommendations ?: emptyList())
|
||||||
|
|
|
@ -154,10 +154,10 @@ fun TextView?.setTextHtml(text: UiText?) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TextView?.setTextHtml(text: Some<UiText>) {
|
fun TextView?.setTextHtml(text: Some<UiText>?) {
|
||||||
setTextHtml(if(text is Some.Success) text.value else null)
|
setTextHtml(if(text is Some.Success) text.value else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TextView?.setText(text: Some<UiText>) {
|
fun TextView?.setText(text: Some<UiText>?) {
|
||||||
setText(if(text is Some.Success) text.value else null)
|
setText(if(text is Some.Success) text.value else null)
|
||||||
}
|
}
|
|
@ -678,7 +678,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/result_series_parent"
|
android:id="@+id/result_resume_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
|
|
Loading…
Reference in a new issue