download child

This commit is contained in:
LagradOst 2021-07-19 01:57:04 +02:00
parent ddd722f19e
commit 3bf76a9563
11 changed files with 292 additions and 9 deletions

View file

@ -0,0 +1,86 @@
package com.lagradost.cloudstream3.ui.download
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.widget.ContentLoadingProgressBar
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.utils.DataStoreHelper.fixVisual
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import kotlinx.android.synthetic.main.download_child_episode.view.*
data class VisualDownloadChildCached(
val currentBytes: Long,
val totalBytes: Long,
val data: VideoDownloadHelper.DownloadEpisodeCached,
)
data class DownloadClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadEpisodeCached)
class DownloadChildAdapter(
var cardList: List<VisualDownloadChildCached>,
private val clickCallback: (DownloadClickEvent) -> Unit,
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return DownloadChildViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.download_child_episode, parent, false),
clickCallback
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is DownloadChildViewHolder -> {
holder.bind(cardList[position])
}
}
}
override fun getItemCount(): Int {
return cardList.size
}
class DownloadChildViewHolder
constructor(
itemView: View,
private val clickCallback: (DownloadClickEvent) -> Unit,
) : RecyclerView.ViewHolder(itemView) {
private val title: TextView = itemView.download_child_episode_text
private val extraInfo: TextView = itemView.download_child_episode_text_extra
private val holder: CardView = itemView.download_child_episode_holder
private val progressBar: ContentLoadingProgressBar = itemView.download_child_episode_progress
@SuppressLint("SetTextI18n")
fun bind(card: VisualDownloadChildCached) {
val d = card.data
val posDur = itemView.context.getViewPos(d.id)
if (posDur != null) {
val visualPos = posDur.fixVisual()
progressBar.max = (visualPos.duration / 1000).toInt()
progressBar.progress = (visualPos.position / 1000).toInt()
progressBar.visibility = View.VISIBLE
} else {
progressBar.visibility = View.GONE
}
title.text = d.name ?: "Episode ${d.episode}" //TODO FIX
val totalMbString = "%.1f".format(card.totalBytes / 1000000f)
val currentMbString = "%.1f".format(card.currentBytes / 1000000f)
extraInfo.text =
"${currentMbString}MB / ${totalMbString}MB"
holder.setOnClickListener {
clickCallback.invoke(DownloadClickEvent(0, d))
}
}
}
}

View file

