play video and delete stuff

This commit is contained in:
reduplicated 2022-10-30 02:35:37 +01:00
parent 6a721941ac
commit fa399cd350
12 changed files with 287 additions and 101 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.5' implementation 'com.github.LagradOst:Aria2cButton:v0.0.6'
} }
task androidSourcesJar(type: Jar) { task androidSourcesJar(type: Jar) {

View file

@ -17,6 +17,8 @@ import androidx.appcompat.widget.SearchView
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.google.android.gms.cast.framework.CastSession import com.google.android.gms.cast.framework.CastSession
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.download.Aria2cHelper.removeMetadata
import com.lagradost.cloudstream3.ui.download.Aria2cHelper.saveMetadata
import com.lagradost.cloudstream3.ui.player.PlayerEventType import com.lagradost.cloudstream3.ui.player.PlayerEventType
import com.lagradost.cloudstream3.ui.result.UiText import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
@ -25,10 +27,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 com.lagradost.fetchbutton.aria2c.DownloadListener
import com.lagradost.fetchbutton.aria2c.DownloadStatusTell
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
@ -121,7 +123,6 @@ 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
@ -136,10 +137,17 @@ object CommonActivity {
act.updateTv() act.updateTv()
NewPipe.init(DownloaderTestImpl.getInstance()) NewPipe.init(DownloaderTestImpl.getInstance())
DownloadListener.mainListener = { metadata -> DownloadListener.mainListener = { (data, metadata) ->
//TODO FIX //TODO FIX
DownloadListener.sessionGidToId[metadata.items.firstOrNull()?.gid]?.let { id -> DownloadListener.sessionGidToId[data.gid]?.let { id ->
AcraApplication.setKey(KEY_DOWNLOAD_INFO_METADATA,id.toString(),metadata) if (metadata.status == DownloadStatusTell.Removed
|| metadata.status == DownloadStatusTell.Error
|| metadata.status == DownloadStatusTell.Waiting
|| metadata.status == null) {
removeMetadata(id)
} else {
saveMetadata(id, metadata)
}
/*val mainpath = metadata.items[0].files[0].path /*val mainpath = metadata.items[0].files[0].path
AcraApplication.setKey( AcraApplication.setKey(
VideoDownloadManager.KEY_DOWNLOAD_INFO, VideoDownloadManager.KEY_DOWNLOAD_INFO,

View file

@ -10,10 +10,10 @@ import android.view.KeyEvent
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavController import androidx.navigation.NavController
@ -107,6 +107,8 @@ const val VLC_EXTRA_POSITION_OUT = "extra_position"
const val VLC_EXTRA_DURATION_OUT = "extra_duration" const val VLC_EXTRA_DURATION_OUT = "extra_duration"
const val VLC_LAST_ID_KEY = "vlc_last_open_id" const val VLC_LAST_ID_KEY = "vlc_last_open_id"
const val DOWNLOAD_COUNT_KEY = "download_badge_count"
// Short name for requests client to make it nicer to use // Short name for requests client to make it nicer to use
var app = Requests(responseParser = object : ResponseParser { var app = Requests(responseParser = object : ResponseParser {
@ -150,7 +152,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
* @return true if the str has launched an app task (be it successful or not) * @return true if the str has launched an app task (be it successful or not)
* @param isWebview does not handle providers and opening download page if true. Can still add repos and login. * @param isWebview does not handle providers and opening download page if true. Can still add repos and login.
* */ * */
fun handleAppIntentUrl(activity: FragmentActivity?, str: String?, isWebview: Boolean): Boolean = fun handleAppIntentUrl(
activity: FragmentActivity?,
str: String?,
isWebview: Boolean
): Boolean =
with(activity) { with(activity) {
if (str != null && this != null) { if (str != null && this != null) {
if (str.startsWith("https://cs.repo")) { if (str.startsWith("https://cs.repo")) {
@ -191,7 +197,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
val url = str.replaceFirst(appStringRepo, "https") val url = str.replaceFirst(appStringRepo, "https")
loadRepository(url) loadRepository(url)
return true return true
} else if (!isWebview){ } else if (!isWebview) {
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) { if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
this.navigate(R.id.navigation_downloads) this.navigate(R.id.navigation_downloads)
return true return true
@ -267,6 +273,25 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
} }
} }
if (destination.id == R.id.navigation_download_child || destination.id == R.id.navigation_downloads) {
setKey(DOWNLOAD_COUNT_KEY, 0)
}
nav_view?.getOrCreateBadge(R.id.navigation_downloads)?.apply {
val count = getKey(DOWNLOAD_COUNT_KEY) ?: 0
if (count <= 0) {
clearNumber()
isVisible = false
} else {
this.backgroundColor =
getResourceColor(R.attr.colorPrimary)
this.badgeTextColor =
getResourceColor(R.attr.colorOnPrimary)
isVisible = true
number = count
}
}
nav_view?.isVisible = isNavVisible && !landscape nav_view?.isVisible = isNavVisible && !landscape
nav_rail_view?.isVisible = isNavVisible && landscape nav_rail_view?.isVisible = isNavVisible && landscape
} }

View file

@ -0,0 +1,65 @@
package com.lagradost.cloudstream3.ui.download
import com.lagradost.cloudstream3.AcraApplication
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import com.lagradost.cloudstream3.utils.VideoDownloadManager.KEY_DOWNLOAD_INFO
import com.lagradost.fetchbutton.aria2c.Aria2Starter
import com.lagradost.fetchbutton.aria2c.DownloadListener
import com.lagradost.fetchbutton.aria2c.Metadata
import java.io.File
const val KEY_DOWNLOAD_INFO_METADATA = "download_info_metadata"
object Aria2cHelper {
fun deleteId(id: Long) {
// backward compatibility
VideoDownloadManager.downloadDeleteEvent.invoke(id.toInt())
getMetadata(id)?.let { data ->
Aria2Starter.deleteFiles(data.items.flatMap { it.files })
}
removeMetadata(id)
AcraApplication.removeKey(KEY_DOWNLOAD_INFO, id.toString())
}
fun saveMetadata(id: Long, meta: Metadata) {
AcraApplication.setKey(KEY_DOWNLOAD_INFO_METADATA, id.toString(), meta)
}
fun removeMetadata(id: Long) {
AcraApplication.removeKey(KEY_DOWNLOAD_INFO_METADATA, id.toString())
}
fun downloadExist(data: Metadata): Boolean {
return data.items.any {
it.files.any { file ->
try {
//println("TESTING PATH: ${file.path}")
File(file.path).exists()
} catch (e: Exception) {
false
}
}
}
}
fun downloadExist(id: Long): Boolean {
return downloadExist(getMetadata(id) ?: return false)
}
fun getMetadata(id: Long): Metadata? {
return AcraApplication.getKey(KEY_DOWNLOAD_INFO_METADATA, id.toString())
}
fun pause(id: Long) {
DownloadListener.sessionIdToGid[id]?.let { gid ->
Aria2Starter.pause(gid, all = true)
}
}
fun unpause(id: Long) {
DownloadListener.sessionIdToGid[id]?.let { gid ->
Aria2Starter.unpause(gid, all = true)
}
}
}

View file

@ -16,6 +16,7 @@ import com.lagradost.cloudstream3.utils.ExtractorUri
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.cloudstream3.utils.VideoDownloadManager import com.lagradost.cloudstream3.utils.VideoDownloadManager
import com.lagradost.fetchbutton.aria2c.Aria2Starter
object DownloadButtonSetup { object DownloadButtonSetup {
fun handleDownloadClick(activity: Activity?, click: DownloadClickEvent) { fun handleDownloadClick(activity: Activity?, click: DownloadClickEvent) {
@ -29,6 +30,7 @@ object DownloadButtonSetup {
DialogInterface.OnClickListener { _, which -> DialogInterface.OnClickListener { _, which ->
when (which) { when (which) {
DialogInterface.BUTTON_POSITIVE -> { DialogInterface.BUTTON_POSITIVE -> {
Aria2cHelper.deleteId(id.toLong())
VideoDownloadManager.deleteFileAndUpdateSettings(ctx, id) VideoDownloadManager.deleteFileAndUpdateSettings(ctx, id)
} }
DialogInterface.BUTTON_NEGATIVE -> { DialogInterface.BUTTON_NEGATIVE -> {
@ -57,11 +59,14 @@ object DownloadButtonSetup {
} }
} }
DOWNLOAD_ACTION_PAUSE_DOWNLOAD -> { DOWNLOAD_ACTION_PAUSE_DOWNLOAD -> {
Aria2cHelper.pause(click.data.id.toLong())
VideoDownloadManager.downloadEvent.invoke( VideoDownloadManager.downloadEvent.invoke(
Pair(click.data.id, VideoDownloadManager.DownloadActionType.Pause) Pair(click.data.id, VideoDownloadManager.DownloadActionType.Pause)
) )
} }
DOWNLOAD_ACTION_RESUME_DOWNLOAD -> { DOWNLOAD_ACTION_RESUME_DOWNLOAD -> {
Aria2cHelper.unpause(click.data.id.toLong())
activity?.let { ctx -> activity?.let { ctx ->
if (VideoDownloadManager.downloadStatus.containsKey(id) && VideoDownloadManager.downloadStatus[id] == VideoDownloadManager.DownloadType.IsPaused) { if (VideoDownloadManager.downloadStatus.containsKey(id) && VideoDownloadManager.downloadStatus[id] == VideoDownloadManager.DownloadType.IsPaused) {
VideoDownloadManager.downloadEvent.invoke( VideoDownloadManager.downloadEvent.invoke(
@ -85,7 +90,7 @@ object DownloadButtonSetup {
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings( VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
act, act,
click.data.id click.data.id
)?.fileLength )?.fileLength ?: Aria2cHelper.getMetadata(click.data.id.toLong())?.downloadedLength
?: 0 ?: 0
if (length > 0) { if (length > 0) {
showToast(act, R.string.delete, Toast.LENGTH_LONG) showToast(act, R.string.delete, Toast.LENGTH_LONG)

View file

@ -1,11 +1,15 @@
package com.lagradost.cloudstream3.ui.download package com.lagradost.cloudstream3.ui.download
import android.text.format.Formatter
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.TextView import android.widget.TextView
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.view.doOnAttach
import androidx.core.view.isVisible
import androidx.core.widget.ContentLoadingProgressBar import androidx.core.widget.ContentLoadingProgressBar
import androidx.lifecycle.findViewTreeLifecycleOwner
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.DownloadHelper.play
@ -15,6 +19,7 @@ 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.UIHelper.popupMenuNoIcons
import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.fetchbutton.aria2c.DownloadListener
import com.lagradost.fetchbutton.aria2c.DownloadStatusTell import com.lagradost.fetchbutton.aria2c.DownloadStatusTell
import com.lagradost.fetchbutton.ui.PieFetchButton import com.lagradost.fetchbutton.ui.PieFetchButton
import kotlinx.android.synthetic.main.download_child_episode.view.* import kotlinx.android.synthetic.main.download_child_episode.view.*
@ -93,15 +98,52 @@ class DownloadChildAdapter(
title.isSelected = true // is needed for text repeating title.isSelected = true // is needed for text repeating
//extraInfo.text = card.currentBytes //extraInfo.text = card.currentBytes
fun updateText(downloadBytes: Long, totalBytes: Long) {
extraInfo?.apply {
text =
context.getString(R.string.download_size_format).format(
Formatter.formatShortFileSize(context, downloadBytes),
Formatter.formatShortFileSize(context, totalBytes)
)
}
}
updateText(card.currentBytes, card.totalBytes)
downloadButton.apply { downloadButton.apply {
val play = val play =
R.string.play_episode//if (card.episode <= 0) R.string.play_movie_button else R.string.play_episode R.string.play_episode//if (card.episode <= 0) R.string.play_movie_button else R.string.play_episode
setPersistentId(card.data.id.toLong()) setPersistentId(d.id.toLong())
doOnAttach { view ->
view.findViewTreeLifecycleOwner()?.let { life ->
DownloadListener.observe(life) {
gid?.let { realGId ->
val meta = DownloadListener.getInfo(realGId)
updateText(meta.downloadedLength, meta.totalLength)
}
}
}
}
downloadButton.isVisible = when (downloadButton.currentStatus) {
null, DownloadStatusTell.Removed -> false
else -> true
}
downloadButton.setOnClickListener { downloadButton.setOnClickListener {
val view = downloadButton val view = downloadButton
fun delete() {
// view.deleteAllFiles()
clickCallback.invoke(
DownloadClickEvent(
DOWNLOAD_ACTION_DELETE_FILE,
d
)
)
}
//if (view !is PieFetchButton) return@setOnClickListener //if (view !is PieFetchButton) return@setOnClickListener
when (view.currentStatus) { when (view.currentStatus) {
/*null, DownloadStatusTell.Removed -> { /*null, DownloadStatusTell.Removed -> {
@ -130,8 +172,8 @@ class DownloadChildAdapter(
) )
)*/ )*/
} }
2 -> play(card.data) 2 -> play(d)
3 -> view.deleteAllFiles() 3 -> delete()
} }
} }
} }
@ -143,8 +185,8 @@ class DownloadChildAdapter(
) )
) { ) {
when (itemId) { when (itemId) {
2 -> play(card.data) 2 -> play(d)
3 -> view.deleteAllFiles() 3 -> delete()
} }
} }
} }
@ -158,8 +200,8 @@ class DownloadChildAdapter(
) { ) {
when (itemId) { when (itemId) {
4 -> view.pauseDownload() 4 -> view.pauseDownload()
2 -> play(card.data) 2 -> play(d)
3 -> view.deleteAllFiles() 3 -> delete()
} }
} }
} }
@ -173,9 +215,15 @@ class DownloadChildAdapter(
} }
} }
} }
holder.setOnClickListener {
if (downloadButton.isVisible) {
downloadButton.play(d)
} else {
holder.setOnClickListener { holder.setOnClickListener {
clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d)) clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d))
} }
} }
} }
}
}
} }

