From 3bf76a95638caa665026981f5c9a5c0703e69bbd Mon Sep 17 00:00:00 2001 From: LagradOst Date: Mon, 19 Jul 2021 01:57:04 +0200 Subject: [PATCH] download child --- .../ui/download/DownloadChildAdapter.kt | 86 ++++++++++++++++++ .../ui/download/DownloadChildFragment.kt | 87 +++++++++++++++++++ .../ui/download/DownloadFragment.kt | 15 +++- .../ui/download/DownloadHeaderAdapter.kt | 1 - .../cloudstream3/ui/result/ResultFragment.kt | 3 +- .../cloudstream3/utils/DataStoreHelper.kt | 11 ++- .../utils/VideoDownloadManager.kt | 3 - .../res/layout/download_child_episode.xml | 73 ++++++++++++++++ .../res/layout/download_header_episode.xml | 1 - .../res/layout/fragment_child_downloads.xml | 19 ++++ .../main/res/layout/fragment_downloads.xml | 2 +- 11 files changed, 292 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt create mode 100644 app/src/main/res/layout/download_child_episode.xml create mode 100644 app/src/main/res/layout/fragment_child_downloads.xml diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt new file mode 100644 index 00000000..a64c381a --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildAdapter.kt @@ -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, + private val clickCallback: (DownloadClickEvent) -> Unit, +) : + RecyclerView.Adapter() { + + 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)) + } + } + } +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt new file mode 100644 index 00000000..37b0ee82 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt @@ -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(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 = + 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt index 48f25df4..b70ab6b7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt @@ -12,7 +12,11 @@ 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.isMovieType 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_result.* @@ -70,7 +74,16 @@ class DownloadFragment : Fragment() { DownloadHeaderAdapter( ArrayList(), ) { 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.layoutManager = GridLayoutManager(context, 1) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt index 839fcba5..c1b4b831 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt @@ -23,7 +23,6 @@ data class VisualDownloadHeaderCached( ) data class DownloadHeaderClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadHeaderCached) -data class DownloadClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadEpisodeCached) class DownloadHeaderAdapter( var cardList: List, diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index b0551eb5..abe39111 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -52,6 +52,7 @@ import com.lagradost.cloudstream3.ui.player.PlayerFragment import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.CastHelper.startCast 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.DataStoreHelper.getViewPos @@ -396,7 +397,7 @@ class ResultFragment : Fragment() { val epData = episodeClick.data ctx.setKey( - DOWNLOAD_EPISODE_CACHE, + getFolderName(DOWNLOAD_EPISODE_CACHE, (currentId ?: return@let).toString()), // 3 deep folder for faster acess epData.id.toString(), VideoDownloadHelper.DownloadEpisodeCached( epData.name, diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt index f13d0806..8f297c08 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt @@ -9,9 +9,18 @@ const val VIDEO_POS_DUR = "video_pos_dur" const val RESULT_WATCH_STATE = "result_watch_state" const val RESULT_SEASON = "result_season" -data class PosDur(val position: Long, val duration: Long) 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 fun Context.setViewPos(id: Int?, pos: Long, dur: Long) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt index 03c92658..8af29a58 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt @@ -22,9 +22,6 @@ import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.mvvm.logError 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.utils.Coroutines.main import com.lagradost.cloudstream3.utils.DataStore.getKey diff --git a/app/src/main/res/layout/download_child_episode.xml b/app/src/main/res/layout/download_child_episode.xml new file mode 100644 index 00000000..05015ad3 --- /dev/null +++ b/app/src/main/res/layout/download_child_episode.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/download_header_episode.xml b/app/src/main/res/layout/download_header_episode.xml index 4f35d0c5..58287226 100644 --- a/app/src/main/res/layout/download_header_episode.xml +++ b/app/src/main/res/layout/download_header_episode.xml @@ -17,7 +17,6 @@ android:layout_height="wrap_content"> diff --git a/app/src/main/res/layout/fragment_child_downloads.xml b/app/src/main/res/layout/fragment_child_downloads.xml new file mode 100644 index 00000000..06fa0c43 --- /dev/null +++ b/app/src/main/res/layout/fragment_child_downloads.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_downloads.xml b/app/src/main/res/layout/fragment_downloads.xml index 89aeeb17..f1cefb49 100644 --- a/app/src/main/res/layout/fragment_downloads.xml +++ b/app/src/main/res/layout/fragment_downloads.xml @@ -99,8 +99,8 @@ android:layout_margin="10dp" android:id="@+id/download_list" android:layout_width="match_parent" + tools:listitem="@layout/download_header_episode" android:layout_height="wrap_content"> -