set keys things

This commit is contained in:
reduplicated 2022-10-29 03:50:59 +02:00
parent 572aa6de3e
commit 6a721941ac
8 changed files with 231 additions and 172 deletions

View file

@ -201,7 +201,7 @@ dependencies {
implementation 'me.xdrop:fuzzywuzzy:1.4.0' implementation 'me.xdrop:fuzzywuzzy:1.4.0'
// aria2c downloader // aria2c downloader
implementation 'com.github.LagradOst:Aria2cButton:v0.0.4' implementation 'com.github.LagradOst:Aria2cButton:v0.0.5'
} }
task androidSourcesJar(type: Jar) { task androidSourcesJar(type: Jar) {

View file

@ -25,8 +25,10 @@ import com.lagradost.cloudstream3.utils.UIHelper
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
import com.lagradost.cloudstream3.utils.UIHelper.toPx import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import com.lagradost.fetchbutton.aria2c.Aria2Settings import com.lagradost.fetchbutton.aria2c.Aria2Settings
import com.lagradost.fetchbutton.aria2c.Aria2Starter import com.lagradost.fetchbutton.aria2c.Aria2Starter
import com.lagradost.fetchbutton.aria2c.DownloadListener
import org.schabi.newpipe.extractor.NewPipe import org.schabi.newpipe.extractor.NewPipe
import java.util.* import java.util.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -119,6 +121,7 @@ object CommonActivity {
val localeCode = settingsManager.getString(getString(R.string.locale_key), null) val localeCode = settingsManager.getString(getString(R.string.locale_key), null)
setLocale(this, localeCode) setLocale(this, localeCode)
} }
const val KEY_DOWNLOAD_INFO_METADATA = "download_info_metadata"
fun init(act: Activity?) { fun init(act: Activity?) {
if (act == null) return if (act == null) return
@ -133,13 +136,31 @@ object CommonActivity {
act.updateTv() act.updateTv()
NewPipe.init(DownloaderTestImpl.getInstance()) NewPipe.init(DownloaderTestImpl.getInstance())
DownloadListener.mainListener = { metadata ->
//TODO FIX
DownloadListener.sessionGidToId[metadata.items.firstOrNull()?.gid]?.let { id ->
AcraApplication.setKey(KEY_DOWNLOAD_INFO_METADATA,id.toString(),metadata)
/*val mainpath = metadata.items[0].files[0].path
AcraApplication.setKey(
VideoDownloadManager.KEY_DOWNLOAD_INFO,
id.toString(),
VideoDownloadManager.DownloadedFileInfo(
metadata.totalLength,
relativePath ?: "",
,
basePath = basePath.second
)
)*/
}
}
thread { thread {
Aria2Starter.start( Aria2Starter.start(
act, act,
Aria2Settings( Aria2Settings(
"1337", //UUID.randomUUID().toString() "1337", //UUID.randomUUID().toString()
4337, 4337,
"/storage/emulated/0/Download",// act.filesDir.path, act.filesDir.path, //"/storage/emulated/0/Download",//
"${act.filesDir.path}/session" "${act.filesDir.path}/session"
) )
) )

View file

@ -3,19 +3,21 @@ package com.lagradost.cloudstream3.ui.download
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.widget.ContentLoadingProgressBar import androidx.core.widget.ContentLoadingProgressBar
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.result.DownloadHelper.play
import com.lagradost.cloudstream3.ui.result.ResultEpisode import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons
import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.fetchbutton.aria2c.DownloadStatusTell
import com.lagradost.fetchbutton.ui.PieFetchButton
import kotlinx.android.synthetic.main.download_child_episode.view.* import kotlinx.android.synthetic.main.download_child_episode.view.*
import java.util.*
const val DOWNLOAD_ACTION_PLAY_FILE = 0 const val DOWNLOAD_ACTION_PLAY_FILE = 0
const val DOWNLOAD_ACTION_DELETE_FILE = 1 const val DOWNLOAD_ACTION_DELETE_FILE = 1
@ -38,39 +40,11 @@ class DownloadChildAdapter(
private val clickCallback: (DownloadClickEvent) -> Unit, private val clickCallback: (DownloadClickEvent) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val mBoundViewHolders: HashSet<DownloadButtonViewHolder> = HashSet()
private fun getAllBoundViewHolders(): Set<DownloadButtonViewHolder?>? {
return Collections.unmodifiableSet(mBoundViewHolders)
}
fun killAdapter() {
getAllBoundViewHolders()?.forEach { view ->
view?.downloadButton?.dispose()
}
}
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
if (holder is DownloadButtonViewHolder) {
holder.downloadButton.dispose()
}
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
if (holder is DownloadButtonViewHolder) {
holder.downloadButton.dispose()
mBoundViewHolders.remove(holder)
}
}
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
if (holder is DownloadButtonViewHolder) {
holder.reattachDownloadButton()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return DownloadChildViewHolder( return DownloadChildViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.download_child_episode, parent, false), LayoutInflater.from(parent.context)
.inflate(R.layout.download_child_episode, parent, false),
clickCallback clickCallback
) )
} }
@ -79,7 +53,6 @@ class DownloadChildAdapter(
when (holder) { when (holder) {
is DownloadChildViewHolder -> { is DownloadChildViewHolder -> {
holder.bind(cardList[position]) holder.bind(cardList[position])
mBoundViewHolders.add(holder)
} }
} }
} }
@ -92,15 +65,13 @@ class DownloadChildAdapter(
constructor( constructor(
itemView: View, itemView: View,
private val clickCallback: (DownloadClickEvent) -> Unit, private val clickCallback: (DownloadClickEvent) -> Unit,
) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder { ) : RecyclerView.ViewHolder(itemView) {
override var downloadButton = EasyDownloadButton()
private val title: TextView = itemView.download_child_episode_text private val title: TextView = itemView.download_child_episode_text
private val extraInfo: TextView = itemView.download_child_episode_text_extra private val extraInfo: TextView = itemView.download_child_episode_text_extra
private val holder: CardView = itemView.download_child_episode_holder private val holder: CardView = itemView.download_child_episode_holder
private val progressBar: ContentLoadingProgressBar = itemView.download_child_episode_progress private val progressBar: ContentLoadingProgressBar =
private val progressBarDownload: ContentLoadingProgressBar = itemView.download_child_episode_progress_downloaded itemView.download_child_episode_progress
private val downloadImage: ImageView = itemView.download_child_episode_download private val downloadButton: PieFetchButton = itemView.download_child_episode_download
private var localCard: VisualDownloadChildCached? = null private var localCard: VisualDownloadChildCached? = null
@ -120,36 +91,91 @@ class DownloadChildAdapter(
title.text = title.context.getNameFull(d.name, d.episode, d.season) title.text = title.context.getNameFull(d.name, d.episode, d.season)
title.isSelected = true // is needed for text repeating title.isSelected = true // is needed for text repeating
//extraInfo.text = card.currentBytes
downloadButton.setUpButton( downloadButton.apply {
card.currentBytes, val play =
card.totalBytes, R.string.play_episode//if (card.episode <= 0) R.string.play_movie_button else R.string.play_episode
progressBarDownload,
downloadImage,
extraInfo,
card.data,
clickCallback
)
setPersistentId(card.data.id.toLong())
downloadButton.setOnClickListener {
val view = downloadButton
//if (view !is PieFetchButton) return@setOnClickListener
when (view.currentStatus) {
/*null, DownloadStatusTell.Removed -> {
view.setStatus(DownloadStatusTell.Waiting)
downloadClickCallback.invoke(
DownloadEpisodeClickEvent(
DOWNLOAD_ACTION_DOWNLOAD,
card
)
)
}*/
DownloadStatusTell.Paused -> {
view.popupMenuNoIcons(
listOf(
1 to R.string.resume,
2 to play,
3 to R.string.delete
)
) {
when (itemId) {
1 -> if (!view.resumeDownload()) {
/*downloadClickCallback.invoke(
DownloadEpisodeClickEvent(
DOWNLOAD_ACTION_DOWNLOAD,
card
)
)*/
}
2 -> play(card.data)
3 -> view.deleteAllFiles()
}
}
}
DownloadStatusTell.Complete -> {
view.popupMenuNoIcons(
listOf(
2 to play,
3 to R.string.delete
)
) {
when (itemId) {
2 -> play(card.data)
3 -> view.deleteAllFiles()
}
}
}
DownloadStatusTell.Active -> {
view.popupMenuNoIcons(
listOf(
4 to R.string.pause,
2 to play,
3 to R.string.delete
)
) {
when (itemId) {
4 -> view.pauseDownload()
2 -> play(card.data)
3 -> view.deleteAllFiles()
}
}
}
DownloadStatusTell.Error -> {
view.redownload()
}
DownloadStatusTell.Waiting -> {
}
else -> {}
}
}
}
holder.setOnClickListener { holder.setOnClickListener {
clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d)) clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d))
} }
} }
override fun reattachDownloadButton() {
downloadButton.dispose()
val card = localCard
if (card != null) {
downloadButton.setUpButton(
card.currentBytes,
card.totalBytes,
progressBarDownload,
downloadImage,
extraInfo,
card.data,
clickCallback
)
}
}
} }
} }