View file

@ -21,7 +21,7 @@ import kotlinx.coroutines.withContext
class DownloadChildFragment : Fragment() { class DownloadChildFragment : Fragment() {
companion object { companion object {
fun newInstance(headerName: String, folder: String) : Bundle { fun newInstance(headerName: String, folder: String): Bundle {
return Bundle().apply { return Bundle().apply {
putString("folder", folder) putString("folder", folder)
putString("name", headerName) putString("name", headerName)
@ -34,7 +34,11 @@ class DownloadChildFragment : Fragment() {
super.onDestroyView() super.onDestroyView()
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_child_downloads, container, false) return inflater.inflate(R.layout.fragment_child_downloads, container, false)
} }
@ -49,7 +53,7 @@ class DownloadChildFragment : Fragment() {
?: return@mapNotNull null ?: return@mapNotNull null
VisualDownloadChildCached(info.fileLength, info.totalBytes, it) VisualDownloadChildCached(info.fileLength, info.totalBytes, it)
} }
}.sortedBy { it.data.episode + (it.data.season?: 0)*100000 } }.sortedBy { it.data.episode + (it.data.season ?: 0) * 100000 }
if (eps.isEmpty()) { if (eps.isEmpty()) {
activity?.onBackPressed() activity?.onBackPressed()
return@main return@main
@ -84,6 +88,13 @@ class DownloadChildFragment : Fragment() {
ArrayList(), ArrayList(),
) { click -> ) { click ->
handleDownloadClick(activity, click) handleDownloadClick(activity, click)
/* println("HANDLE ACTION :${click.action}")
if (click.action == DOWNLOAD_ACTION_DELETE_FILE) {
val list = (download_child_list?.adapter as DownloadChildAdapter?)?.cardList
if (list != null) {
updateList(folder)
}
}*/
} }
downloadDeleteEventListener = { id: Int -> downloadDeleteEventListener = { id: Int ->

View file

@ -1,50 +1,59 @@
package com.lagradost.cloudstream3.ui.result package com.lagradost.cloudstream3.ui.result
import android.app.Activity import androidx.core.net.toUri
import android.net.Uri
import android.widget.Toast
import com.lagradost.cloudstream3.CommonActivity.showToast
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.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.ui.player.GeneratorPlayer
import com.lagradost.cloudstream3.utils.ExtractorUri import com.lagradost.cloudstream3.utils.ExtractorUri
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons
import com.lagradost.cloudstream3.utils.VideoDownloadHelper 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
import java.io.File
object DownloadHelper { object DownloadHelper {
fun PieFetchButton.play(card: VideoDownloadHelper.DownloadEpisodeCached) { fun PieFetchButton.play(card: VideoDownloadHelper.DownloadEpisodeCached) {
val files = this.getVideos() val files = this.getVideos()
DownloadFileGenerator( // fucked af, but who cares
Aria2Starter.saveActivity.get()?.navigate(
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(DownloadFileGenerator(
files.map { path -> files.map { path ->
val file = File(path)
ExtractorUri( ExtractorUri(
uri = Uri.parse(path), uri = file.toUri(),
id = card.id, id = card.id,
parentId = card.parentId, parentId = card.parentId,
name = context.getString(R.string.downloaded_file), //click.data.name ?: keyInfo.displayName name = context.getString(R.string.downloaded_file), //click.data.name ?: keyInfo.displayName
season = card.season, season = card.season,
episode = card.episode episode = card.episode,
//basePath = keyInfo.basePath, basePath = file.path,
displayName = file.name
//displayName = keyInfo.displayName, //displayName = keyInfo.displayName,
//relativePath = keyInfo.relativePath, //relativePath = keyInfo.relativePath,
) )
} }
) )))
} }
fun PieFetchButton.play(card: ResultEpisode) { fun PieFetchButton.play(card: ResultEpisode) {
val files = this.getVideos() val files = this.getVideos()
DownloadFileGenerator( // fucked af, but who cares
Aria2Starter.saveActivity.get()?.navigate(
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(DownloadFileGenerator(
files.map { path -> files.map { path ->
val file = File(path)
ExtractorUri( ExtractorUri(
uri = Uri.parse(path), uri = file.toUri(),
id = card.id, id = card.id,
parentId = card.parentId, parentId = card.parentId,
@ -54,12 +63,12 @@ object DownloadHelper {
headerName = card.headerName, headerName = card.headerName,
tvType = card.tvType, tvType = card.tvType,
//basePath = keyInfo.basePath, basePath = file.path,
//displayName = keyInfo.displayName, displayName = file.name,
//relativePath = keyInfo.relativePath, //relativePath = keyInfo.relativePath,
) )
} }
) )))
} }
fun PieFetchButton.setUp( fun PieFetchButton.setUp(
@ -70,7 +79,12 @@ object DownloadHelper {
val play = if (card.episode <= 0) R.string.play_movie_button else R.string.play_episode val play = if (card.episode <= 0) R.string.play_movie_button else R.string.play_episode
setOnLongClickListener { //Aria2Starter.saveActivity.get() setOnLongClickListener { //Aria2Starter.saveActivity.get()
downloadClickCallback.invoke(DownloadEpisodeClickEvent(DOWNLOAD_ACTION_LONG_CLICK, card)) downloadClickCallback.invoke(
DownloadEpisodeClickEvent(
DOWNLOAD_ACTION_LONG_CLICK,
card
)
)
//showToast(it.context as? Activity, R.string.download, Toast.LENGTH_SHORT) //showToast(it.context as? Activity, R.string.download, Toast.LENGTH_SHORT)
return@setOnLongClickListener true return@setOnLongClickListener true
} }

View file

@ -16,6 +16,8 @@ import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.getId import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.APIHolder.unixTime import com.lagradost.cloudstream3.APIHolder.unixTime
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.CommonActivity.getCastSession import com.lagradost.cloudstream3.CommonActivity.getCastSession
import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
@ -55,8 +57,6 @@ import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.requestRW import com.lagradost.cloudstream3.utils.UIHelper.requestRW
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getBasePath
import com.lagradost.cloudstream3.utils.VideoDownloadManager.gotoDir
import com.lagradost.fetchbutton.NotificationMetaData import com.lagradost.fetchbutton.NotificationMetaData
import com.lagradost.fetchbutton.aria2c.Aria2Starter import com.lagradost.fetchbutton.aria2c.Aria2Starter
import com.lagradost.fetchbutton.aria2c.UriRequest import com.lagradost.fetchbutton.aria2c.UriRequest
@ -604,10 +604,12 @@ class ResultViewModel2 : ViewModel() {
currentType currentType
) )
val topFolder = VideoDownloadManager.getDownloadDir()?.filePath ?: throw RuntimeException("FUCK YOU")//AcraApplication.context?.getBasePath()?.first //?.second?.also { println("URIIIIII: $it") } ?: throw RuntimeException("FUCK YOU") val topFolder = VideoDownloadManager.getDownloadDir()?.filePath
?: throw RuntimeException("FUCK YOU")//AcraApplication.context?.getBasePath()?.first //?.second?.also { println("URIIIIII: $it") } ?: throw RuntimeException("FUCK YOU")
//?: VideoDownloadManager.getDownloadDir()?.filePath ?: return null //?: VideoDownloadManager.getDownloadDir()?.filePath ?: return null
val folder = topFolder//topFolder?.gotoDir(getFolder(currentType, currentHeaderName).replace(".", ""), true)?.uri?.toString() ?: throw RuntimeException("FUCK YOU") val folder =
topFolder//topFolder?.gotoDir(getFolder(currentType, currentHeaderName).replace(".", ""), true)?.uri?.toString() ?: throw RuntimeException("FUCK YOU")
//val folder = //val folder =
// topFolder + "/" + getFolder(currentType, currentHeaderName).replace(".", "") // topFolder + "/" + getFolder(currentType, currentHeaderName).replace(".", "")
//val src = "$DOWNLOAD_NAVIGATE_TO/$parentId" // url ?: return@let //val src = "$DOWNLOAD_NAVIGATE_TO/$parentId" // url ?: return@let
@ -670,12 +672,13 @@ class ResultViewModel2 : ViewModel() {
val linkRequests = links.filter { link -> !link.isM3u8 }.map { link -> val linkRequests = links.filter { link -> !link.isM3u8 }.map { link ->
newUriRequest( newUriRequest(
episode.id.toLong(), link.url, episode.id.toLong(), link.url,
getFolder(currentType, currentHeaderName) + File.pathSeparator +
VideoDownloadManager.getDisplayName( VideoDownloadManager.getDisplayName(
VideoDownloadManager.getFileName( VideoDownloadManager.getFileName(
AcraApplication.context ?: return null, AcraApplication.context ?: return null,
meta meta
), "mp4" ), "mp4"
), null, ), null, // we use the dir set at start
link.headers, USER_AGENT, link.headers, USER_AGENT,
notificationMetaData = notification?.copy( notificationMetaData = notification?.copy(
linkName = "${link.name} ${ linkName = "${link.name} ${
@ -1107,6 +1110,7 @@ class ResultViewModel2 : ViewModel() {
Aria2Starter.download(sub) Aria2Starter.download(sub)
} }
val linksFound = req.links.isNotEmpty() val linksFound = req.links.isNotEmpty()
setKey(DOWNLOAD_COUNT_KEY, (getKey(DOWNLOAD_COUNT_KEY) ?: 0) + 1)
mainThread { mainThread {
showToast( showToast(
activity, activity,

View file

@ -29,12 +29,12 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
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
import com.lagradost.cloudstream3.ui.download.Aria2cHelper
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
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
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,17 +1487,17 @@ 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) { if (res == null) {
AcraApplication.getKey<Metadata>( Aria2cHelper.getMetadata(id.toLong())?.let { data ->
CommonActivity.KEY_DOWNLOAD_INFO_METADATA, if (Aria2cHelper.downloadExist(data)) {
id.toString()
)?.let { data ->
if (data.totalLength > 1000L)
return DownloadedFileInfoResult( return DownloadedFileInfoResult(
data.downloadedLength, data.totalLength, data.downloadedLength,
data.totalLength,
Uri.EMPTY Uri.EMPTY
) )
} }
}
Aria2cHelper.deleteId(id.toLong())
context.removeKey(KEY_DOWNLOAD_INFO, id.toString()) context.removeKey(KEY_DOWNLOAD_INFO, id.toString())
} }
return res return res
@ -1629,7 +1629,7 @@ object VideoDownloadManager {
} }
} }
/*fun isMyServiceRunning(context: Context, serviceClass: Class<*>): Boolean { /*fun isMyServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager? val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
for (service in manager!!.getRunningServices(Int.MAX_VALUE)) { for (service in manager!!.getRunningServices(Int.MAX_VALUE)) {
if (serviceClass.name == service.service.className) { if (serviceClass.name == service.service.className) {
@ -1637,7 +1637,7 @@ object VideoDownloadManager {
} }
} }
return false return false
}*/ }*/
fun downloadEpisode( fun downloadEpisode(
context: Context?, context: Context?,

View file

@ -22,6 +22,10 @@
<color name="white">#FFF</color> <color name="white">#FFF</color>
<color name="black">#000</color> <color name="black">#000</color>
<color name="whiteText">#FFF</color>
<color name="blackText">#000</color>
<color name="dubColor">#3d50fa</color> <!--3b65f5 f18c82 8294F1--> <color name="dubColor">#3d50fa</color> <!--3b65f5 f18c82 8294F1-->
<color name="amoledModeLight">#121213</color> <color name="amoledModeLight">#121213</color>

View file

@ -55,6 +55,8 @@
<!-- DEF STYLE --> <!-- DEF STYLE -->
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorOnPrimary">@color/whiteText</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="textColor">@color/textColor</item> <item name="textColor">@color/textColor</item>
<item name="grayTextColor">@color/grayTextColor</item> <item name="grayTextColor">@color/grayTextColor</item>
@ -105,7 +107,7 @@
<item name="android:colorPrimary">@color/colorPrimary</item> <item name="android:colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="colorOnPrimary">@color/colorAccent</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorAccent</item> <item name="android:colorAccent">@color/colorAccent</item>
</style> </style>
@ -115,7 +117,7 @@
<item name="android:colorPrimary">@color/colorPrimaryBlue</item> <item name="android:colorPrimary">@color/colorPrimaryBlue</item>
<item name="colorPrimaryDark">#4855A2</item> <item name="colorPrimaryDark">#4855A2</item>
<item name="colorAccent">#5A6BCB</item> <item name="colorAccent">#5A6BCB</item>
<item name="colorOnPrimary">#5A6BCB</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryBlue</item> <item name="android:colorAccent">@color/colorPrimaryBlue</item>
</style> </style>
@ -125,7 +127,7 @@
<item name="android:colorPrimary">@color/colorPrimaryPurple</item> <item name="android:colorPrimary">@color/colorPrimaryPurple</item>
<item name="colorPrimaryDark">#4704A3</item> <item name="colorPrimaryDark">#4704A3</item>
<item name="colorAccent">#7125DB</item> <item name="colorAccent">#7125DB</item>
<item name="colorOnPrimary">#7125DB</item> <item name="colorOnPrimary">@color/whiteText</item>
<item name="android:colorAccent">@color/colorPrimaryPurple</item> <item name="android:colorAccent">@color/colorPrimaryPurple</item>
</style> </style>
@ -134,7 +136,7 @@
<item name="android:colorPrimary">@color/colorPrimaryGreen</item> <item name="android:colorPrimary">@color/colorPrimaryGreen</item>
<item name="colorPrimaryDark">#007363</item> <item name="colorPrimaryDark">#007363</item>
<item name="colorAccent">#39C1AE</item> <item name="colorAccent">#39C1AE</item>
<item name="colorOnPrimary">#39C1AE</item> <item name="colorOnPrimary">@color/blackText</item>
<item name="android:colorAccent">@color/colorPrimaryGreen</item> <item name="android:colorAccent">@color/colorPrimaryGreen</item>
</style> </style>
@ -143,7 +145,7 @@
<item name="android:colorPrimary">@color/colorPrimaryGreenApple</item> <item name="android:colorPrimary">@color/colorPrimaryGreenApple</item>
<item name="colorPrimaryDark">#319B5A</item> <item name="colorPrimaryDark">#319B5A</item>
<item name="colorAccent">#51C57E</item> <item name="colorAccent">#51C57E</item>
<item name="colorOnPrimary">#51C57E</item> <item name="colorOnPrimary">@color/blackText</item>
<item name="android:colorAccent">@color/colorPrimaryGreenApple</item> <item name="android:colorAccent">@color/colorPrimaryGreenApple</item>
</style> </style>
@ -152,7 +154,7 @@
<item name="android:colorPrimary">@color/colorPrimaryRed</item> <item name="android:colorPrimary">@color/colorPrimaryRed</item>
<item name="colorPrimaryDark">#B62B2B</item> <item name="colorPrimaryDark">#B62B2B</item>
<item name="colorAccent">@color/colorPrimaryRed</item> <!--#F53B3B--> <item name="colorAccent">@color/colorPrimaryRed</item> <!--#F53B3B-->
<item name="colorOnPrimary">@color/colorPrimaryRed</item> <!--#EC3838--> <item name="colorOnPrimary">@color/whiteText</item> <!--#EC3838-->
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryRed</item> <item name="android:colorAccent">@color/colorPrimaryRed</item>
</style> </style>
@ -162,7 +164,7 @@
<item name="android:colorPrimary">@color/colorPrimaryBanana</item> <item name="android:colorPrimary">@color/colorPrimaryBanana</item>
<item name="colorPrimaryDark">#9B7D31</item> <item name="colorPrimaryDark">#9B7D31</item>
<item name="colorAccent">#C5B251</item> <item name="colorAccent">#C5B251</item>
<item name="colorOnPrimary">#C5A851</item> <item name="colorOnPrimary">@color/blackText</item>
<item name="android:colorAccent">@color/colorPrimaryBanana</item> <item name="android:colorAccent">@color/colorPrimaryBanana</item>
</style> </style>
@ -171,7 +173,7 @@
<item name="android:colorPrimary">@color/colorPrimaryParty</item> <item name="android:colorPrimary">@color/colorPrimaryParty</item>
<item name="colorPrimaryDark">#C1495B</item> <item name="colorPrimaryDark">#C1495B</item>
<item name="colorAccent">#FD798C</item> <item name="colorAccent">#FD798C</item>
<item name="colorOnPrimary">#BF5968</item> <item name="colorOnPrimary">@color/blackText</item>
<item name="android:colorAccent">@color/colorPrimaryParty</item> <item name="android:colorAccent">@color/colorPrimaryParty</item>
</style> </style>
@ -180,7 +182,7 @@
<item name="android:colorPrimary">@color/colorPrimaryPink</item> <item name="android:colorPrimary">@color/colorPrimaryPink</item>
<item name="colorPrimaryDark">#DD1280</item> <item name="colorPrimaryDark">#DD1280</item>
<item name="colorAccent">#FF4DAE</item> <item name="colorAccent">#FF4DAE</item>
<item name="colorOnPrimary">#DD1280</item> <item name="colorOnPrimary">@color/blackText</item>
<item name="android:colorAccent">@color/colorPrimaryPink</item> <item name="android:colorAccent">@color/colorPrimaryPink</item>
</style> </style>
@ -189,7 +191,7 @@
<item name="android:colorPrimary">@color/colorPrimaryCarnationPink</item> <item name="android:colorPrimary">@color/colorPrimaryCarnationPink</item>
<item name="colorPrimaryDark">#83366f</item> <item name="colorPrimaryDark">#83366f</item>
<item name="colorAccent">#BD5DA5</item> <item name="colorAccent">#BD5DA5</item>
<item name="colorOnPrimary">#BD5DA5</item> <item name="colorOnPrimary">@color/blackText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryCarnationPink</item> <item name="android:colorAccent">@color/colorPrimaryCarnationPink</item>
</style> </style>
@ -199,7 +201,7 @@
<item name="android:colorPrimary">@color/colorPrimaryMaroon</item> <item name="android:colorPrimary">@color/colorPrimaryMaroon</item>
<item name="colorPrimaryDark">#370C0C</item> <item name="colorPrimaryDark">#370C0C</item>
<item name="colorAccent">#451010</item> <item name="colorAccent">#451010</item>
<item name="colorOnPrimary">#451010</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryMaroon</item> <item name="android:colorAccent">@color/colorPrimaryMaroon</item>
</style> </style>
@ -209,7 +211,7 @@
<item name="android:colorPrimary">@color/colorPrimaryDarkGreen</item> <item name="android:colorPrimary">@color/colorPrimaryDarkGreen</item>
<item name="colorPrimaryDark">#003d00</item> <item name="colorPrimaryDark">#003d00</item>
<item name="colorAccent">#004500</item> <item name="colorAccent">#004500</item>
<item name="colorOnPrimary">#004500</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryDarkGreen</item> <item name="android:colorAccent">@color/colorPrimaryDarkGreen</item>
</style> </style>
@ -219,7 +221,7 @@
<item name="android:colorPrimary">@color/colorPrimaryNavyBlue</item> <item name="android:colorPrimary">@color/colorPrimaryNavyBlue</item>
<item name="colorPrimaryDark">#000073</item> <item name="colorPrimaryDark">#000073</item>
<item name="colorAccent">#000080</item> <item name="colorAccent">#000080</item>
<item name="colorOnPrimary">#000080</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryNavyBlue</item> <item name="android:colorAccent">@color/colorPrimaryNavyBlue</item>
</style> </style>
@ -229,7 +231,7 @@
<item name="android:colorPrimary">@color/colorPrimaryGrey</item> <item name="android:colorPrimary">@color/colorPrimaryGrey</item>
<item name="colorPrimaryDark">#484848</item> <item name="colorPrimaryDark">#484848</item>
<item name="colorAccent">#515151</item> <item name="colorAccent">#515151</item>
<item name="colorOnPrimary">#515151</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryGrey</item> <item name="android:colorAccent">@color/colorPrimaryGrey</item>
</style> </style>
@ -239,7 +241,7 @@
<item name="android:colorPrimary">@color/colorPrimaryWhite</item> <item name="android:colorPrimary">@color/colorPrimaryWhite</item>
<item name="colorPrimaryDark">#CCCCCC</item> <item name="colorPrimaryDark">#CCCCCC</item>
<item name="colorAccent">#FFFFFF</item> <item name="colorAccent">#FFFFFF</item>
<item name="colorOnPrimary">#FFFFFF</item> <item name="colorOnPrimary">@color/blackText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryWhite</item> <item name="android:colorAccent">@color/colorPrimaryWhite</item>
</style> </style>
@ -249,7 +251,7 @@
<item name="android:colorPrimary">@color/colorPrimaryBrown</item> <item name="android:colorPrimary">@color/colorPrimaryBrown</item>
<item name="colorPrimaryDark">#582700</item> <item name="colorPrimaryDark">#582700</item>
<item name="colorAccent">#622C00</item> <item name="colorAccent">#622C00</item>
<item name="colorOnPrimary">#622C00</item> <item name="colorOnPrimary">@color/whiteText</item>
<!-- Needed for leanback fuckery --> <!-- Needed for leanback fuckery -->
<item name="android:colorAccent">@color/colorPrimaryBrown</item> <item name="android:colorAccent">@color/colorPrimaryBrown</item>
</style> </style>