@ -0,0 +1,87 @@
package com.lagradost.cloudstream3.ui.download
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.getKeys
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import kotlinx.android.synthetic.main.fragment_child_downloads.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class DownloadChildFragment : Fragment() {
companion object {
fun newInstance(headerName: String, folder: String) =
DownloadChildFragment().apply {
arguments = Bundle().apply {
putString("folder", folder)
putString("name", headerName)
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_child_downloads, container, false)
}
private fun updateList(folder: String) = main {
val data = withContext(Dispatchers.IO) { context?.getKeys(folder) }
if (data == null) {
activity?.onBackPressed() // TODO FIX
return@main
}
val eps = withContext(Dispatchers.IO) {
data.mapNotNull { key ->
context?.getKey<VideoDownloadHelper.DownloadEpisodeCached>(key)
}.mapNotNull {
val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(requireContext(), it.id)
?: return@mapNotNull null
VisualDownloadChildCached(info.fileLength, info.totalBytes, it)
}
}
if (eps.isEmpty()) {
activity?.onBackPressed()
return@main
}
(download_child_list?.adapter as DownloadChildAdapter? ?: return@main).cardList = eps
download_child_list?.adapter?.notifyDataSetChanged()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val folder = arguments?.getString("folder")
val name = arguments?.getString("name")
if (folder == null) {
activity?.onBackPressed() // TODO FIX
return
}
context?.fixPaddingStatusbar(download_child_root)
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> =
DownloadChildAdapter(
ArrayList(),
) { click ->
if (click.action == 0) { // TODO PLAY
val info =
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(requireContext(), click.data.id)
?: return@DownloadChildAdapter
}
}
download_child_list.adapter = adapter
download_child_list.layoutManager = GridLayoutManager(context, 1)
updateList(folder)
}
}

View file

@ -12,7 +12,11 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.isMovieType
import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE
import com.lagradost.cloudstream3.utils.DataStore.getFolderName
import kotlinx.android.synthetic.main.fragment_downloads.* import kotlinx.android.synthetic.main.fragment_downloads.*
import kotlinx.android.synthetic.main.fragment_result.* import kotlinx.android.synthetic.main.fragment_result.*
@ -70,7 +74,16 @@ class DownloadFragment : Fragment() {
DownloadHeaderAdapter( DownloadHeaderAdapter(
ArrayList(), ArrayList(),
) { click -> ) { click ->
if(click.data.type.isMovieType()) {
//TODO MOVIE
}
else {
val folder = getFolderName(DOWNLOAD_EPISODE_CACHE, click.data.id.toString())
activity?.supportFragmentManager?.beginTransaction()
?.setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit)
?.add(R.id.homeRoot, DownloadChildFragment.newInstance(click.data.name, folder))
?.commit()
}
} }
download_list.adapter = adapter download_list.adapter = adapter
download_list.layoutManager = GridLayoutManager(context, 1) download_list.layoutManager = GridLayoutManager(context, 1)

View file

@ -23,7 +23,6 @@ data class VisualDownloadHeaderCached(
) )
data class DownloadHeaderClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadHeaderCached) data class DownloadHeaderClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadHeaderCached)
data class DownloadClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadEpisodeCached)
class DownloadHeaderAdapter( class DownloadHeaderAdapter(
var cardList: List<VisualDownloadHeaderCached>, var cardList: List<VisualDownloadHeaderCached>,

View file

@ -52,6 +52,7 @@ import com.lagradost.cloudstream3.ui.player.PlayerFragment
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.CastHelper.startCast import com.lagradost.cloudstream3.utils.CastHelper.startCast
import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getFolderName
import com.lagradost.cloudstream3.utils.DataStore.setKey import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
@ -396,7 +397,7 @@ class ResultFragment : Fragment() {
val epData = episodeClick.data val epData = episodeClick.data
ctx.setKey( ctx.setKey(
DOWNLOAD_EPISODE_CACHE, getFolderName(DOWNLOAD_EPISODE_CACHE, (currentId ?: return@let).toString()), // 3 deep folder for faster acess
epData.id.toString(), epData.id.toString(),
VideoDownloadHelper.DownloadEpisodeCached( VideoDownloadHelper.DownloadEpisodeCached(
epData.name, epData.name,

View file

@ -9,9 +9,18 @@ const val VIDEO_POS_DUR = "video_pos_dur"
const val RESULT_WATCH_STATE = "result_watch_state" const val RESULT_WATCH_STATE = "result_watch_state"
const val RESULT_SEASON = "result_season" const val RESULT_SEASON = "result_season"
data class PosDur(val position: Long, val duration: Long)
object DataStoreHelper { object DataStoreHelper {
data class PosDur(val position: Long, val duration: Long)
fun PosDur.fixVisual(): PosDur {
if (duration <= 0) return PosDur(0, duration)
val percentage = position * 100 / duration
if (percentage <= 1) return PosDur(0, duration)
if (percentage <= 5) return PosDur(5 * duration / 100, duration)
if (percentage >= 95) return PosDur(duration, duration)
return this
}
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
fun Context.setViewPos(id: Int?, pos: Long, dur: Long) { fun Context.setViewPos(id: Int?, pos: Long, dur: Long) {

View file

@ -22,9 +22,6 @@ import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
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.RESTART_NONE
import com.lagradost.cloudstream3.services.START_VALUE_KEY
import com.lagradost.cloudstream3.services.VideoDownloadKeepAliveService
import com.lagradost.cloudstream3.services.VideoDownloadService import com.lagradost.cloudstream3.services.VideoDownloadService
import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKey

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:cardCornerRadius="@dimen/roundedImageRadius"
app:cardBackgroundColor="@color/transparent"
app:cardElevation="0dp"
android:id="@+id/download_child_episode_holder"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:layout_marginBottom="5dp"
>
<androidx.core.widget.ContentLoadingProgressBar
android:layout_marginBottom="-1.5dp"
android:id="@+id/download_child_episode_progress"
android:progressTint="@color/colorPrimary"
android:progressBackgroundTint="@color/colorPrimary"
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent"
tools:progress="50"
android:layout_gravity="bottom"
android:layout_height="5dp">
</androidx.core.widget.ContentLoadingProgressBar>
<GridLayout android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="center_vertical"
android:id="@+id/download_child_episode_play"
android:src="@drawable/ic_baseline_play_arrow_24"
android:contentDescription="@string/episode_play_descript"/>
<LinearLayout
android:layout_gravity="center_vertical"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
<TextView
android:id="@+id/download_child_episode_text"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="center_vertical" android:gravity="center_vertical" tools:text="Episode 1"
android:textColor="@color/textColor" android:layout_width="wrap_content"
android:layout_height="match_parent">
</TextView>
<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="@color/grayTextColor"
android:layout_width="wrap_content"
android:layout_height="match_parent">
</TextView>
</LinearLayout>
<ImageView
android:visibility="gone"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_height="match_parent"
android:layout_width="30dp"
android:id="@+id/download_child_episode_download"
android:background="?selectableItemBackgroundBorderless"
android:layout_gravity="center_vertical|end"
android:src="@drawable/netflix_download"
android:contentDescription="@string/download_descript"/>
</GridLayout>
</androidx.cardview.widget.CardView>

View file

@ -17,7 +17,6 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<!--app:cardCornerRadius="@dimen/roundedImageRadius"--> <!--app:cardCornerRadius="@dimen/roundedImageRadius"-->
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="70dp" android:layout_width="70dp"
android:layout_height="104dp" android:layout_height="104dp"
> >

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:background="@color/bitDarkerGrayBackground"
android:id="@+id/download_child_root"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.download.DownloadFragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_margin="10dp"
tools:listitem="@layout/download_child_episode"
android:id="@+id/download_child_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

View file

@ -99,8 +99,8 @@
android:layout_margin="10dp" android:layout_margin="10dp"
android:id="@+id/download_list" android:id="@+id/download_list"
android:layout_width="match_parent" android:layout_width="match_parent"
tools:listitem="@layout/download_header_episode"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
<TextView <TextView
android:id="@+id/text_no_downloads" android:id="@+id/text_no_downloads"