Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@ import androidx.viewbinding.ViewBinding
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.DownloadChildEpisodeBinding
import com.lagradost.cloudstream3.databinding.DownloadHeaderEpisodeBinding
import com.lagradost.cloudstream3.databinding.DownloadChildEpisodeLargeBinding
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.secondsToReadable
import com.lagradost.cloudstream3.ui.NoStateAdapter
import com.lagradost.cloudstream3.ui.ViewHolderState
import com.lagradost.cloudstream3.ui.download.button.DownloadStatusTell
import com.lagradost.cloudstream3.utils.AppContextUtils.getNameFull
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.ImageLoader.loadImage
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.cloudstream3.utils.setText
import com.lagradost.cloudstream3.utils.txt
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale


const val DOWNLOAD_ACTION_PLAY_FILE = 0
const val DOWNLOAD_ACTION_DELETE_FILE = 1
Expand Down Expand Up @@ -76,6 +85,7 @@ class DownloadAdapter(
companion object {
private const val VIEW_TYPE_HEADER = 0
private const val VIEW_TYPE_CHILD = 1
private const val VIEW_TYPE_CHILD_LARGE = 2
}


Expand Down Expand Up @@ -366,11 +376,133 @@ class DownloadAdapter(
}
}

private fun bindChildLarge(
binding: DownloadChildEpisodeLargeBinding,
card: VisualDownloadCached.Child?
) {
if (card == null) return
val data = card.data

binding.apply {
episodePoster.loadImage(data.poster)
episodeText.text = root.context.getNameFull(data.name, data.episode, data.season)

val ratingText = data.score?.toString()

episodeRating.isVisible = !ratingText.isNullOrBlank()
episodeRating.text = ratingText?.let { "Rated: $it" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not translatable, i.e. you should use getString(R.string.rated_format, it) instead


episodeRuntime.isVisible = (data.runtime ?: 0) > 0
episodeRuntime.text = secondsToReadable(data.runtime ?: 0, "")

episodeDescript.isVisible = !data.description.isNullOrBlank()
episodeDescript.text = data.description.orEmpty()

episodeDate.isVisible = data.airDate != null

data.airDate?.let { airDate ->
val formattedAirDate = SimpleDateFormat.getDateInstance(
DateFormat.LONG,
Locale.getDefault()
).format(Date(airDate))
episodeDate.setText(txt(formattedAirDate))
}

episodeMetaRow?.isVisible = episodeDate.isVisible || episodeRating.isVisible || episodeRuntime.isVisible

val posDur = getViewPos(data.id)
episodeProgress.isVisible = posDur != null

posDur?.let {
val max = (it.duration / 1000).toInt()
val progress = (it.position / 1000).toInt()

if (max > 0 && progress >= (0.95 * max).toInt()) {
episodePlayIcon.setImageResource(R.drawable.ic_baseline_check_24)
episodeProgress.isVisible = false
} else {
episodePlayIcon.setImageResource(R.drawable.netflix_play)
episodeProgress.max = max
episodeProgress.progress = progress
episodeProgress.isVisible = true
}
}

// Download button
val status = downloadButton.getStatus(
data.id,
card.currentBytes,
card.totalBytes
)

if (status == DownloadStatusTell.IsDone) {
downloadButton.setProgress(card.currentBytes, card.totalBytes)
downloadButton.applyMetaData(data.id, card.currentBytes, card.totalBytes)
downloadButton.doSetProgress = false
} else {
downloadButton.resetView()
}

downloadButton.setDefaultClickListener(
data,
downloadSize,
onItemClickEvent
)

downloadButton.isVisible = !isMultiDeleteState

// Selection / multi-delete parity
downloadChildEpisodeLargeHolder.apply {
when {
isMultiDeleteState -> {
setOnClickListener {
deleteCheckbox?.let {
toggleIsChecked(it, data.id)
}
}
setOnLongClickListener {
deleteCheckbox?.let {
toggleIsChecked(it, data.id)
}
true
}
}
else -> {
setOnClickListener {
onItemClickEvent.invoke(
DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, data)
)
}
setOnLongClickListener {
onItemSelectionChanged.invoke(data.id, true)
true
}
}
}
}

if (isMultiDeleteState) {
deleteCheckbox?.setOnCheckedChangeListener { _, isChecked ->
onItemSelectionChanged.invoke(data.id, isChecked)
}
} else {
deleteCheckbox?.setOnCheckedChangeListener(null)
}

deleteCheckbox.apply {
this?.isVisible = isMultiDeleteState
this?.isChecked = card.isSelected
}
}
}