View file

@ -30,7 +30,6 @@ class DownloadChildFragment : Fragment() {
} }
override fun onDestroyView() { override fun onDestroyView() {
(download_child_list?.adapter as DownloadChildAdapter?)?.killAdapter()
downloadDeleteEventListener?.let { VideoDownloadManager.downloadDeleteEvent -= it } downloadDeleteEventListener?.let { VideoDownloadManager.downloadDeleteEvent -= it }
super.onDestroyView() super.onDestroyView()
} }

View file

@ -1,12 +1,15 @@
package com.lagradost.cloudstream3.ui.download package com.lagradost.cloudstream3.ui.download
import android.content.Context import android.content.Context
import android.net.Uri
import android.os.Environment import android.os.Environment
import android.os.StatFs import android.os.StatFs
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.CommonActivity
import com.lagradost.cloudstream3.isMovieType import com.lagradost.cloudstream3.isMovieType
import com.lagradost.cloudstream3.mvvm.launchSafe import com.lagradost.cloudstream3.mvvm.launchSafe
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
@ -53,12 +56,10 @@ class DownloadViewModel : ViewModel() {
// parentId : downloadsCount // parentId : downloadsCount
val totalDownloads = HashMap<Int, Int>() val totalDownloads = HashMap<Int, Int>()
// Gets all children downloads // Gets all children downloads
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
for (c in children) { for (c in children) {
val childFile = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, c.id) ?: continue val childFile = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, c.id) ?: continue
if (childFile.fileLength <= 1) continue if (childFile.fileLength <= 1) continue
val len = childFile.totalBytes val len = childFile.totalBytes
val flen = childFile.fileLength val flen = childFile.fileLength
@ -68,7 +69,7 @@ class DownloadViewModel : ViewModel() {
totalDownloads[c.parentId] = totalDownloads[c.parentId]?.plus(1) ?: 1 totalDownloads[c.parentId] = totalDownloads[c.parentId]?.plus(1) ?: 1
} }
} }
println("FIXED: $totalDownloads")
val cached = withContext(Dispatchers.IO) { // wont fetch useless keys val cached = withContext(Dispatchers.IO) { // wont fetch useless keys
totalDownloads.entries.filter { it.value > 0 }.mapNotNull { totalDownloads.entries.filter { it.value > 0 }.mapNotNull {
context.getKey<VideoDownloadHelper.DownloadHeaderCached>( context.getKey<VideoDownloadHelper.DownloadHeaderCached>(

View file

@ -8,14 +8,37 @@ import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_LONG_CLICK import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_LONG_CLICK
import com.lagradost.cloudstream3.ui.download.DownloadEpisodeClickEvent import com.lagradost.cloudstream3.ui.download.DownloadEpisodeClickEvent
import com.lagradost.cloudstream3.ui.download.VisualDownloadChildCached
import com.lagradost.cloudstream3.ui.player.DownloadFileGenerator import com.lagradost.cloudstream3.ui.player.DownloadFileGenerator
import com.lagradost.cloudstream3.utils.ExtractorUri import com.lagradost.cloudstream3.utils.ExtractorUri
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.fetchbutton.aria2c.Aria2Starter import com.lagradost.fetchbutton.aria2c.Aria2Starter
import com.lagradost.fetchbutton.aria2c.DownloadStatusTell import com.lagradost.fetchbutton.aria2c.DownloadStatusTell
import com.lagradost.fetchbutton.ui.PieFetchButton import com.lagradost.fetchbutton.ui.PieFetchButton
object DownloadHelper { object DownloadHelper {
fun PieFetchButton.play(card: VideoDownloadHelper.DownloadEpisodeCached) {
val files = this.getVideos()
DownloadFileGenerator(
files.map { path ->
ExtractorUri(
uri = Uri.parse(path),
id = card.id,
parentId = card.parentId,
name = context.getString(R.string.downloaded_file), //click.data.name ?: keyInfo.displayName
season = card.season,
episode = card.episode
//basePath = keyInfo.basePath,
//displayName = keyInfo.displayName,
//relativePath = keyInfo.relativePath,
)
}
)
}
fun PieFetchButton.play(card: ResultEpisode) { fun PieFetchButton.play(card: ResultEpisode) {
val files = this.getVideos() val files = this.getVideos()
DownloadFileGenerator( DownloadFileGenerator(

View file

@ -22,12 +22,10 @@ import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager import androidx.work.WorkManager
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.MainActivity
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.services.VideoDownloadService import com.lagradost.cloudstream3.services.VideoDownloadService
@ -36,6 +34,7 @@ import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.removeKey import com.lagradost.cloudstream3.utils.DataStore.removeKey
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.fetchbutton.aria2c.Metadata
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -1487,7 +1486,20 @@ object VideoDownloadManager {
fun getDownloadFileInfoAndUpdateSettings(context: Context, id: Int): DownloadedFileInfoResult? { fun getDownloadFileInfoAndUpdateSettings(context: Context, id: Int): DownloadedFileInfoResult? {
val res = getDownloadFileInfo(context, id) val res = getDownloadFileInfo(context, id)
if (res == null) context.removeKey(KEY_DOWNLOAD_INFO, id.toString()) if (res == null) {
AcraApplication.getKey<Metadata>(
CommonActivity.KEY_DOWNLOAD_INFO_METADATA,
id.toString()
)?.let { data ->
if (data.totalLength > 1000L)
return DownloadedFileInfoResult(
data.downloadedLength, data.totalLength,
Uri.EMPTY
)
}
context.removeKey(KEY_DOWNLOAD_INFO, id.toString())
}
return res return res
} }

View file

@ -1,118 +1,95 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:nextFocusRight="@id/download_child_episode_download" android:id="@+id/download_child_episode_holder"
android:nextFocusLeft="@id/nav_rail_view" android:layout_width="match_parent"
android:id="@+id/download_child_episode_holder" android:layout_height="50dp"
android:layout_width="match_parent" android:layout_marginBottom="5dp"
android:layout_height="50dp" android:foreground="@drawable/outline_drawable"
app:cardCornerRadius="@dimen/rounded_image_radius" android:nextFocusLeft="@id/nav_rail_view"
app:cardBackgroundColor="@color/transparent" android:nextFocusRight="@id/download_child_episode_download"
app:cardElevation="0dp" app:cardBackgroundColor="@color/transparent"
android:foreground="@drawable/outline_drawable" app:cardCornerRadius="@dimen/rounded_image_radius"
android:layout_marginBottom="5dp"> app:cardElevation="0dp">
<androidx.core.widget.ContentLoadingProgressBar <androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/download_child_episode_progress" android:id="@+id/download_child_episode_progress"
android:layout_marginBottom="-1.5dp" style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:progressTint="?attr/colorPrimary" android:layout_width="match_parent"
android:progressBackgroundTint="?attr/colorPrimary" android:layout_height="5dp"
style="@android:style/Widget.Material.ProgressBar.Horizontal" android:layout_gravity="bottom"
android:layout_width="match_parent" android:layout_marginBottom="-1.5dp"
tools:progress="50" android:progressBackgroundTint="?attr/colorPrimary"
android:layout_gravity="bottom" android:progressTint="?attr/colorPrimary"
android:layout_height="5dp" /> tools:progress="50" />
<GridLayout <GridLayout
android:foreground="?android:attr/selectableItemBackgroundBorderless" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="match_parent"> android:foreground="?android:attr/selectableItemBackgroundBorderless">
<ImageView <ImageView
android:id="@+id/download_child_episode_play" android:id="@+id/download_child_episode_play"
android:visibility="gone" android:layout_gravity="center_vertical"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:layout_gravity="center_vertical" android:contentDescription="@string/episode_play_img_des"
android:src="@drawable/ic_baseline_play_arrow_24" android:src="@drawable/ic_baseline_play_arrow_24"
android:contentDescription="@string/episode_play_img_des" /> android:visibility="gone" />
<LinearLayout <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="50dp"
android:orientation="vertical">
<TextView
android:id="@+id/download_child_episode_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:orientation="vertical" android:layout_marginStart="10dp"
android:layout_height="wrap_content" android:layout_marginEnd="10dp"
android:layout_marginEnd="50dp"
android:layout_width="match_parent"> android:ellipsize="marquee"
android:gravity="center_vertical"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="?attr/textColor"
tools:text="Episode 1 Episode 1 Episode 1 Episode 1 Episode 1 Episode 1 Episode 1" />
<TextView <TextView
android:id="@+id/download_child_episode_text" android:id="@+id/download_child_episode_text_extra"
android:layout_marginStart="10dp" android:layout_width="wrap_content"
android:layout_marginEnd="10dp" android:layout_height="match_parent"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:gravity="center_vertical" android:layout_marginStart="10dp"
tools:text="Episode 1 Episode 1 Episode 1 Episode 1 Episode 1 Episode 1 Episode 1" android:layout_marginEnd="10dp"
android:gravity="center_vertical"
android:scrollHorizontally="true" android:textColor="?attr/grayTextColor"
android:ellipsize="marquee" tools:text="128MB / 237MB" />
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:textColor="?attr/textColor"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/download_child_episode_text_extra"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
tools:text="128MB / 237MB"
android:textColor="?attr/grayTextColor"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout> </LinearLayout>
<FrameLayout
android:layout_marginStart="-50dp"
android:layout_gravity="end"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/download_child_episode_progress_downloaded"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:indeterminate="false"
android:progressDrawable="@drawable/circular_progress_bar_cs3"
android:background="@drawable/circle_shape_cs3"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:layout_margin="5dp"
android:layout_gravity="end|center_vertical"
android:progress="0"
android:visibility="visible" />
<ImageView
android:nextFocusRight="@id/download_child_episode_holder"
android:nextFocusLeft="@id/download_child_episode_holder"
android:id="@+id/download_child_episode_download"
android:visibility="visible"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="10dp"
android:layout_width="50dp"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_baseline_play_arrow_24"
app:tint="?attr/textColor"
android:contentDescription="@string/download" />
</FrameLayout>
</GridLayout> </GridLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end">
<com.lagradost.fetchbutton.ui.PieFetchButton
android:id="@+id/download_child_episode_download"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="?selectableItemBackgroundBorderless"
android:padding="10dp" />
</FrameLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>