forked from recloudstream/cloudstream
		
	download stuff
This commit is contained in:
		
							parent
							
								
									472a9d678a
								
							
						
					
					
						commit
						3606d1ec05
					
				
					 8 changed files with 321 additions and 93 deletions
				
			
		|  | @ -0,0 +1,195 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.download | ||||||
|  | 
 | ||||||
|  | import android.animation.ObjectAnimator | ||||||
|  | import android.annotation.SuppressLint | ||||||
|  | import android.app.Activity | ||||||
|  | import android.view.View | ||||||
|  | import android.view.animation.DecelerateInterpolator | ||||||
|  | import android.widget.ImageView | ||||||
|  | import android.widget.TextView | ||||||
|  | import androidx.core.widget.ContentLoadingProgressBar | ||||||
|  | import androidx.fragment.app.FragmentActivity | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.UIHelper.popupMenuNoIcons | ||||||
|  | import com.lagradost.cloudstream3.ui.player.PlayerFragment | ||||||
|  | import com.lagradost.cloudstream3.ui.player.UriData | ||||||
|  | import com.lagradost.cloudstream3.utils.Coroutines | ||||||
|  | import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos | ||||||
|  | import com.lagradost.cloudstream3.utils.VideoDownloadHelper | ||||||
|  | import com.lagradost.cloudstream3.utils.VideoDownloadManager | ||||||
|  | 
 | ||||||