override fun onCreateCustomContent(parent: ViewGroup, viewType: Int): ViewHolderState<Any> {
val inflater = LayoutInflater.from(parent.context)
val binding = when (viewType) {
VIEW_TYPE_HEADER -> DownloadHeaderEpisodeBinding.inflate(inflater, parent, false)
VIEW_TYPE_CHILD -> DownloadChildEpisodeBinding.inflate(inflater, parent, false)
VIEW_TYPE_CHILD_LARGE -> DownloadChildEpisodeLargeBinding.inflate(inflater, parent, false)
else -> throw IllegalArgumentException("Invalid view type")
}
return ViewHolderState(binding)
Expand All @@ -382,25 +514,32 @@ class DownloadAdapter(
position: Int
) {
when (val binding = holder.view) {
is DownloadHeaderEpisodeBinding -> bindHeader(
binding,
item as? VisualDownloadCached.Header
)
is DownloadHeaderEpisodeBinding ->
bindHeader(binding, item as? VisualDownloadCached.Header)

is DownloadChildEpisodeBinding -> bindChild(
binding,
item as? VisualDownloadCached.Child
)
is DownloadChildEpisodeBinding ->
bindChild(binding, item as? VisualDownloadCached.Child)

is DownloadChildEpisodeLargeBinding ->
bindChildLarge(binding, item as? VisualDownloadCached.Child)
}
}

override fun customContentViewType(item: VisualDownloadCached): Int {
return when (item) {
is VisualDownloadCached.Child -> VIEW_TYPE_CHILD
is VisualDownloadCached.Header -> VIEW_TYPE_HEADER
is VisualDownloadCached.Child -> {
val poster = item.data.poster
if (poster.isNullOrBlank()) {
VIEW_TYPE_CHILD
} else {
VIEW_TYPE_CHILD_LARGE
}
}
}
}


@SuppressLint("NotifyDataSetChanged")
fun setIsMultiDeleteState(value: Boolean) {
if (isMultiDeleteState == value) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import coil3.dispose
import com.lagradost.api.Log
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.CommonActivity
import com.lagradost.cloudstream3.R
Expand Down Expand Up @@ -170,6 +171,8 @@ class EpisodeAdapter(
score = item.score,
description = item.description,
cacheTime = System.currentTimeMillis(),
runtime = item.runTime,
airDate = item.airDate
), null
) {
when (it.action) {
Expand Down Expand Up @@ -386,6 +389,8 @@ class EpisodeAdapter(
score = item.score,
description = item.description,
cacheTime = System.currentTimeMillis(),
runtime = item.runTime,
airDate = item.airDate
), null
) {
when (it.action) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,8 @@ open class ResultFragmentPhone : FullScreenPlayer() {
score = ep.score,
description = ep.description,
cacheTime = System.currentTimeMillis(),
runtime = ep.runTime,
airDate = ep.airDate
),
null
) { click ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,8 @@ class ResultViewModel2 : ViewModel() {
score = episode.score,
description = episode.description,
cacheTime = System.currentTimeMillis(),
runtime = episode.runTime,
airDate = episode.airDate
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ object VideoDownloadHelper {
@JsonProperty("score") var score: Score? = null,
@JsonProperty("description") val description: String?,
@JsonProperty("cacheTime") val cacheTime: Long,
@JsonProperty("airDate") val airDate: Long? = null,
@JsonProperty("runtime") val runtime: Int? = null,
override val id: Int,
): DownloadCached(id) {
@JsonProperty("rating", access = JsonProperty.Access.WRITE_ONLY)
Expand Down
Loading