|  | object DownloadButtonSetup { | ||||||
|  |     fun handleDownloadClick(activity: Activity?, headerName: String?, click: DownloadClickEvent) { | ||||||
|  |         val id = click.data.id | ||||||
|  |         when (click.action) { | ||||||
|  |             DOWNLOAD_ACTION_DELETE_FILE -> { | ||||||
|  |                 activity?.let { ctx -> | ||||||
|  |                     VideoDownloadManager.deleteFileAndUpdateSettings(ctx, id) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             DOWNLOAD_ACTION_PAUSE_DOWNLOAD -> { | ||||||
|  |                 VideoDownloadManager.downloadEvent.invoke( | ||||||
|  |                     Pair(click.data.id, VideoDownloadManager.DownloadActionType.Pause) | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             DOWNLOAD_ACTION_RESUME_DOWNLOAD -> { | ||||||
|  |                 activity?.let { ctx -> | ||||||
|  |                     val pkg = VideoDownloadManager.getDownloadResumePackage(ctx, id) | ||||||
|  |                     if (pkg != null) { | ||||||
|  |                         VideoDownloadManager.downloadFromResume(ctx, pkg) | ||||||
|  |                     } else { | ||||||
|  |                         VideoDownloadManager.downloadEvent.invoke( | ||||||
|  |                             Pair(click.data.id, VideoDownloadManager.DownloadActionType.Resume) | ||||||
|  |                         ) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             DOWNLOAD_ACTION_PLAY_FILE -> { | ||||||
|  |                 activity?.let { act -> | ||||||
|  |                     val info = | ||||||
|  |                         VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(act, click.data.id) | ||||||
|  |                             ?: return | ||||||
|  | 
 | ||||||
|  |                     (act as FragmentActivity).supportFragmentManager.beginTransaction() | ||||||
|  |                         .setCustomAnimations( | ||||||
|  |                             R.anim.enter_anim, | ||||||
|  |                             R.anim.exit_anim, | ||||||
|  |                             R.anim.pop_enter, | ||||||
|  |                             R.anim.pop_exit | ||||||
|  |                         ) | ||||||
|  |                         .add( | ||||||
|  |                             R.id.homeRoot, | ||||||
|  |                             PlayerFragment.newInstance( | ||||||
|  |                                 UriData( | ||||||
|  |                                     info.path.toString(), | ||||||
|  |                                     click.data.id, | ||||||
|  |                                     headerName ?: "null", | ||||||
|  |                                     click.data.episode, | ||||||
|  |                                     click.data.season | ||||||
|  |                                 ), | ||||||
|  |                                 act.getViewPos(click.data.id)?.position ?: 0 | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                         .commit() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun setUpButton( | ||||||
|  |         setupCurrentBytes: Long?, | ||||||
|  |         setupTotalBytes: Long?, | ||||||
|  |         progressBar: ContentLoadingProgressBar, | ||||||
|  |         downloadImage: ImageView, | ||||||
|  |         textView: TextView?, | ||||||
|  |         data: VideoDownloadHelper.DownloadEpisodeCached, | ||||||
|  |         clickCallback: (DownloadClickEvent) -> Unit, | ||||||
|  |     ) { | ||||||
|  |         var lastState: VideoDownloadManager.DownloadType? = null | ||||||
|  |         var currentBytes = setupCurrentBytes ?: 0 | ||||||
|  |         var totalBytes = setupTotalBytes ?: 0 | ||||||
|  |         var needImageUpdate = false | ||||||
|  | 
 | ||||||
|  |         fun changeDownloadImage(state: VideoDownloadManager.DownloadType) { | ||||||
|  |             Coroutines.runOnMainThread { | ||||||
|  |                 lastState = state | ||||||
|  |                 if (currentBytes <= 0) needImageUpdate = true | ||||||
|  |                 val img = if (currentBytes > 0) when (state) { | ||||||
|  |                     VideoDownloadManager.DownloadType.IsPaused -> R.drawable.ic_baseline_play_arrow_24 | ||||||
|  |                     VideoDownloadManager.DownloadType.IsDownloading -> R.drawable.netflix_pause | ||||||
|  |                     else -> R.drawable.ic_baseline_delete_outline_24 | ||||||
|  |                 } else R.drawable.netflix_download | ||||||
|  |                 downloadImage?.setImageResource(img) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @SuppressLint("SetTextI18n") | ||||||
|  |         fun fixDownloadedBytes(setCurrentBytes: Long, setTotalBytes: Long, animate: Boolean) { | ||||||
|  |             Coroutines.runOnMainThread { | ||||||
|  |                 currentBytes = setCurrentBytes | ||||||
|  |                 totalBytes = setTotalBytes | ||||||
|  | 
 | ||||||
|  |                 if (currentBytes == 0L) { | ||||||
|  |                     changeDownloadImage(VideoDownloadManager.DownloadType.IsStopped) | ||||||
|  |                     textView?.visibility = View.GONE | ||||||
|  |                     progressBar?.visibility = View.GONE | ||||||
|  |                 } else { | ||||||
|  |                     if (lastState == VideoDownloadManager.DownloadType.IsStopped) { | ||||||
|  |                         changeDownloadImage(VideoDownloadManager.getDownloadState(data.id)) | ||||||
|  |                     } | ||||||
|  |                     textView?.visibility = View.VISIBLE | ||||||
|  |                     progressBar?.visibility = View.VISIBLE | ||||||
|  |                     val currentMbString = "%.1f".format(setCurrentBytes / 1000000f) | ||||||
|  |                     val totalMbString = "%.1f".format(setTotalBytes / 1000000f) | ||||||
|  | 
 | ||||||
|  |                     textView?.text = | ||||||
|  |                         "${currentMbString}MB / ${totalMbString}MB" | ||||||
|  | 
 | ||||||
|  |                     progressBar?.let { bar -> | ||||||
|  |                         bar.max = (setTotalBytes / 1000).toInt() | ||||||
|  | 
 | ||||||
|  |                         if (animate) { | ||||||
|  |                             val animation: ObjectAnimator = ObjectAnimator.ofInt( | ||||||
|  |                                 bar, | ||||||
|  |                                 "progress", | ||||||
|  |                                 bar.progress, | ||||||
|  |                                 (setCurrentBytes / 1000).toInt() | ||||||
|  |                             ) | ||||||
|  |                             animation.duration = 500 | ||||||
|  |                             animation.setAutoCancel(true) | ||||||
|  |                             animation.interpolator = DecelerateInterpolator() | ||||||
|  |                             animation.start() | ||||||
|  |                         } else { | ||||||
|  |                             bar.progress = (setCurrentBytes / 1000).toInt() | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fixDownloadedBytes(currentBytes, totalBytes, false) | ||||||
|  |         changeDownloadImage(VideoDownloadManager.getDownloadState(data.id)) | ||||||
|  | 
 | ||||||
|  |         VideoDownloadManager.downloadProgressEvent += { downloadData -> | ||||||
|  |             if (data.id == downloadData.first) { | ||||||
|  |                 if (downloadData.second != currentBytes || downloadData.third != totalBytes) { // TO PREVENT WASTING UI TIME | ||||||
|  |                     fixDownloadedBytes(downloadData.second, downloadData.third, true) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         VideoDownloadManager.downloadStatusEvent += { downloadData -> | ||||||
|  |             if (data.id == downloadData.first) { | ||||||
|  |                 if (lastState != downloadData.second || needImageUpdate) { // TO PREVENT WASTING UI TIME | ||||||
|  |                     changeDownloadImage(downloadData.second) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         downloadImage.setOnClickListener { | ||||||
|  |             if (currentBytes <= 0) { | ||||||
|  |                 clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_DOWNLOAD, data)) | ||||||
|  |             } else { | ||||||
|  |                 val list = arrayListOf( | ||||||
|  |                     Pair(DOWNLOAD_ACTION_DELETE_FILE, R.string.popup_delete_file), | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |                 // DON'T RESUME A DOWNLOADED FILE | ||||||
|  |                 if (lastState != VideoDownloadManager.DownloadType.IsDone && ((currentBytes * 100 / totalBytes) < 98)) { | ||||||
|  |                     list.add( | ||||||
|  |                         if (lastState == VideoDownloadManager.DownloadType.IsDownloading) | ||||||
|  |                             Pair(DOWNLOAD_ACTION_PAUSE_DOWNLOAD, R.string.popup_pause_download) | ||||||
|  |                         else | ||||||
|  |                             Pair(DOWNLOAD_ACTION_RESUME_DOWNLOAD, R.string.popup_resume_download) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 it.popupMenuNoIcons( | ||||||
|  |                     list | ||||||
|  |                 ) { | ||||||
|  |                     clickCallback.invoke(DownloadClickEvent(itemId, data)) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -28,6 +28,7 @@ const val DOWNLOAD_ACTION_PLAY_FILE = 0 | ||||||
| const val DOWNLOAD_ACTION_DELETE_FILE = 1 | const val DOWNLOAD_ACTION_DELETE_FILE = 1 | ||||||
| const val DOWNLOAD_ACTION_RESUME_DOWNLOAD = 2 | const val DOWNLOAD_ACTION_RESUME_DOWNLOAD = 2 | ||||||
| const val DOWNLOAD_ACTION_PAUSE_DOWNLOAD = 3 | const val DOWNLOAD_ACTION_PAUSE_DOWNLOAD = 3 | ||||||
|  | const val DOWNLOAD_ACTION_DOWNLOAD = 4 | ||||||
| 
 | 
 | ||||||
| data class VisualDownloadChildCached( | data class VisualDownloadChildCached( | ||||||
|     val currentBytes: Long, |     val currentBytes: Long, | ||||||
|  | @ -89,6 +90,16 @@ class DownloadChildAdapter( | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             title.text = d.name ?: "Episode ${d.episode}" //TODO FIX |             title.text = d.name ?: "Episode ${d.episode}" //TODO FIX | ||||||
|  |             DownloadButtonSetup.setUpButton( | ||||||
|  |                 card.currentBytes, | ||||||
|  |                 card.totalBytes, | ||||||
|  |                 progressBarDownload, | ||||||
|  |                 downloadImage, | ||||||
|  |                 extraInfo, | ||||||
|  |                 card.data, | ||||||
|  |                 clickCallback | ||||||
|  |             ) | ||||||
|  |             /* | ||||||
|             val totalMbString = "%.1f".format(card.totalBytes / 1000000f) |             val totalMbString = "%.1f".format(card.totalBytes / 1000000f) | ||||||
| 
 | 
 | ||||||
|             var lastState: VideoDownloadManager.DownloadType? = null |             var lastState: VideoDownloadManager.DownloadType? = null | ||||||
|  | @ -175,7 +186,7 @@ class DownloadChildAdapter( | ||||||
|                 ) { |                 ) { | ||||||
|                     clickCallback.invoke(DownloadClickEvent(itemId, d)) |                     clickCallback.invoke(DownloadClickEvent(itemId, d)) | ||||||
|                 } |                 } | ||||||
|             } |             }*/ | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ 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.ui.download.DownloadButtonSetup.handleDownloadClick | ||||||
| import com.lagradost.cloudstream3.ui.player.PlayerFragment | import com.lagradost.cloudstream3.ui.player.PlayerFragment | ||||||
| import com.lagradost.cloudstream3.ui.player.UriData | import com.lagradost.cloudstream3.ui.player.UriData | ||||||
| import com.lagradost.cloudstream3.utils.Coroutines.main | import com.lagradost.cloudstream3.utils.Coroutines.main | ||||||
|  | @ -35,63 +36,6 @@ class DownloadChildFragment : Fragment() { | ||||||
|                     putString("name", headerName) |                     putString("name", headerName) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|         fun handleDownloadClick(activity: Activity?, headerName: String?, click: DownloadClickEvent) { |  | ||||||
|             val id = click.data.id |  | ||||||
|             when (click.action) { |  | ||||||
|                 DOWNLOAD_ACTION_DELETE_FILE -> { |  | ||||||
|                     activity?.let { ctx -> |  | ||||||
|                         VideoDownloadManager.deleteFileAndUpdateSettings(ctx, id) |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 DOWNLOAD_ACTION_PAUSE_DOWNLOAD -> { |  | ||||||
|                     VideoDownloadManager.downloadEvent.invoke( |  | ||||||
|                         Pair(click.data.id, VideoDownloadManager.DownloadActionType.Pause) |  | ||||||
|                     ) |  | ||||||
|                 } |  | ||||||
|                 DOWNLOAD_ACTION_RESUME_DOWNLOAD -> { |  | ||||||
|                     activity?.let { ctx -> |  | ||||||
|                         val pkg = VideoDownloadManager.getDownloadResumePackage(ctx, id) |  | ||||||
|                         if (pkg != null) { |  | ||||||
|                             VideoDownloadManager.downloadFromResume(ctx, pkg) |  | ||||||
|                         } else { |  | ||||||
|                             VideoDownloadManager.downloadEvent.invoke( |  | ||||||
|                                 Pair(click.data.id, VideoDownloadManager.DownloadActionType.Resume) |  | ||||||
|                             ) |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 DOWNLOAD_ACTION_PLAY_FILE -> { |  | ||||||
|                     activity?.let { act -> |  | ||||||
|                         val info = |  | ||||||
|                             VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(act, click.data.id) |  | ||||||
|                                 ?: return |  | ||||||
| 
 |  | ||||||
|                         (act as FragmentActivity).supportFragmentManager.beginTransaction() |  | ||||||
|                             .setCustomAnimations( |  | ||||||
|                                 R.anim.enter_anim, |  | ||||||
|                                 R.anim.exit_anim, |  | ||||||
|                                 R.anim.pop_enter, |  | ||||||
|                                 R.anim.pop_exit |  | ||||||
|                             ) |  | ||||||
|                             .add( |  | ||||||
|                                 R.id.homeRoot, |  | ||||||
|                                 PlayerFragment.newInstance( |  | ||||||
|                                     UriData( |  | ||||||
|                                         info.path.toString(), |  | ||||||
|                                         click.data.id, |  | ||||||
|                                         headerName ?: "null", |  | ||||||
|                                         click.data.episode, |  | ||||||
|                                         click.data.season |  | ||||||
|                                     ), |  | ||||||
|                                     act.getViewPos(click.data.id)?.position ?: 0 |  | ||||||
|                                 ) |  | ||||||
|                             ) |  | ||||||
|                             .commit() |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { |     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | ||||||
|  |  | ||||||
|  | @ -12,6 +12,11 @@ import androidx.recyclerview.widget.RecyclerView | ||||||
| import com.bumptech.glide.Glide | import com.bumptech.glide.Glide | ||||||
| import com.bumptech.glide.load.model.GlideUrl | import com.bumptech.glide.load.model.GlideUrl | ||||||
| import com.lagradost.cloudstream3.R | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD | ||||||
|  | import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup | ||||||
|  | import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick | ||||||
|  | import com.lagradost.cloudstream3.ui.download.DownloadClickEvent | ||||||
|  | import com.lagradost.cloudstream3.utils.VideoDownloadHelper | ||||||
| import kotlinx.android.synthetic.main.result_episode.view.episode_holder | import kotlinx.android.synthetic.main.result_episode.view.episode_holder | ||||||
| import kotlinx.android.synthetic.main.result_episode.view.episode_text | import kotlinx.android.synthetic.main.result_episode.view.episode_text | ||||||
| import kotlinx.android.synthetic.main.result_episode_large.view.* | import kotlinx.android.synthetic.main.result_episode_large.view.* | ||||||
|  | @ -37,8 +42,9 @@ data class EpisodeClickEvent(val action: Int, val data: ResultEpisode) | ||||||
| 
 | 
 | ||||||
| class EpisodeAdapter( | class EpisodeAdapter( | ||||||
|     var cardList: List<ResultEpisode>, |     var cardList: List<ResultEpisode>, | ||||||
|     val hasDownloadSupport : Boolean, |     private val hasDownloadSupport: Boolean, | ||||||
|     private val clickCallback: (EpisodeClickEvent) -> Unit, |     private val clickCallback: (EpisodeClickEvent) -> Unit, | ||||||
|  |     private val downloadClickCallback: (DownloadClickEvent) -> Unit, | ||||||
| ) : | ) : | ||||||
|     RecyclerView.Adapter<RecyclerView.ViewHolder>() { |     RecyclerView.Adapter<RecyclerView.ViewHolder>() { | ||||||
|     @LayoutRes |     @LayoutRes | ||||||
|  | @ -57,7 +63,8 @@ class EpisodeAdapter( | ||||||
|         return CardViewHolder( |         return CardViewHolder( | ||||||
|             LayoutInflater.from(parent.context).inflate(layout, parent, false), |             LayoutInflater.from(parent.context).inflate(layout, parent, false), | ||||||
|             hasDownloadSupport, |             hasDownloadSupport, | ||||||
|             clickCallback |             clickCallback, | ||||||
|  |             downloadClickCallback | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -76,15 +83,18 @@ class EpisodeAdapter( | ||||||
|     class CardViewHolder |     class CardViewHolder | ||||||
|     constructor( |     constructor( | ||||||
|         itemView: View, |         itemView: View, | ||||||
|         private val hasDownloadSupport : Boolean, |         private val hasDownloadSupport: Boolean, | ||||||
|         private val clickCallback: (EpisodeClickEvent) -> Unit, |         private val clickCallback: (EpisodeClickEvent) -> Unit, | ||||||
|  |         private val downloadClickCallback: (DownloadClickEvent) -> Unit, | ||||||
|     ) : RecyclerView.ViewHolder(itemView) { |     ) : RecyclerView.ViewHolder(itemView) { | ||||||
|         private val episodeText: TextView = itemView.episode_text |         private val episodeText: TextView = itemView.episode_text | ||||||
|         private val episodeRating: TextView? = itemView.episode_rating |         private val episodeRating: TextView? = itemView.episode_rating | ||||||
|         private val episodeDescript: TextView? = itemView.episode_descript |         private val episodeDescript: TextView? = itemView.episode_descript | ||||||
|         private val episodeProgress: ContentLoadingProgressBar? = itemView.episode_progress |         private val episodeProgress: ContentLoadingProgressBar? = itemView.episode_progress | ||||||
|         private val episodePoster: ImageView? = itemView.episode_poster |         private val episodePoster: ImageView? = itemView.episode_poster | ||||||
|         private val episodeDownload: ImageView? = itemView.episode_download | 
 | ||||||
|  |         private val episodeDownloadBar: ContentLoadingProgressBar = itemView.result_episode_progress_downloaded | ||||||
|  |         private val episodeDownloadImage: ImageView = itemView.result_episode_download | ||||||
| 
 | 
 | ||||||
|         private val episodeHolder = itemView.episode_holder |         private val episodeHolder = itemView.episode_holder | ||||||
| 
 | 
 | ||||||
|  | @ -134,11 +144,23 @@ class EpisodeAdapter( | ||||||
|                 return@setOnLongClickListener true |                 return@setOnLongClickListener true | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             episodeDownload?.visibility = if(hasDownloadSupport) View.VISIBLE else View.GONE |             if(hasDownloadSupport) { | ||||||
| 
 |                 DownloadButtonSetup.setUpButton( | ||||||
|             episodeDownload?.setOnClickListener { |                     null, null, episodeDownloadBar, episodeDownloadImage, null, | ||||||
|  |                     VideoDownloadHelper.DownloadEpisodeCached( | ||||||
|  |                         card.name, card.poster, card.episode, card.season, card.id, 0, card.rating, card.descript | ||||||
|  |                     ) | ||||||
|  |                 ) { | ||||||
|  |                     if(it.action == DOWNLOAD_ACTION_DOWNLOAD) { | ||||||
|                         clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card)) |                         clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card)) | ||||||
|  |                     } else { | ||||||
|  |                         downloadClickCallback.invoke(it) | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             episodeDownloadImage.visibility = if (hasDownloadSupport) View.VISIBLE else View.GONE | ||||||
|  |             episodeDownloadBar.visibility = if (hasDownloadSupport) View.VISIBLE else View.GONE | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -47,6 +47,8 @@ import com.lagradost.cloudstream3.UIHelper.requestRW | ||||||
| import com.lagradost.cloudstream3.mvvm.Resource | import com.lagradost.cloudstream3.mvvm.Resource | ||||||
| import com.lagradost.cloudstream3.mvvm.observe | import com.lagradost.cloudstream3.mvvm.observe | ||||||
| import com.lagradost.cloudstream3.ui.WatchType | import com.lagradost.cloudstream3.ui.WatchType | ||||||
|  | import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD | ||||||
|  | import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick | ||||||
| import com.lagradost.cloudstream3.ui.player.PlayerData | import com.lagradost.cloudstream3.ui.player.PlayerData | ||||||
| import com.lagradost.cloudstream3.ui.player.PlayerFragment | import com.lagradost.cloudstream3.ui.player.PlayerFragment | ||||||
| import com.lagradost.cloudstream3.utils.* | import com.lagradost.cloudstream3.utils.* | ||||||
|  | @ -625,9 +627,13 @@ class ResultFragment : Fragment() { | ||||||
|             EpisodeAdapter( |             EpisodeAdapter( | ||||||
|                 ArrayList(), |                 ArrayList(), | ||||||
|                 api.hasDownloadSupport, |                 api.hasDownloadSupport, | ||||||
|             ) { episodeClick -> |                 { episodeClick -> | ||||||
|                     handleAction(episodeClick) |                     handleAction(episodeClick) | ||||||
|  |                 }, | ||||||
|  |                 { downloadClickEvent -> | ||||||
|  |                     handleDownloadClick(activity, currentHeaderName, downloadClickEvent) | ||||||
|                 } |                 } | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         result_episodes.adapter = adapter |         result_episodes.adapter = adapter | ||||||
|         result_episodes.layoutManager = GridLayoutManager(context, 1) |         result_episodes.layoutManager = GridLayoutManager(context, 1) | ||||||
|  |  | ||||||
|  | @ -144,7 +144,7 @@ object VideoDownloadManager { | ||||||
|     val downloadStatus = HashMap<Int, DownloadType>() |     val downloadStatus = HashMap<Int, DownloadType>() | ||||||
|     val downloadStatusEvent = Event<Pair<Int, DownloadType>>() |     val downloadStatusEvent = Event<Pair<Int, DownloadType>>() | ||||||
|     val downloadEvent = Event<Pair<Int, DownloadActionType>>() |     val downloadEvent = Event<Pair<Int, DownloadActionType>>() | ||||||
|     val downloadProgressEvent = Event<Pair<Int, Long>>() |     val downloadProgressEvent = Event<Triple<Int, Long, Long>>() | ||||||
|     val downloadQueue = LinkedList<DownloadResumePackage>() |     val downloadQueue = LinkedList<DownloadResumePackage>() | ||||||
| 
 | 
 | ||||||
|     private var hasCreatedNotChanel = false |     private var hasCreatedNotChanel = false | ||||||
|  | @ -542,7 +542,7 @@ object VideoDownloadManager { | ||||||
|             try { |             try { | ||||||
|                 downloadStatus[ep.id] = type |                 downloadStatus[ep.id] = type | ||||||
|                 downloadStatusEvent.invoke(Pair(ep.id, type)) |                 downloadStatusEvent.invoke(Pair(ep.id, type)) | ||||||
|                 downloadProgressEvent.invoke(Pair(ep.id, bytesDownloaded)) |                 downloadProgressEvent.invoke(Triple(ep.id, bytesDownloaded, bytesTotal)) | ||||||
|             } catch (e: Exception) { |             } catch (e: Exception) { | ||||||
|                 // IDK MIGHT ERROR |                 // IDK MIGHT ERROR | ||||||
|             } |             } | ||||||
|  | @ -626,13 +626,15 @@ object VideoDownloadManager { | ||||||
|         // RETURN MESSAGE |         // RETURN MESSAGE | ||||||
|         return when { |         return when { | ||||||
|             isFailed -> { |             isFailed -> { | ||||||
|  |                 downloadProgressEvent.invoke(Triple(id, 0, 0)) | ||||||
|                 ERROR_CONNECTION_ERROR |                 ERROR_CONNECTION_ERROR | ||||||
|             } |             } | ||||||
|             isStopped -> { |             isStopped -> { | ||||||
|  |                 downloadProgressEvent.invoke(Triple(id, 0, 0)) | ||||||
|                 deleteFile() |                 deleteFile() | ||||||
|             } |             } | ||||||
|             else -> { |             else -> { | ||||||
|                 downloadProgressEvent.invoke(Pair(id, bytesDownloaded)) |                 downloadProgressEvent.invoke(Triple(id, bytesDownloaded, bytesTotal)) | ||||||
|                 isDone = true |                 isDone = true | ||||||
|                 updateNotification() |                 updateNotification() | ||||||
|                 SUCCESS_DOWNLOAD_DONE |                 SUCCESS_DOWNLOAD_DONE | ||||||
|  | @ -715,6 +717,8 @@ object VideoDownloadManager { | ||||||
| 
 | 
 | ||||||
|     private fun deleteFile(context: Context, id: Int): Boolean { |     private fun deleteFile(context: Context, id: Int): Boolean { | ||||||
|         downloadEvent.invoke(Pair(id, DownloadActionType.Stop)) |         downloadEvent.invoke(Pair(id, DownloadActionType.Stop)) | ||||||
|  |         downloadProgressEvent.invoke(Triple(id, 0, 0)) | ||||||
|  |         downloadStatusEvent.invoke(Pair(id, DownloadType.IsStopped)) | ||||||
|         val info = context.getKey<DownloadedFileInfo>(KEY_DOWNLOAD_INFO, id.toString()) ?: return false |         val info = context.getKey<DownloadedFileInfo>(KEY_DOWNLOAD_INFO, id.toString()) ?: return false | ||||||
| 
 | 
 | ||||||
|         if (isScopedStorage()) { |         if (isScopedStorage()) { | ||||||
|  |  | ||||||
|  | @ -61,16 +61,38 @@ | ||||||
|                 android:textColor="@color/textColor" android:layout_width="wrap_content" |                 android:textColor="@color/textColor" android:layout_width="wrap_content" | ||||||
|                 android:layout_height="match_parent"> |                 android:layout_height="match_parent"> | ||||||
|         </TextView> |         </TextView> | ||||||
|  |          | ||||||
|  |         <FrameLayout | ||||||
|  |                 android:layout_gravity="end" | ||||||
|  |                 android:layout_width="wrap_content" | ||||||
|  |                 android:layout_height="match_parent"> | ||||||
|  |             <androidx.core.widget.ContentLoadingProgressBar | ||||||
|  |                     android:layout_marginEnd="10dp" | ||||||
|  |                     android:layout_marginStart="10dp" | ||||||
|  |                     android:layout_width="40dp" | ||||||
|  |                     android:layout_height="40dp" | ||||||
|  |                     android:id="@+id/result_episode_progress_downloaded" | ||||||
|  |                     android:indeterminate="false" | ||||||
|  |                     android:progressDrawable="@drawable/circular_progress_bar" | ||||||
|  |                     android:background="@drawable/circle_shape" | ||||||
|  |                     style="?android:attr/progressBarStyleHorizontal" | ||||||
|  |                     android:max="100" | ||||||
|  |                     android:layout_margin="5dp" | ||||||
|  |                     android:layout_gravity="end|center_vertical" | ||||||
|  |                     android:progress="0" | ||||||
|  |                     android:visibility="visible" | ||||||
|  |             /> | ||||||
|             <ImageView |             <ImageView | ||||||
|                     android:visibility="visible" |                     android:visibility="visible" | ||||||
|                     android:layout_marginEnd="10dp" |                     android:layout_marginEnd="10dp" | ||||||
|                     android:layout_marginStart="10dp" |                     android:layout_marginStart="10dp" | ||||||
|                     android:layout_height="match_parent" |                     android:layout_height="match_parent" | ||||||
|  |                     android:padding="2dp" | ||||||
|                     android:layout_width="30dp" |                     android:layout_width="30dp" | ||||||
|                 android:id="@+id/episode_download" |                     android:id="@+id/result_episode_download" | ||||||
|                     android:background="?selectableItemBackgroundBorderless" |                     android:background="?selectableItemBackgroundBorderless" | ||||||
|                 android:layout_gravity="center_vertical|end" |                     android:src="@drawable/ic_baseline_play_arrow_24" | ||||||
|                 android:src="@drawable/netflix_download" |  | ||||||
|                     android:contentDescription="@string/download_descript"/> |                     android:contentDescription="@string/download_descript"/> | ||||||
|  |         </FrameLayout> | ||||||
|     </GridLayout> |     </GridLayout> | ||||||
| </androidx.cardview.widget.CardView> | </androidx.cardview.widget.CardView> | ||||||
|  | @ -76,16 +76,40 @@ | ||||||
|                         android:layout_height="wrap_content"> |                         android:layout_height="wrap_content"> | ||||||
|                 </TextView> |                 </TextView> | ||||||
|             </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:layout_marginEnd="10dp" | ||||||
|  |                         android:layout_marginStart="10dp" | ||||||
|  |                         android:layout_width="40dp" | ||||||
|  |                         android:layout_height="40dp" | ||||||
|  |                         android:id="@+id/result_episode_progress_downloaded" | ||||||
|  |                         android:indeterminate="false" | ||||||
|  |                         android:progressDrawable="@drawable/circular_progress_bar" | ||||||
|  |                         android:background="@drawable/circle_shape" | ||||||
|  |                         style="?android:attr/progressBarStyleHorizontal" | ||||||
|  |                         android:max="100" | ||||||
|  |                         android:layout_margin="5dp" | ||||||
|  |                         android:layout_gravity="end|center_vertical" | ||||||
|  |                         android:progress="0" | ||||||
|  |                         android:visibility="visible" | ||||||
|  |                 /> | ||||||
|                 <ImageView |                 <ImageView | ||||||
|                         android:visibility="visible" |                         android:visibility="visible" | ||||||
|                     android:layout_marginStart="-40dp" |                         android:layout_marginEnd="10dp" | ||||||
|  |                         android:layout_marginStart="10dp" | ||||||
|                         android:layout_height="match_parent" |                         android:layout_height="match_parent" | ||||||
|  |                         android:padding="2dp" | ||||||
|                         android:layout_width="30dp" |                         android:layout_width="30dp" | ||||||
|                     android:id="@+id/episode_download" |                         android:id="@+id/result_episode_download" | ||||||
|                         android:background="?selectableItemBackgroundBorderless" |                         android:background="?selectableItemBackgroundBorderless" | ||||||
|                     android:layout_gravity="center_vertical|end" |                         android:src="@drawable/ic_baseline_play_arrow_24" | ||||||
|                     android:src="@drawable/netflix_download" |  | ||||||
|                         android:contentDescription="@string/download_descript"/> |                         android:contentDescription="@string/download_descript"/> | ||||||
|  |             </FrameLayout> | ||||||
|  | 
 | ||||||
|         </LinearLayout> |         </LinearLayout> | ||||||
|         <TextView |         <TextView | ||||||
|                 android:paddingTop="10dp" |                 android:paddingTop="10dp" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue