...
This commit is contained in:
parent
1b55784839
commit
c30285133b
52 changed files with 533 additions and 365 deletions
|
|
@ -4,13 +4,14 @@ plugins {
|
|||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.devtools.ksp'
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "1.8.10"
|
||||
id "org.jetbrains.kotlin.plugin.parcelize" version "1.8.10"
|
||||
}
|
||||
|
||||
def properties = new Properties()
|
||||
def versionMajor = 1
|
||||
def versionMinor = 6
|
||||
def versionPatch = 8
|
||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
||||
def versionBuild = 1 // bump for dogfood builds, public betas, etc.
|
||||
def versionExt = ""
|
||||
|
||||
if (versionBuild > 0){
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
android:name=".MainActivity"
|
||||
android:configChanges="locale"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
|
||||
</activity>
|
||||
|
|
@ -53,6 +54,7 @@
|
|||
android:configChanges="smallestScreenSize|layoutDirection|locale|orientation|screenSize"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/Theme.BottomSheet">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
|
@ -125,6 +127,7 @@
|
|||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:configChanges="locale"
|
||||
android:launchMode="singleTask"
|
||||
android:targetActivity=".MainActivity"
|
||||
android:windowSoftInputMode="adjustPan"
|
||||
android:exported="true">
|
||||
|
|
@ -147,6 +150,7 @@
|
|||
android:icon="@mipmap/ic_launcher_dark"
|
||||
android:roundIcon="@mipmap/ic_launcher_round_dark"
|
||||
android:configChanges="locale"
|
||||
android:launchMode="singleTask"
|
||||
android:targetActivity=".MainActivity"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
<intent-filter>
|
||||
|
|
@ -167,6 +171,7 @@
|
|||
android:icon="@mipmap/ic_launcher_light"
|
||||
android:roundIcon="@mipmap/ic_launcher_round_light"
|
||||
android:configChanges="locale"
|
||||
android:launchMode="singleTask"
|
||||
android:targetActivity=".MainActivity"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
<intent-filter>
|
||||
|
|
@ -184,6 +189,7 @@
|
|||
android:name=".ui.more.WebViewActivity"
|
||||
android:configChanges="locale"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import androidx.fragment.app.FragmentContainerView
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
|
|
@ -48,6 +49,7 @@ import com.deniscerri.ytdlnis.util.ThemeUtil
|
|||
import com.deniscerri.ytdlnis.util.UpdateUtil
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.elevation.SurfaceColors
|
||||
import com.google.android.material.navigation.NavigationBarView
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.navigationrail.NavigationRailView
|
||||
|
|
@ -82,6 +84,7 @@ class MainActivity : BaseActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeUtil.updateTheme(this)
|
||||
window.navigationBarColor = SurfaceColors.SURFACE_2.getColor(this)
|
||||
setContentView(R.layout.activity_main)
|
||||
context = baseContext
|
||||
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
|
||||
|
|
@ -362,8 +365,10 @@ class MainActivity : BaseActivity() {
|
|||
Toast.makeText(context, "Couldn't read file", Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
val bottomSheet = DownloadBottomSheetDialog(type = DownloadViewModel.Type.command, result = downloadViewModel.createEmptyResultItem(f.absolutePath))
|
||||
bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable("result", downloadViewModel.createEmptyResultItem(f.absolutePath))
|
||||
bundle.putSerializable("type", DownloadViewModel.Type.command)
|
||||
navController.navigate(R.id.downloadBottomSheetDialog, bundle)
|
||||
}else{
|
||||
val `is` = contentResolver.openInputStream(uri!!)
|
||||
val textBuilder = StringBuilder()
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ interface DownloadDao {
|
|||
@Query("SELECT * FROM downloads ORDER BY status")
|
||||
fun getAllDownloads() : PagingSource<Int, DownloadItem>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Active' or status='Paused'")
|
||||
@Query("SELECT * FROM downloads WHERE status in ('Active', 'ActivePaused', 'PausedReQueued')")
|
||||
fun getActiveDownloads() : Flow<List<DownloadItem>>
|
||||
|
||||
@Query("SELECT COUNT(*) FROM downloads WHERE status='Active' or status='Paused'")
|
||||
@Query("SELECT COUNT(*) FROM downloads WHERE status in ('Active', 'ActivePaused', 'PausedReQueued')")
|
||||
fun getActiveDownloadsCountFlow() : Flow<Int>
|
||||
|
||||
@Query("SELECT COUNT(*) FROM downloads WHERE status in (:status)")
|
||||
|
|
@ -25,34 +25,34 @@ interface DownloadDao {
|
|||
@Query("SELECT COUNT(*) FROM downloads WHERE status in (:status)")
|
||||
fun getDownloadsCountByStatus(status : List<String>) : Int
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Active' or status='Paused'")
|
||||
@Query("SELECT * FROM downloads WHERE status in('Active','ActivePaused','PausedReQueued')")
|
||||
fun getActiveAndPausedDownloadsList() : List<DownloadItem>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Active'")
|
||||
fun getActiveDownloadsList() : List<DownloadItem>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Active' or status='Queued' or status='QueuedPaused' or status='Paused'")
|
||||
@Query("SELECT * FROM downloads WHERE status in('Active','Queued','QueuedPaused','ActivePaused','PausedReQueued')")
|
||||
fun getActiveAndQueuedDownloadsList() : List<DownloadItem>
|
||||
|
||||
@Query("SELECT id FROM downloads WHERE status='Active' or status='Queued' or status='QueuedPaused' or status='Paused'")
|
||||
@Query("SELECT id FROM downloads WHERE status in('Active','Queued','QueuedPaused','ActivePaused','PausedReQueued')")
|
||||
fun getActiveAndQueuedDownloadIDs() : List<Long>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Active' or status='Queued' or status='QueuedPaused' or status='Paused'")
|
||||
@Query("SELECT * FROM downloads WHERE status in('Active','Queued','QueuedPaused','ActivePaused','PausedReQueued')")
|
||||
fun getActiveAndQueuedDownloads() : Flow<List<DownloadItem>>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Queued' or status='QueuedPaused' ORDER BY downloadStartTime, id")
|
||||
@Query("SELECT * FROM downloads WHERE status in('Queued','QueuedPaused') ORDER BY downloadStartTime, id")
|
||||
fun getQueuedDownloads() : PagingSource<Int, DownloadItemSimple>
|
||||
|
||||
@Query("SELECT format FROM downloads WHERE status='Queued' or status='QueuedPaused'")
|
||||
@Query("SELECT format FROM downloads WHERE status in('Queued','QueuedPaused')")
|
||||
fun getSelectedFormatFromQueued() : List<Format>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE downloadStartTime <= :currentTime and status='Queued' ORDER BY downloadStartTime, id LIMIT 20")
|
||||
@Query("SELECT * FROM downloads WHERE downloadStartTime <= :currentTime and status in ('Queued', 'PausedReQueued') ORDER BY downloadStartTime, id LIMIT 20")
|
||||
fun getQueuedDownloadsThatAreNotScheduledChunked(currentTime: Long) : Flow<List<DownloadItem>>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Queued' or status='QueuedPaused' or status='Paused' ORDER BY downloadStartTime, id")
|
||||
@Query("SELECT * FROM downloads WHERE status in ('Queued','QueuedPaused','ActivePaused','PausedReQueued') ORDER BY downloadStartTime, id")
|
||||
fun getQueuedAndPausedDownloads() : Flow<List<DownloadItem>>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Queued' or status='QueuedPaused' ORDER BY downloadStartTime, id")
|
||||
@Query("SELECT * FROM downloads WHERE status in('Queued','QueuedPaused') ORDER BY downloadStartTime, id")
|
||||
fun getQueuedDownloadsList() : List<DownloadItem>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Cancelled' ORDER BY id DESC")
|
||||
|
|
@ -87,7 +87,7 @@ interface DownloadDao {
|
|||
|
||||
@Query("UPDATE downloads " +
|
||||
"SET status = CASE " +
|
||||
" WHEN status = 'Active' THEN 'Paused' " +
|
||||
" WHEN status = 'Active' THEN 'ActivePaused' " +
|
||||
" WHEN status = 'Queued' THEN 'QueuedPaused' " +
|
||||
" ELSE status " +
|
||||
" END;")
|
||||
|
|
@ -95,7 +95,7 @@ interface DownloadDao {
|
|||
|
||||
@Query("UPDATE downloads " +
|
||||
"SET status = CASE " +
|
||||
" WHEN status = 'Paused' THEN 'Active' " +
|
||||
" WHEN status = 'ActivePaused' THEN 'Active' " +
|
||||
" WHEN status = 'QueuedPaused' THEN 'Queued' " +
|
||||
" ELSE status " +
|
||||
" END;")
|
||||
|
|
@ -125,7 +125,7 @@ interface DownloadDao {
|
|||
@Query("DELETE FROM downloads WHERE id in (:list)")
|
||||
suspend fun deleteAllWithIDs(list: List<Long>)
|
||||
|
||||
@Query("UPDATE downloads SET status='Cancelled' WHERE status='Queued' or status='QueuedPaused' or status='Active' or status='Paused'")
|
||||
@Query("UPDATE downloads SET status='Cancelled' WHERE status in('Queued','QueuedPaused','Active','ActivePaused','PausedReQueued')")
|
||||
suspend fun cancelActiveQueued()
|
||||
|
||||
@Query("DELETE FROM downloads WHERE status='Processing' AND id=:id")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class AudioPreferences(
|
||||
var embedThumb: Boolean = true,
|
||||
var splitByChapters: Boolean = false,
|
||||
var sponsorBlockFilters: ArrayList<String> = arrayListOf()
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class ChapterItem(
|
||||
@SerializedName(value = "start_time")
|
||||
var start_time: Long,
|
||||
|
|
@ -9,4 +12,4 @@ data class ChapterItem(
|
|||
var end_time: Long,
|
||||
@SerializedName(value = "title")
|
||||
var title: String,
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Entity(tableName = "downloads")
|
||||
@Parcelize
|
||||
data class DownloadItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long,
|
||||
|
|
@ -24,7 +27,7 @@ data class DownloadItem(
|
|||
var downloadPath: String,
|
||||
var website: String,
|
||||
val downloadSize: String,
|
||||
val playlistTitle: String,
|
||||
var playlistTitle: String,
|
||||
val audioPreferences : AudioPreferences,
|
||||
val videoPreferences: VideoPreferences,
|
||||
@ColumnInfo(defaultValue = "")
|
||||
|
|
@ -36,4 +39,4 @@ data class DownloadItem(
|
|||
@ColumnInfo(defaultValue = "0")
|
||||
var downloadStartTime: Long,
|
||||
var logID: Long?
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class Format(
|
||||
@SerializedName(value = "format_id", alternate = ["itag"])
|
||||
var format_id: String = "",
|
||||
|
|
@ -23,4 +26,4 @@ data class Format(
|
|||
var asr: String? = "",
|
||||
@SerializedName(value = "url")
|
||||
var url: String? = ""
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Entity(tableName = "results")
|
||||
@Parcelize
|
||||
data class ResultItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long,
|
||||
|
|
@ -20,4 +23,4 @@ data class ResultItem(
|
|||
var urls: String,
|
||||
var chapters: MutableList<ChapterItem>?,
|
||||
var creationTime: Long = System.currentTimeMillis() / 1000,
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
package com.deniscerri.ytdlnis.database.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class VideoPreferences (
|
||||
var embedSubs: Boolean = true,
|
||||
var addChapters: Boolean = true,
|
||||
|
|
@ -9,4 +13,4 @@ data class VideoPreferences (
|
|||
var subsLanguages: String = "en.*,.*-orig",
|
||||
var audioFormatIDs : ArrayList<String> = arrayListOf(),
|
||||
var removeAudio: Boolean = false
|
||||
)
|
||||
) : Parcelable
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
val activeDownloadsCount : Flow<Int> = downloadDao.getActiveDownloadsCountFlow()
|
||||
|
||||
enum class Status {
|
||||
Active, Paused, Queued, QueuedPaused, Error, Cancelled, Saved
|
||||
Active, ActivePaused, PausedReQueued, Queued, QueuedPaused, Error, Cancelled, Saved
|
||||
}
|
||||
|
||||
suspend fun insert(item: DownloadItem) : Long {
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
}
|
||||
|
||||
items.forEach {
|
||||
if (it.status != DownloadRepository.Status.Paused.toString()) it.status = DownloadRepository.Status.Queued.toString()
|
||||
if (it.status != DownloadRepository.Status.ActivePaused.toString()) it.status = DownloadRepository.Status.Queued.toString()
|
||||
val currentCommand = infoUtil.buildYoutubeDLRequest(it)
|
||||
val parsedCurrentCommand = infoUtil.parseYTDLRequestString(currentCommand)
|
||||
val existingDownload = activeAndQueuedDownloads.firstOrNull{d ->
|
||||
|
|
@ -640,7 +640,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
existing.add(it)
|
||||
}else{
|
||||
if (it.id == 0L){
|
||||
val id = withContext(Dispatchers.IO){
|
||||
val id = runBlocking {
|
||||
repository.insert(it)
|
||||
}
|
||||
it.id = id
|
||||
|
|
@ -665,6 +665,13 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
}
|
||||
}
|
||||
|
||||
if (items.any { it.playlistTitle.isEmpty() }){
|
||||
items.forEachIndexed { index, it -> it.playlistTitle = "Various[${index+1}]" }
|
||||
withContext(Dispatchers.IO){
|
||||
dao.updateMultiple(items)
|
||||
}
|
||||
}
|
||||
|
||||
if (!useScheduler || alarmScheduler.isDuringTheScheduledTime() || items.any { it.downloadStartTime > 0L } ){
|
||||
startDownloadWorker(queuedItems)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class PauseDownloadNotificationReceiver : BroadcastReceiver() {
|
|||
CoroutineScope(Dispatchers.IO).launch{
|
||||
runCatching {
|
||||
val item = dbManager.downloadDao.getDownloadById(id.toLong())
|
||||
item.status = DownloadRepository.Status.Paused.toString()
|
||||
item.status = DownloadRepository.Status.ActivePaused.toString()
|
||||
dbManager.downloadDao.update(item)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.deniscerri.ytdlnis.receiver
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
|
|
@ -16,10 +17,16 @@ import android.util.Log
|
|||
import android.util.Patterns
|
||||
import android.view.WindowManager
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.IntentSanitizer
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
|
|
@ -34,6 +41,7 @@ import com.deniscerri.ytdlnis.ui.downloadcard.SelectPlaylistItemsDialog
|
|||
import com.deniscerri.ytdlnis.util.ThemeUtil
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.properties.Delegates
|
||||
|
|
@ -46,6 +54,7 @@ class ShareActivity : BaseActivity() {
|
|||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
private lateinit var cookieViewModel: CookieViewModel
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
private lateinit var navController: NavController
|
||||
private var quickDownload by Delegates.notNull<Boolean>()
|
||||
|
||||
|
||||
|
|
@ -83,6 +92,28 @@ class ShareActivity : BaseActivity() {
|
|||
handleIntents(intent)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
navController.addOnDestinationChangedListener(object: NavController.OnDestinationChangedListener{
|
||||
override fun onDestinationChanged(
|
||||
controller: NavController,
|
||||
destination: NavDestination,
|
||||
arguments: Bundle?
|
||||
) {
|
||||
if (navController.currentBackStack.value.isEmpty()) return
|
||||
navController.removeOnDestinationChangedListener(this)
|
||||
lifecycleScope.launch {
|
||||
navController.currentBackStack.collectLatest {
|
||||
if (it.isEmpty()){
|
||||
this@ShareActivity.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
handleIntents(intent)
|
||||
|
|
@ -91,6 +122,9 @@ class ShareActivity : BaseActivity() {
|
|||
private fun handleIntents(intent: Intent) {
|
||||
askPermissions()
|
||||
|
||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.frame_layout) as NavHostFragment
|
||||
navController = navHostFragment.findNavController()
|
||||
|
||||
val action = intent.action
|
||||
Log.e("aa", intent.toString())
|
||||
if (Intent.ACTION_SEND == action || Intent.ACTION_VIEW == action) {
|
||||
|
|
@ -129,10 +163,10 @@ class ShareActivity : BaseActivity() {
|
|||
}
|
||||
val downloadType = DownloadViewModel.Type.valueOf(type ?: downloadViewModel.getDownloadType(url = result.url).toString())
|
||||
if (sharedPreferences.getBoolean("download_card", true) && !background){
|
||||
val bottomSheet = DownloadBottomSheetDialog(
|
||||
result = result,
|
||||
type = downloadType)
|
||||
bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable("result", result)
|
||||
bundle.putSerializable("type", downloadType)
|
||||
navController.setGraph(R.navigation.share_nav_graph, bundle)
|
||||
}else{
|
||||
lifecycleScope.launch(Dispatchers.IO){
|
||||
val downloadItem = downloadViewModel.createDownloadItemFromResult(
|
||||
|
|
@ -152,32 +186,6 @@ class ShareActivity : BaseActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun showDownloadSheet(it: ResultItem){
|
||||
|
||||
}
|
||||
|
||||
private fun showSelectPlaylistItems(it: List<ResultItem?>){
|
||||
if (sharedPreferences.getBoolean("download_card", true)){
|
||||
val bottomSheet = SelectPlaylistItemsDialog(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
|
||||
bottomSheet.show(supportFragmentManager, "downloadPlaylistSheet")
|
||||
}else{
|
||||
lifecycleScope.launch(Dispatchers.IO){
|
||||
val downloadItems = mutableListOf<DownloadItem>()
|
||||
lifecycleScope.launch(Dispatchers.IO){
|
||||
it.forEach { res ->
|
||||
val i = downloadViewModel.createDownloadItemFromResult(
|
||||
result = res!!,
|
||||
givenType = DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
|
||||
i.format = downloadViewModel.getLatestCommandTemplateAsFormat()
|
||||
downloadItems.add(i)
|
||||
}
|
||||
downloadViewModel.queueDownloads(downloadItems)
|
||||
}
|
||||
}
|
||||
this.finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun askPermissions() {
|
||||
val permissions = arrayListOf<String>()
|
||||
if (!checkFilePermission()) {
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.forEach
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
|
@ -158,28 +160,30 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
recyclerView?.enableFastScroll()
|
||||
|
||||
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
|
||||
resultViewModel.items.observe(viewLifecycleOwner) {
|
||||
homeAdapter!!.submitList(it)
|
||||
resultsList = it
|
||||
if(resultViewModel.repository.itemCount.value > 1 || resultViewModel.repository.itemCount.value == -1){
|
||||
if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && !loadingItems){
|
||||
downloadAllFabCoordinator!!.visibility = VISIBLE
|
||||
resultViewModel.items.observe(requireActivity()) {
|
||||
kotlin.runCatching {
|
||||
homeAdapter!!.submitList(it)
|
||||
resultsList = it
|
||||
if(resultViewModel.repository.itemCount.value > 1 || resultViewModel.repository.itemCount.value == -1){
|
||||
if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && !loadingItems){
|
||||
downloadAllFabCoordinator!!.visibility = VISIBLE
|
||||
}else{
|
||||
downloadAllFabCoordinator!!.visibility = GONE
|
||||
}
|
||||
}else if (resultViewModel.repository.itemCount.value == 1){
|
||||
if (sharedPreferences!!.getBoolean("download_card", true)){
|
||||
if(it.size == 1 && quickLaunchSheet && parentFragmentManager.findFragmentByTag("downloadSingleSheet") == null){
|
||||
showSingleDownloadSheet(
|
||||
it[0],
|
||||
DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
|
||||
)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
downloadAllFabCoordinator!!.visibility = GONE
|
||||
}
|
||||
}else if (resultViewModel.repository.itemCount.value == 1){
|
||||
if (sharedPreferences!!.getBoolean("download_card", true)){
|
||||
if(it.size == 1 && quickLaunchSheet && parentFragmentManager.findFragmentByTag("downloadSingleSheet") == null){
|
||||
showSingleDownloadSheet(
|
||||
it[0],
|
||||
DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
|
||||
)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
downloadAllFabCoordinator!!.visibility = GONE
|
||||
quickLaunchSheet = true
|
||||
}
|
||||
quickLaunchSheet = true
|
||||
}
|
||||
|
||||
initMenu()
|
||||
|
|
@ -271,8 +275,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
ids?.forEach {
|
||||
items.add(downloadViewModel.getItemByID(it))
|
||||
}
|
||||
val bottomSheet = DownloadMultipleBottomSheetDialog(items.toMutableList())
|
||||
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
|
||||
findNavController().navigate(R.id.downloadMultipleBottomSheetDialog2, bundleOf(
|
||||
Pair("downloads", items)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -560,20 +565,18 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
if(sharedPreferences!!.getBoolean("quick_download", false) || sharedPreferences!!.getString("preferred_download_type", "video") == "command"){
|
||||
if (queryList.size == 1 && Patterns.WEB_URL.matcher(queryList.first()).matches()){
|
||||
if (sharedPreferences!!.getBoolean("download_card", true)) {
|
||||
showSingleDownloadSheet(
|
||||
resultItem = downloadViewModel.createEmptyResultItem(queryList.first()),
|
||||
type = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
|
||||
)
|
||||
} else {
|
||||
lifecycleScope.launch{
|
||||
val downloadItem = withContext(Dispatchers.IO){
|
||||
downloadViewModel.createDownloadItemFromResult(
|
||||
result = downloadViewModel.createEmptyResultItem(queryList.first()),
|
||||
givenType = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
|
||||
)
|
||||
}
|
||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
||||
withContext(Dispatchers.Main){
|
||||
showSingleDownloadSheet(
|
||||
resultItem = downloadViewModel.createEmptyResultItem(queryList.first()),
|
||||
type = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val downloadItem = downloadViewModel.createDownloadItemFromResult(
|
||||
result = downloadViewModel.createEmptyResultItem(queryList.first()),
|
||||
givenType = DownloadViewModel.Type.valueOf(sharedPreferences!!.getString("preferred_download_type", "video")!!)
|
||||
)
|
||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
||||
}
|
||||
|
||||
}else{
|
||||
|
|
@ -620,8 +623,13 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
resultItem: ResultItem,
|
||||
type: DownloadViewModel.Type
|
||||
){
|
||||
val bottomSheet = DownloadBottomSheetDialog(resultItem, downloadViewModel.getDownloadType(type, resultItem.url))
|
||||
bottomSheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
if(findNavController().currentBackStack.value.firstOrNull {it.destination.id == R.id.downloadBottomSheetDialog} == null){
|
||||
//show the fragment if its not in the backstack
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable("result", resultItem)
|
||||
bundle.putSerializable("type", downloadViewModel.getDownloadType(type, resultItem.url))
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundle)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCardClick(videoURL: String, add: Boolean) {
|
||||
|
|
@ -646,8 +654,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
|
||||
override fun onCardDetailsClick(videoURL: String) {
|
||||
if (parentFragmentManager.findFragmentByTag("resultDetails") == null && resultsList != null && resultsList!!.isNotEmpty()){
|
||||
val bottomSheet = ResultCardDetailsDialog(resultsList!!.first{it!!.url == videoURL}!!)
|
||||
bottomSheet.show(parentFragmentManager, "cutVideoSheet")
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable("result", resultsList!!.first{it!!.url == videoURL}!!)
|
||||
findNavController().navigate(R.id.resultCardDetailsDialog, bundle)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -662,8 +671,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
downloadViewModel.turnResultItemsToDownloadItems(resultsList!!)
|
||||
}
|
||||
if (sharedPreferences!!.getBoolean("download_card", true)) {
|
||||
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList.toMutableList())
|
||||
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
|
||||
findNavController().navigate(R.id.downloadMultipleBottomSheetDialog2, bundleOf(
|
||||
Pair("downloads", downloadList)
|
||||
))
|
||||
} else {
|
||||
downloadViewModel.queueDownloads(downloadList)
|
||||
}
|
||||
|
|
@ -723,8 +733,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
|||
}
|
||||
|
||||
if (sharedPreferences!!.getBoolean("download_card", true)) {
|
||||
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList.toMutableList())
|
||||
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
|
||||
findNavController().navigate(R.id.downloadMultipleBottomSheetDialog2, bundleOf(
|
||||
Pair("downloads", downloadList)
|
||||
))
|
||||
} else {
|
||||
downloadViewModel.queueDownloads(downloadList)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,25 +133,37 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
|
||||
cancelButton.setOnClickListener {onItemClickListener.onCancelClick(item.id)}
|
||||
|
||||
if (item.status == DownloadRepository.Status.Paused.toString()){
|
||||
progressBar.isIndeterminate = false
|
||||
pauseButton.icon = ContextCompat.getDrawable(activity, R.drawable.exomedia_ic_play_arrow_white)
|
||||
pauseButton.tag = ActiveDownloadAction.Resume
|
||||
cancelButton.visibility = View.VISIBLE
|
||||
}else{
|
||||
progressBar.isIndeterminate = true
|
||||
pauseButton.icon = ContextCompat.getDrawable(activity, R.drawable.exomedia_ic_pause_white)
|
||||
cancelButton.visibility = View.GONE
|
||||
pauseButton.tag = ActiveDownloadAction.Pause
|
||||
|
||||
when(DownloadRepository.Status.valueOf(item.status)){
|
||||
DownloadRepository.Status.Active -> {
|
||||
progressBar.isIndeterminate = true
|
||||
pauseButton.icon = ContextCompat.getDrawable(activity, R.drawable.exomedia_ic_pause_white)
|
||||
cancelButton.visibility = View.GONE
|
||||
pauseButton.isEnabled = true
|
||||
pauseButton.tag = ActiveDownloadAction.Pause
|
||||
}
|
||||
DownloadRepository.Status.ActivePaused -> {
|
||||
progressBar.isIndeterminate = false
|
||||
pauseButton.icon = ContextCompat.getDrawable(activity, R.drawable.exomedia_ic_play_arrow_white)
|
||||
pauseButton.tag = ActiveDownloadAction.Resume
|
||||
pauseButton.isEnabled = true
|
||||
cancelButton.visibility = View.VISIBLE
|
||||
}
|
||||
DownloadRepository.Status.PausedReQueued -> {
|
||||
progressBar.isIndeterminate = true
|
||||
pauseButton.icon = ContextCompat.getDrawable(activity, R.drawable.ic_refresh)
|
||||
pauseButton.tag = null
|
||||
pauseButton.isEnabled = false
|
||||
cancelButton.visibility = View.GONE
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
pauseButton.setOnClickListener {
|
||||
if (pauseButton.tag == ActiveDownloadAction.Pause){
|
||||
onItemClickListener.onPauseClick(item.id, ActiveDownloadAction.Pause, position)
|
||||
|
||||
}else{
|
||||
onItemClickListener.onPauseClick(item.id, ActiveDownloadAction.Resume, position)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class ActiveDownloadMinifiedAdapter(onItemClickListener: OnItemClickListener, ac
|
|||
if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
|
||||
cancelButton.setOnClickListener {onItemClickListener.onCancelClick(item.id)}
|
||||
|
||||
if (item.status == DownloadRepository.Status.Paused.toString()){
|
||||
if (item.status == DownloadRepository.Status.ActivePaused.toString()){
|
||||
progressBar.isIndeterminate = false
|
||||
pauseButton.icon = ContextCompat.getDrawable(activity, R.drawable.exomedia_ic_play_arrow_white)
|
||||
pauseButton.tag = ActiveDownloadAdapter.ActiveDownloadAction.Resume
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import android.app.Dialog
|
|||
import android.content.DialogInterface
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.text.format.DateFormat
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Patterns
|
||||
|
|
@ -17,13 +17,16 @@ import android.widget.Button
|
|||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
import com.deniscerri.ytdlnis.database.dao.CommandTemplateDao
|
||||
|
|
@ -44,14 +47,20 @@ import com.google.android.material.button.MaterialButton
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
class DownloadBottomSheetDialog(private var result: ResultItem, private val type: Type, private var currentDownloadItem: DownloadItem? = null) : BottomSheetDialogFragment() {
|
||||
class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||
private lateinit var tabLayout: TabLayout
|
||||
private lateinit var viewPager2: ViewPager2
|
||||
private lateinit var fragmentAdapter : DownloadFragmentAdapter
|
||||
|
|
@ -64,6 +73,18 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
private lateinit var sharedPreferences : SharedPreferences
|
||||
private lateinit var updateItem : Button
|
||||
private lateinit var view: View
|
||||
private lateinit var shimmerLoading :ShimmerFrameLayout
|
||||
private lateinit var title : View
|
||||
private lateinit var shimmerLoadingSubtitle : ShimmerFrameLayout
|
||||
private lateinit var subtitle : View
|
||||
|
||||
private var updateJob : Job? = null
|
||||
private var updateFormatsJob : Job? = null
|
||||
|
||||
|
||||
private lateinit var result: ResultItem
|
||||
private lateinit var type: Type
|
||||
private var currentDownloadItem: DownloadItem? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -81,6 +102,26 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
view = LayoutInflater.from(context).inflate(R.layout.download_bottom_sheet, null)
|
||||
dialog.setContentView(view)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 33){
|
||||
arguments?.getParcelable("result", ResultItem::class.java)
|
||||
}else{
|
||||
arguments?.getParcelable<ResultItem>("result")
|
||||
}.apply {
|
||||
if (this == null){
|
||||
dismiss()
|
||||
return
|
||||
}else{
|
||||
result = this
|
||||
}
|
||||
}
|
||||
|
||||
type = arguments?.getSerializable("type") as Type
|
||||
currentDownloadItem = if (Build.VERSION.SDK_INT >= 33){
|
||||
arguments?.getParcelable("downloadItem", DownloadItem::class.java)
|
||||
}else{
|
||||
arguments?.getParcelable<DownloadItem>("downloadItem")
|
||||
}
|
||||
|
||||
dialog.setOnShowListener {
|
||||
behavior = BottomSheetBehavior.from(view.parent as View)
|
||||
val displayMetrics = DisplayMetrics()
|
||||
|
|
@ -95,6 +136,13 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
viewPager2 = view.findViewById(R.id.download_viewpager)
|
||||
updateItem = view.findViewById(R.id.update_item)
|
||||
|
||||
|
||||
//loading shimmers
|
||||
shimmerLoading = view.findViewById(R.id.shimmer_loading_title)
|
||||
title = view.findViewById(R.id.bottom_sheet_title)
|
||||
shimmerLoadingSubtitle = view.findViewById(R.id.shimmer_loading_subtitle)
|
||||
subtitle = view.findViewById(R.id.bottom_sheet_subtitle)
|
||||
|
||||
(viewPager2.getChildAt(0) as? RecyclerView)?.apply {
|
||||
isNestedScrollingEnabled = false
|
||||
overScrollMode = View.OVER_SCROLL_NEVER
|
||||
|
|
@ -224,6 +272,8 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
|
||||
scheduleBtn.setOnClickListener{
|
||||
UiUtil.showDatePicker(fragmentManager) {
|
||||
updateJob?.cancel()
|
||||
updateFormatsJob?.cancel()
|
||||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
val item: DownloadItem = getDownloadItem()
|
||||
|
|
@ -237,6 +287,8 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
}
|
||||
}
|
||||
download!!.setOnClickListener {
|
||||
updateJob?.cancel()
|
||||
updateFormatsJob?.cancel()
|
||||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
val item: DownloadItem = getDownloadItem()
|
||||
|
|
@ -285,7 +337,7 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
(updateItem.parent as LinearLayout).visibility = View.VISIBLE
|
||||
updateItem.setOnClickListener {
|
||||
(updateItem.parent as LinearLayout).visibility = View.GONE
|
||||
initUpdateData(view)
|
||||
initUpdateData()
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
|
@ -300,7 +352,7 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
|
||||
//update in the background if there is no data
|
||||
if(result.title.isEmpty() && currentDownloadItem == null && !sharedPreferences.getBoolean("quick_download", false) && type != Type.command){
|
||||
initUpdateData(view)
|
||||
initUpdateData()
|
||||
}else {
|
||||
val usingGenericFormatsOrEmpty = result.formats.isEmpty() || result.formats.any { it.format_note.contains("ytdlnisgeneric") }
|
||||
if (usingGenericFormatsOrEmpty && sharedPreferences.getBoolean("update_formats", false) && !sharedPreferences.getBoolean("quick_download", false)){
|
||||
|
|
@ -377,48 +429,83 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
}
|
||||
}
|
||||
|
||||
private fun initUpdateData(v: View){
|
||||
val shimmerLoading = v.findViewById<ShimmerFrameLayout>(R.id.shimmer_loading_title)
|
||||
val title = v.findViewById<View>(R.id.bottom_sheet_title)
|
||||
val shimmerLoadingSubtitle = v.findViewById<ShimmerFrameLayout>(R.id.shimmer_loading_subtitle)
|
||||
val subtitle = v.findViewById<View>(R.id.bottom_sheet_subtitle)
|
||||
|
||||
val updateJob = CoroutineScope(SupervisorJob()).launch(Dispatchers.IO){
|
||||
withContext(Dispatchers.Main){
|
||||
title.visibility = View.GONE
|
||||
subtitle.visibility = View.GONE
|
||||
shimmerLoading.visibility = View.VISIBLE
|
||||
shimmerLoadingSubtitle.visibility = View.VISIBLE
|
||||
shimmerLoading.startShimmer()
|
||||
shimmerLoadingSubtitle.startShimmer()
|
||||
}
|
||||
|
||||
|
||||
if (result.url.isBlank()){
|
||||
withContext(Dispatchers.Main){dismiss()}
|
||||
return@launch
|
||||
}
|
||||
|
||||
val result = resultViewModel.parseQueries(listOf(result.url))
|
||||
if (result.isEmpty()){
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (result.size == 1 && result[0] != null){
|
||||
fragmentAdapter.setResultItem(result[0]!!)
|
||||
private fun initUpdateData() {
|
||||
updateJob = CoroutineScope(SupervisorJob()).launch(Dispatchers.IO){
|
||||
findNavController().saveState()
|
||||
kotlin.runCatching {
|
||||
withContext(Dispatchers.Main){
|
||||
runCatching {
|
||||
val f = fragmentManager?.findFragmentByTag("f0") as DownloadAudioFragment
|
||||
f.updateUI(result[0])
|
||||
}
|
||||
|
||||
runCatching {
|
||||
val f1 = fragmentManager?.findFragmentByTag("f1") as DownloadVideoFragment
|
||||
f1.updateUI(result[0])
|
||||
}
|
||||
title.visibility = View.GONE
|
||||
subtitle.visibility = View.GONE
|
||||
shimmerLoading.visibility = View.VISIBLE
|
||||
shimmerLoadingSubtitle.visibility = View.VISIBLE
|
||||
shimmerLoading.startShimmer()
|
||||
shimmerLoadingSubtitle.startShimmer()
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main){
|
||||
if (result.url.isBlank()){
|
||||
withContext(Dispatchers.Main){dismiss()}
|
||||
return@launch
|
||||
}
|
||||
|
||||
val result = resultViewModel.parseQueries(listOf(result.url))
|
||||
if (result.isEmpty()){
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (result.size == 1 && result[0] != null){
|
||||
fragmentAdapter.setResultItem(result[0]!!)
|
||||
withContext(Dispatchers.Main){
|
||||
runCatching {
|
||||
val f = fragmentManager?.findFragmentByTag("f0") as DownloadAudioFragment
|
||||
f.updateUI(result[0])
|
||||
}
|
||||
|
||||
runCatching {
|
||||
val f1 = fragmentManager?.findFragmentByTag("f1") as DownloadVideoFragment
|
||||
f1.updateUI(result[0])
|
||||
}
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main){
|
||||
title.visibility = View.VISIBLE
|
||||
subtitle.visibility = View.VISIBLE
|
||||
shimmerLoading.visibility = View.GONE
|
||||
shimmerLoadingSubtitle.visibility = View.GONE
|
||||
shimmerLoading.stopShimmer()
|
||||
shimmerLoadingSubtitle.stopShimmer()
|
||||
}
|
||||
|
||||
val usingGenericFormatsOrEmpty = result[0]!!.formats.isEmpty() || result[0]!!.formats.any { it.format_note.contains("ytdlnisgeneric") }
|
||||
|
||||
if (usingGenericFormatsOrEmpty && sharedPreferences.getBoolean("update_formats", false)){
|
||||
initUpdateFormats(result[0]!!.url)
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
//open multi download card instead
|
||||
if (activity is ShareActivity){
|
||||
val preferredType = DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!)
|
||||
withContext(Dispatchers.Main){
|
||||
findNavController().navigate(R.id.action_downloadBottomSheetDialog_to_selectPlaylistItemsDialog, bundleOf(
|
||||
Pair("results", result),
|
||||
Pair("type", preferredType),
|
||||
))
|
||||
}
|
||||
}else{
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shimmerLoading.setOnClickListener {
|
||||
updateJob?.cancel()
|
||||
(updateItem.parent as LinearLayout).visibility = View.VISIBLE
|
||||
}
|
||||
updateJob?.invokeOnCompletion {
|
||||
kotlin.runCatching {
|
||||
requireActivity().runOnUiThread {
|
||||
title.visibility = View.VISIBLE
|
||||
subtitle.visibility = View.VISIBLE
|
||||
shimmerLoading.visibility = View.GONE
|
||||
|
|
@ -426,48 +513,13 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
shimmerLoading.stopShimmer()
|
||||
shimmerLoadingSubtitle.stopShimmer()
|
||||
}
|
||||
|
||||
val usingGenericFormatsOrEmpty = result[0]!!.formats.isEmpty() || result[0]!!.formats.any { it.format_note.contains("ytdlnisgeneric") }
|
||||
|
||||
if (usingGenericFormatsOrEmpty && sharedPreferences.getBoolean("update_formats", false)){
|
||||
initUpdateFormats(result[0]!!.url)
|
||||
}
|
||||
|
||||
}else{
|
||||
//open multi download card instead
|
||||
if (activity is ShareActivity){
|
||||
val preferredType = DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!)
|
||||
withContext(Dispatchers.Main){
|
||||
val playlistSelect = SelectPlaylistItemsDialog(items = result, type = preferredType)
|
||||
parentFragmentManager.addFragmentOnAttachListener { fragmentManager, fragment ->
|
||||
dismiss()
|
||||
}
|
||||
playlistSelect.show(parentFragmentManager, "downloadPlaylistSheet")
|
||||
}
|
||||
}else{
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
shimmerLoading.setOnClickListener {
|
||||
updateJob.cancel()
|
||||
(updateItem.parent as LinearLayout).visibility = View.VISIBLE
|
||||
}
|
||||
updateJob.invokeOnCompletion {
|
||||
requireActivity().runOnUiThread {
|
||||
title.visibility = View.VISIBLE
|
||||
subtitle.visibility = View.VISIBLE
|
||||
shimmerLoading.visibility = View.GONE
|
||||
shimmerLoadingSubtitle.visibility = View.GONE
|
||||
shimmerLoading.stopShimmer()
|
||||
shimmerLoadingSubtitle.stopShimmer()
|
||||
}
|
||||
}
|
||||
updateJob.start()
|
||||
updateJob?.start()
|
||||
}
|
||||
|
||||
private fun initUpdateFormats(url: String){
|
||||
CoroutineScope(SupervisorJob()).launch(Dispatchers.IO) {
|
||||
updateFormatsJob = CoroutineScope(SupervisorJob()).launch(Dispatchers.IO) {
|
||||
withContext(Dispatchers.Main){
|
||||
runCatching {
|
||||
val f1 = fragmentManager?.findFragmentByTag("f0") as DownloadAudioFragment
|
||||
|
|
@ -510,25 +562,7 @@ class DownloadBottomSheetDialog(private var result: ResultItem, private val type
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
cleanUp()
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
cleanUp()
|
||||
}
|
||||
|
||||
|
||||
private fun cleanUp(){
|
||||
kotlin.runCatching {
|
||||
if (activity is ShareActivity && !parentFragmentManager.fragments.map { it.tag }.contains("downloadPlaylistSheet")){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
updateFormatsJob?.start()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import android.content.SharedPreferences
|
|||
import android.content.res.Configuration
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.format.DateFormat
|
||||
import android.util.DisplayMetrics
|
||||
|
|
@ -37,6 +38,7 @@ import com.deniscerri.ytdlnis.R
|
|||
import com.deniscerri.ytdlnis.ui.adapter.ConfigureMultipleDownloadsAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
|
|
@ -66,7 +68,7 @@ import kotlinx.coroutines.withContext
|
|||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener,
|
||||
class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener,
|
||||
ConfigureDownloadBottomSheetDialog.OnDownloadItemUpdateListener {
|
||||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
private lateinit var historyViewModel: HistoryViewModel
|
||||
|
|
@ -80,6 +82,8 @@ class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadI
|
|||
private lateinit var filesize : TextView
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
private lateinit var items: MutableList<DownloadItem>
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -97,6 +101,19 @@ class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadI
|
|||
val view = LayoutInflater.from(context).inflate(R.layout.download_multiple_bottom_sheet, null)
|
||||
dialog.setContentView(view)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 33){
|
||||
arguments?.getParcelableArrayList("downloads", DownloadItem::class.java)
|
||||
}else{
|
||||
arguments?.getParcelableArrayList<DownloadItem>("downloads")
|
||||
}.apply {
|
||||
if (this == null){
|
||||
dismiss()
|
||||
return
|
||||
}else{
|
||||
items = this
|
||||
}
|
||||
}
|
||||
|
||||
if (items.isEmpty()) dismiss()
|
||||
|
||||
dialog.setOnShowListener {
|
||||
|
|
@ -138,10 +155,7 @@ class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadI
|
|||
item.downloadStartTime = it.timeInMillis
|
||||
}
|
||||
runBlocking {
|
||||
val chunks = items.chunked(10)
|
||||
for (c in chunks) {
|
||||
downloadViewModel.queueDownloads(c)
|
||||
}
|
||||
downloadViewModel.queueDownloads(items)
|
||||
val first = items.first()
|
||||
val date = SimpleDateFormat(DateFormat.getBestDateTimePattern(Locale.getDefault(), "ddMMMyyyy - HHmm"), Locale.getDefault()).format(first.downloadStartTime)
|
||||
Toast.makeText(context, getString(R.string.download_rescheduled_to) + " " + date, Toast.LENGTH_LONG).show()
|
||||
|
|
@ -154,11 +168,7 @@ class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadI
|
|||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
runBlocking {
|
||||
val chunks = items.chunked(10)
|
||||
for (c in chunks) {
|
||||
downloadViewModel.queueDownloads(c)
|
||||
}
|
||||
|
||||
downloadViewModel.queueDownloads(items)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
|
|
@ -559,24 +569,6 @@ class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadI
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
cleanup()
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
cleanup()
|
||||
}
|
||||
|
||||
private fun cleanup(){
|
||||
kotlin.runCatching {
|
||||
if (activity is ShareActivity){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onButtonClick(itemURL: String) {
|
||||
lifecycleScope.launch {
|
||||
val item = items.find { it.url == itemURL } ?: return@launch
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import android.content.res.Configuration
|
|||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.text.format.DateFormat
|
||||
|
|
@ -70,7 +71,7 @@ import java.text.SimpleDateFormat
|
|||
import java.util.*
|
||||
|
||||
|
||||
class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogFragment(), GenericDownloadAdapter.OnItemClickListener, ActiveDownloadMinifiedAdapter.OnItemClickListener {
|
||||
class ResultCardDetailsDialog : BottomSheetDialogFragment(), GenericDownloadAdapter.OnItemClickListener, ActiveDownloadMinifiedAdapter.OnItemClickListener {
|
||||
private lateinit var infoUtil: InfoUtil
|
||||
private lateinit var notificationUtil: NotificationUtil
|
||||
private lateinit var videoView: PlayerView
|
||||
|
|
@ -85,6 +86,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
private lateinit var dialogView : View
|
||||
private lateinit var item: ResultItem
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -136,6 +138,19 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val i = if (Build.VERSION.SDK_INT >= 33){
|
||||
arguments?.getParcelable("result", ResultItem::class.java)
|
||||
}else{
|
||||
arguments?.getParcelable<ResultItem>("result")
|
||||
}
|
||||
|
||||
if (i == null) {
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
|
||||
item = i
|
||||
|
||||
//remove outdated player url of 1hr so it can refetch it in the player
|
||||
if (item.creationTime > System.currentTimeMillis() - 3600000) item.urls = ""
|
||||
|
||||
|
|
@ -293,10 +308,12 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
}
|
||||
|
||||
private fun onButtonClick(type: DownloadViewModel.Type){
|
||||
this.dismiss()
|
||||
if (sharedPreferences.getBoolean("download_card", true)) {
|
||||
val bottomSheet = DownloadBottomSheetDialog(item, type)
|
||||
bottomSheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable("result", item)
|
||||
bundle.putSerializable("type", type)
|
||||
findNavController().navigateUp()
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundle)
|
||||
} else {
|
||||
lifecycleScope.launch{
|
||||
val downloadItem = withContext(Dispatchers.IO){
|
||||
|
|
@ -305,6 +322,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
givenType = type)
|
||||
}
|
||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,7 +342,6 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
kotlin.runCatching {
|
||||
videoView.player?.stop()
|
||||
videoView.player?.release()
|
||||
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("resultDetails")!!).commit()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -582,7 +599,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
ActiveDownloadAdapter.ActiveDownloadAction.Pause -> {
|
||||
lifecycleScope.launch {
|
||||
cancelItem(itemID.toInt())
|
||||
item.status = DownloadRepository.Status.Paused.toString()
|
||||
item.status = DownloadRepository.Status.ActivePaused.toString()
|
||||
withContext(Dispatchers.IO){
|
||||
downloadViewModel.updateDownload(item)
|
||||
}
|
||||
|
|
@ -591,7 +608,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
|
|||
}
|
||||
ActiveDownloadAdapter.ActiveDownloadAction.Resume -> {
|
||||
lifecycleScope.launch {
|
||||
item.status = DownloadRepository.Status.Active.toString()
|
||||
item.status = DownloadRepository.Status.PausedReQueued.toString()
|
||||
withContext(Dispatchers.IO){
|
||||
downloadViewModel.updateDownload(item)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,19 @@ package com.deniscerri.ytdlnis.ui.downloadcard
|
|||
import android.app.ActionBar.LayoutParams
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
|
|
@ -30,8 +33,9 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu
|
|||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class SelectPlaylistItemsDialog(private val items: List<ResultItem?>, private val type: DownloadViewModel.Type) : DialogFragment(), PlaylistAdapter.OnItemClickListener {
|
||||
class SelectPlaylistItemsDialog : DialogFragment(), PlaylistAdapter.OnItemClickListener {
|
||||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
private lateinit var resultViewModel: ResultViewModel
|
||||
private lateinit var listAdapter : PlaylistAdapter
|
||||
|
|
@ -41,6 +45,10 @@ class SelectPlaylistItemsDialog(private val items: List<ResultItem?>, private va
|
|||
private lateinit var fromTextInput: TextInputLayout
|
||||
private lateinit var toTextInput: TextInputLayout
|
||||
|
||||
|
||||
private lateinit var items: List<ResultItem?>
|
||||
private lateinit var type: DownloadViewModel.Type
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(STYLE_NORMAL, R.style.FullScreenDialogTheme)
|
||||
|
|
@ -65,6 +73,21 @@ class SelectPlaylistItemsDialog(private val items: List<ResultItem?>, private va
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 33){
|
||||
arguments?.getParcelableArrayList("results", ResultItem::class.java)
|
||||
}else{
|
||||
arguments?.getParcelableArrayList<ResultItem>("results")
|
||||
}.apply {
|
||||
if (this == null){
|
||||
dismiss()
|
||||
return
|
||||
}else{
|
||||
items = this
|
||||
}
|
||||
}
|
||||
type = arguments?.getSerializable("type") as DownloadViewModel.Type
|
||||
|
||||
|
||||
dialog?.window?.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
||||
|
||||
toolbar = view.findViewById<MaterialToolbar>(R.id.toolbar)
|
||||
|
|
@ -156,11 +179,12 @@ class SelectPlaylistItemsDialog(private val items: List<ResultItem?>, private va
|
|||
val checkedResultItems = items.filter { item -> checkedItems.contains(item!!.url) }
|
||||
if (checkedResultItems.size == 1){
|
||||
val resultItem = resultViewModel.getItemByURL(checkedResultItems[0]!!.url)
|
||||
val bottomSheet = DownloadBottomSheetDialog(resultItem, type)
|
||||
parentFragmentManager.addFragmentOnAttachListener { fragmentManager, fragment ->
|
||||
dismiss()
|
||||
withContext(Dispatchers.Main){
|
||||
findNavController().navigate(R.id.action_selectPlaylistItemsDialog_to_downloadBottomSheetDialog, bundleOf(
|
||||
Pair("result", resultItem),
|
||||
Pair("type", downloadViewModel.getDownloadType(type, resultItem.url)),
|
||||
))
|
||||
}
|
||||
bottomSheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
}else{
|
||||
val downloadItems = mutableListOf<DownloadItem>()
|
||||
checkedResultItems.forEach { c ->
|
||||
|
|
@ -173,11 +197,11 @@ class SelectPlaylistItemsDialog(private val items: List<ResultItem?>, private va
|
|||
downloadItems.add(i)
|
||||
}
|
||||
|
||||
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadItems)
|
||||
parentFragmentManager.addFragmentOnAttachListener { fragmentManager, fragment ->
|
||||
dismiss()
|
||||
withContext(Dispatchers.Main){
|
||||
findNavController().navigate(R.id.action_selectPlaylistItemsDialog_to_downloadMultipleBottomSheetDialog, bundleOf(
|
||||
Pair("downloads", downloadItems)
|
||||
))
|
||||
}
|
||||
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
|
||||
}
|
||||
|
||||
dismiss()
|
||||
|
|
@ -210,25 +234,6 @@ class SelectPlaylistItemsDialog(private val items: List<ResultItem?>, private va
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
cleanup()
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
cleanup()
|
||||
}
|
||||
|
||||
private fun cleanup(){
|
||||
kotlin.runCatching {
|
||||
val movedToMultipleOrSingleSheet = parentFragmentManager.fragments.map { it.tag }.contains("downloadMultipleSheet") || parentFragmentManager.fragments.map { it.tag }.contains("downloadSingleSheet")
|
||||
if (activity is ShareActivity && !movedToMultipleOrSingleSheet){
|
||||
(activity as ShareActivity).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRanges(start: String, end: String) : Boolean {
|
||||
return start.isNotBlank() && end.isNotBlank()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
|
|||
downloadViewModel.getActiveDownloads()
|
||||
}.forEach {
|
||||
cancelItem(it.id.toInt())
|
||||
it.status = DownloadRepository.Status.Paused.toString()
|
||||
it.status = DownloadRepository.Status.ActivePaused.toString()
|
||||
downloadViewModel.updateDownload(it)
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
|
|||
downloadViewModel.getActiveDownloads()
|
||||
}
|
||||
|
||||
val toQueue = active.filter { it.status == DownloadRepository.Status.Paused.toString() }.toMutableList()
|
||||
val toQueue = active.filter { it.status == DownloadRepository.Status.ActivePaused.toString() }.toMutableList()
|
||||
toQueue.forEach {
|
||||
it.status = DownloadRepository.Status.Queued.toString()
|
||||
downloadViewModel.updateDownload(it)
|
||||
|
|
@ -162,7 +162,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
|
|||
|
||||
if (it.size > 1){
|
||||
pauseResume.visibility = View.VISIBLE
|
||||
if (it.all { l -> l.status == DownloadRepository.Status.Paused.toString() }){
|
||||
if (it.all { l -> l.status == DownloadRepository.Status.ActivePaused.toString() }){
|
||||
pauseResume.text = requireContext().getString(R.string.resume)
|
||||
}else{
|
||||
pauseResume.text = requireContext().getString(R.string.pause)
|
||||
|
|
@ -208,7 +208,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
|
|||
ActiveDownloadAdapter.ActiveDownloadAction.Pause -> {
|
||||
lifecycleScope.launch {
|
||||
cancelItem(itemID.toInt())
|
||||
item.status = DownloadRepository.Status.Paused.toString()
|
||||
item.status = DownloadRepository.Status.ActivePaused.toString()
|
||||
withContext(Dispatchers.IO){
|
||||
downloadViewModel.updateDownload(item)
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
|
|||
}
|
||||
ActiveDownloadAdapter.ActiveDownloadAction.Resume -> {
|
||||
lifecycleScope.launch {
|
||||
item.status = DownloadRepository.Status.Active.toString()
|
||||
item.status = DownloadRepository.Status.PausedReQueued.toString()
|
||||
withContext(Dispatchers.IO){
|
||||
downloadViewModel.updateDownload(item)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@ import android.widget.RelativeLayout
|
|||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
|
|
@ -131,12 +133,12 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
|||
}
|
||||
},
|
||||
longClickDownloadButton = {
|
||||
val sheet = DownloadBottomSheetDialog(
|
||||
currentDownloadItem = it,
|
||||
result = downloadViewModel.createResultItemFromDownload(it),
|
||||
type = it.type
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||
Pair("downloadItem", it),
|
||||
Pair("result", downloadViewModel.createResultItemFromDownload(it)),
|
||||
Pair("type", it.type)
|
||||
)
|
||||
)
|
||||
sheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
},
|
||||
scheduleButtonClick = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import android.widget.Toast
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import androidx.work.WorkManager
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import android.widget.AdapterView.OnItemClickListener
|
|||
import android.widget.RelativeLayout
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
|
@ -134,12 +135,11 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
}
|
||||
},
|
||||
longClickDownloadButton = {
|
||||
val sheet = DownloadBottomSheetDialog(
|
||||
currentDownloadItem = it,
|
||||
result = downloadViewModel.createResultItemFromDownload(it),
|
||||
type = it.type
|
||||
)
|
||||
sheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||
Pair("downloadItem", it),
|
||||
Pair("result", downloadViewModel.createResultItemFromDownload(it)),
|
||||
Pair("type", it.type)
|
||||
))
|
||||
},
|
||||
scheduleButtonClick = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.forEach
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
|
@ -411,11 +412,10 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
historyViewModel.delete(it, false)
|
||||
},
|
||||
redownloadShowDownloadCard = {
|
||||
val sheet = DownloadBottomSheetDialog(
|
||||
result = downloadViewModel.createResultItemFromHistory(it),
|
||||
type = it.type
|
||||
)
|
||||
sheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||
Pair("result", downloadViewModel.createResultItemFromHistory(it)),
|
||||
Pair("type", it.type),
|
||||
))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -547,10 +547,10 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
ItemTouchHelper.RIGHT -> {
|
||||
val item = historyList!![position]!!
|
||||
historyAdapter!!.notifyItemChanged(position)
|
||||
val sheet = DownloadBottomSheetDialog(type = item.type,
|
||||
result = downloadViewModel.createResultItemFromHistory(item)
|
||||
)
|
||||
sheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||
Pair("result", downloadViewModel.createResultItemFromHistory(item)),
|
||||
Pair("type", item.type)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@ import android.widget.TextView
|
|||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
|
|
@ -154,12 +156,11 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
|
|||
}
|
||||
},
|
||||
longClickDownloadButton = {
|
||||
val sheet = DownloadBottomSheetDialog(
|
||||
currentDownloadItem = it,
|
||||
result = downloadViewModel.createResultItemFromDownload(it),
|
||||
type = it.type
|
||||
)
|
||||
sheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||
Pair("downloadItem", it),
|
||||
Pair("result", downloadViewModel.createResultItemFromDownload(it)),
|
||||
Pair("type", it.type)
|
||||
))
|
||||
},
|
||||
scheduleButtonClick = {downloadItem ->
|
||||
UiUtil.showDatePicker(parentFragmentManager) {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@ import android.widget.RelativeLayout
|
|||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
|
|
@ -131,12 +133,11 @@ class SavedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLis
|
|||
}
|
||||
},
|
||||
longClickDownloadButton = { it: DownloadItem ->
|
||||
val sheet = DownloadBottomSheetDialog(
|
||||
currentDownloadItem = it,
|
||||
result = downloadViewModel.createResultItemFromDownload(it),
|
||||
type = it.type
|
||||
)
|
||||
sheet.show(parentFragmentManager, "downloadSingleSheet")
|
||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||
Pair("downloadItem", it),
|
||||
Pair("result", downloadViewModel.createResultItemFromDownload(it)),
|
||||
Pair("type", it.type),
|
||||
))
|
||||
},
|
||||
scheduleButtonClick = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ class DownloadLogFragment : Fragment() {
|
|||
}
|
||||
|
||||
content = view.findViewById(R.id.content)
|
||||
content.movementMethod = ScrollingMovementMethod()
|
||||
content.setTextIsSelectable(true)
|
||||
contentScrollView = view.findViewById(R.id.content_scrollview)
|
||||
val bottomAppBar = view.findViewById<BottomAppBar>(R.id.bottomAppBar)
|
||||
|
|
@ -89,7 +88,7 @@ class DownloadLogFragment : Fragment() {
|
|||
}
|
||||
|
||||
val id = arguments?.getLong("logID")
|
||||
if (id == null) {
|
||||
if (id == null || id == 0L) {
|
||||
mainActivity.onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
|
||||
|
|
@ -155,19 +154,11 @@ class DownloadLogFragment : Fragment() {
|
|||
true
|
||||
}
|
||||
|
||||
// contentScrollView.setOnScrollChangeListener { view, sx, sy, osx, osy ->
|
||||
// if (sy < osy){
|
||||
// if (contentScrollView.canScrollVertically(1)){
|
||||
// shouldScroll = false
|
||||
// content.movementMethod = LinkMovementMethod.getInstance()
|
||||
// bottomAppBar?.menu?.get(1)?.isVisible = true
|
||||
// }else{
|
||||
// shouldScroll = true
|
||||
// content.movementMethod = ScrollingMovementMethod()
|
||||
// bottomAppBar?.menu?.get(1)?.isVisible = false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
contentScrollView.setOnScrollChangeListener { view, sx, sy, osx, osy ->
|
||||
if (sy < osy){
|
||||
bottomAppBar?.menu?.get(1)?.isVisible = contentScrollView.canScrollVertically(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logViewModel.getLogFlowByID(id!!).observe(viewLifecycleOwner){logItem ->
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class NotificationUtil(var context: Context) {
|
|||
val importance = NotificationManager.IMPORTANCE_LOW
|
||||
var channel = NotificationChannel(DOWNLOAD_WORKER_CHANNEL_ID, name, importance)
|
||||
channel.description = description
|
||||
channel.setSound(null, null)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
|
||||
//gui downloads
|
||||
|
|
|
|||
|
|
@ -611,7 +611,7 @@ object UiUtil {
|
|||
|
||||
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
|
||||
View.GONE
|
||||
else formatNote!!.text = item.format.format_note.uppercase()
|
||||
else formatNote!!.text = item.format.format_note
|
||||
|
||||
if (item.format.container != "") {
|
||||
container!!.text = if (file.exists()) file.extension.uppercase() else item.format.container.uppercase()
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ import com.yausername.youtubedl_android.YoutubeDL.UpdateStatus
|
|||
import io.noties.markwon.AbstractMarkwonPlugin
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.MarkwonConfiguration
|
||||
import io.noties.markwon.MarkwonSpansFactory
|
||||
import io.noties.markwon.core.MarkwonTheme
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
|
@ -94,7 +92,7 @@ class UpdateUtil(var context: Context) {
|
|||
.setTitle(v.tag_name)
|
||||
.setMessage(v.body)
|
||||
.setIcon(R.drawable.ic_update_app)
|
||||
.setNeutralButton(R.string.skip){ d: DialogInterface?, _:Int ->
|
||||
.setNeutralButton(R.string.ignore){ d: DialogInterface?, _:Int ->
|
||||
skippedVersions.add(v.tag_name)
|
||||
sharedPreferences.edit().putString("skip_updates", skippedVersions.joinToString(",")).apply()
|
||||
d?.dismiss()
|
||||
|
|
|
|||
|
|
@ -259,7 +259,10 @@ class DownloadWorker(
|
|||
}else{
|
||||
logString.append("${it.message}\n")
|
||||
logItem.content = logString.toString()
|
||||
logRepo.insert(logItem)
|
||||
val logID = withContext(Dispatchers.IO){
|
||||
logRepo.insert(logItem)
|
||||
}
|
||||
downloadItem.logID = logID
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -277,8 +280,8 @@ class DownloadWorker(
|
|||
}
|
||||
|
||||
notificationUtil.createDownloadErrored(
|
||||
downloadItem.title, it.message,
|
||||
if (logDownloads) logItem.id else null,
|
||||
downloadItem.title.ifEmpty { downloadItem.url }, it.message,
|
||||
downloadItem.logID,
|
||||
NotificationUtil.DOWNLOAD_FINISHED_CHANNEL_ID
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,15 @@ class TerminalDownloadWorker(
|
|||
}
|
||||
}
|
||||
|
||||
request.addOption("-P", FileUtil.getDefaultCommandPath() + "/" + itemId)
|
||||
val commandPath = sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!!
|
||||
val noCache = !sharedPreferences.getBoolean("cache_downloads", true) && File(FileUtil.formatPath(commandPath)).canWrite()
|
||||
|
||||
if (!noCache){
|
||||
request.addOption("-P", FileUtil.getCachePath(context) + "/TERMINAL/" + itemId)
|
||||
}else if (!request.hasOption("-P")){
|
||||
request.addOption("-P", FileUtil.formatPath(commandPath))
|
||||
}
|
||||
|
||||
|
||||
val logDownloads = sharedPreferences.getBoolean("log_downloads", false) && !sharedPreferences.getBoolean("incognito", false)
|
||||
|
||||
|
|
@ -120,16 +128,18 @@ class TerminalDownloadWorker(
|
|||
}
|
||||
}.onSuccess {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
//move file from internal to set download directory
|
||||
try {
|
||||
FileUtil.moveFile(File(FileUtil.getDefaultCommandPath() + "/" + itemId),context, downloadLocation!!, false){ p ->
|
||||
setProgressAsync(workDataOf("progress" to p))
|
||||
if(!noCache){
|
||||
//move file from internal to set download directory
|
||||
try {
|
||||
FileUtil.moveFile(File(FileUtil.getCachePath(context) + "/TERMINAL/" + itemId),context, downloadLocation!!, false){ p ->
|
||||
setProgressAsync(workDataOf("progress" to p))
|
||||
}
|
||||
}catch (e: Exception){
|
||||
e.printStackTrace()
|
||||
handler.postDelayed({
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
}, 1000)
|
||||
}
|
||||
}catch (e: Exception){
|
||||
e.printStackTrace()
|
||||
handler.postDelayed({
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".receiver.ShareActivity"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/frame_layout"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -27,6 +27,12 @@
|
|||
<action
|
||||
android:id="@+id/action_homeFragment_to_resultCardDetailsDialog"
|
||||
app:destination="@id/resultCardDetailsDialog" />
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_downloadBottomSheetDialog"
|
||||
app:destination="@id/downloadBottomSheetDialog" />
|
||||
<action
|
||||
android:id="@+id/action_homeFragment_to_downloadMultipleBottomSheetDialog2"
|
||||
app:destination="@id/downloadMultipleBottomSheetDialog2" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/historyFragment"
|
||||
|
|
@ -96,7 +102,7 @@
|
|||
android:id="@+id/downloadLogFragment"
|
||||
android:name="com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogFragment"
|
||||
android:label="DownloadLogFragment" />
|
||||
<fragment
|
||||
<dialog
|
||||
android:id="@+id/resultCardDetailsDialog"
|
||||
android:name="com.deniscerri.ytdlnis.ui.downloadcard.ResultCardDetailsDialog"
|
||||
android:label="ResultCardDetailsDialog" />
|
||||
|
|
@ -142,4 +148,12 @@
|
|||
android:name="com.deniscerri.ytdlnis.ui.more.settings.GeneralSettingsFragment"
|
||||
android:label="AppearanceSettingsFragment" />
|
||||
</navigation>
|
||||
<dialog
|
||||
android:id="@+id/downloadBottomSheetDialog"
|
||||
android:name="com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog"
|
||||
android:label="DownloadBottomSheetDialog" />
|
||||
<dialog
|
||||
android:id="@+id/downloadMultipleBottomSheetDialog2"
|
||||
android:name="com.deniscerri.ytdlnis.ui.downloadcard.DownloadMultipleBottomSheetDialog"
|
||||
android:label="DownloadMultipleBottomSheetDialog" />
|
||||
</navigation>
|
||||
|
|
@ -8,14 +8,27 @@
|
|||
android:label="DownloadBottomSheetDialog" >
|
||||
<action
|
||||
android:id="@+id/action_downloadBottomSheetDialog_to_selectPlaylistItemsDialog"
|
||||
app:destination="@id/selectPlaylistItemsDialog" />
|
||||
app:destination="@id/selectPlaylistItemsDialog"
|
||||
app:launchSingleTop="true"
|
||||
app:popUpTo="@id/downloadBottomSheetDialog"
|
||||
app:popUpToInclusive="true" />
|
||||
</dialog>
|
||||
<dialog
|
||||
android:id="@+id/selectPlaylistItemsDialog"
|
||||
android:name="com.deniscerri.ytdlnis.ui.downloadcard.SelectPlaylistItemsDialog"
|
||||
android:label="SelectPlaylistItemsDialog">
|
||||
<action
|
||||
android:id="@+id/action_selectPlaylistItemsDialog_to_downloadMultipleBottomSheetDialog"
|
||||
app:destination="@id/downloadMultipleBottomSheetDialog" />
|
||||
app:destination="@id/downloadMultipleBottomSheetDialog"
|
||||
app:launchSingleTop="true"
|
||||
app:popUpTo="@id/selectPlaylistItemsDialog"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/action_selectPlaylistItemsDialog_to_downloadBottomSheetDialog"
|
||||
app:destination="@id/downloadBottomSheetDialog"
|
||||
app:launchSingleTop="true"
|
||||
app:popUpTo="@id/selectPlaylistItemsDialog"
|
||||
app:popUpToInclusive="true" />
|
||||
</dialog>
|
||||
<dialog
|
||||
android:id="@+id/downloadMultipleBottomSheetDialog"
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">تعيين نوع التحميل اللاحق بناءً على آخر نوع تحميل تم الوصول اليه</string>
|
||||
<string name="schedule">توقيت</string>
|
||||
<string name="search_command_hint">بحث في قوالب الأوامر</string>
|
||||
<string name="skip">تخطي</string>
|
||||
<string name="ignore">تخطي</string>
|
||||
<string name="license">الترخيص</string>
|
||||
<string name="download_already_exists_summary">المضي بالتحميل على أي حال؟</string>
|
||||
<string name="modify_download_card">تحرير بطاقة التحميل</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">Selecciona el último tipo de la descarga abierto para el elemento actual</string>
|
||||
<string name="schedule">Horario</string>
|
||||
<string name="search_command_hint">Búsqueda a partir de comandos</string>
|
||||
<string name="skip">Omitir</string>
|
||||
<string name="ignore">Omitir</string>
|
||||
<string name="license">Licencia</string>
|
||||
<string name="download_already_exists_summary">¿Todavía quieres descargar\?</string>
|
||||
<string name="modify_download_card">Modificar la tarjeta de descarga</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">वर्तमान आइटम के लिए अंतिम बार खोला गया डाउनलोड टाईप चुनें</string>
|
||||
<string name="schedule">शडिऊल</string>
|
||||
<string name="search_command_hint">कमांड में से खोजें</string>
|
||||
<string name="skip">छोड़ें</string>
|
||||
<string name="ignore">छोड़ें</string>
|
||||
<string name="license">लाइसेंस</string>
|
||||
<string name="download_already_exists_summary">क्या आप अब भी डाउनलोड करना चाहते हैं\?</string>
|
||||
<string name="modify_download_card">डाउनलोड कार्ड संशोधित करें</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="couldnt_parse_file">לא ניתן לנתח את הקובץ</string>
|
||||
<string name="schedule">תזמון</string>
|
||||
<string name="search_command_hint">חפש מתוך פקודות</string>
|
||||
<string name="skip">דילוג</string>
|
||||
<string name="ignore">דילוג</string>
|
||||
<string name="license">רישיון</string>
|
||||
<string name="download_already_exists_summary">האם תרצה להמשיך להוריד\?</string>
|
||||
<string name="modify_download_card">התאמת כרטיס הורדה</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">ਮੌਜੂਦਾ ਆਈਟਮ ਲਈ ਆਖਰੀ ਵਾਰ ਖੋਲ੍ਹੀ ਗਈ ਡਾਊਨਲੋਡ ਕਿਸਮ ਚੁਣੋ</string>
|
||||
<string name="schedule">ਸ਼ਡਿਊਲ</string>
|
||||
<string name="search_command_hint">ਕਮਾਂਡਾਂ ਤੋਂ ਖੋਜ ਕਰੋ</string>
|
||||
<string name="skip">ਸਕਿੱਪ ਕਰੋ</string>
|
||||
<string name="ignore">ਸਕਿੱਪ ਕਰੋ</string>
|
||||
<string name="license">ਲਾਈਸੈਂਸ</string>
|
||||
<string name="download_already_exists_summary">ਕੀ ਤੁਸੀਂ ਅਜੇ ਵੀ ਡਾਊਨਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ\?</string>
|
||||
<string name="modify_download_card">ਡਾਊਨਲੋਡ ਕਾਰਡ ਨੂੰ ਸੋਧੋ</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">Selecione o último tipo de download aberto para o item atual</string>
|
||||
<string name="schedule">Agendar</string>
|
||||
<string name="search_command_hint">Pesquisar a partir dos comandos</string>
|
||||
<string name="skip">Pular</string>
|
||||
<string name="ignore">Pular</string>
|
||||
<string name="license">Licença</string>
|
||||
<string name="download_already_exists_summary">Você ainda quer fazer o download\?</string>
|
||||
<string name="modify_download_card">Modificar cartão de download</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">Selecionar o último tipo de download aberto para o item atual</string>
|
||||
<string name="schedule">Agendar</string>
|
||||
<string name="search_command_hint">Pesquisar a partir de comandos</string>
|
||||
<string name="skip">Saltar</string>
|
||||
<string name="ignore">Saltar</string>
|
||||
<string name="license">Licença</string>
|
||||
<string name="download_already_exists_summary">Ainda queres descarregar\?</string>
|
||||
<string name="modify_download_card">Modificar o cartão de descarregamento</string>
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@
|
|||
<string name="schedule">Расписание</string>
|
||||
<string name="user_agent_header">Заголовок User-Agent</string>
|
||||
<string name="search_command_hint">Поиск по командам</string>
|
||||
<string name="skip">Пропустить</string>
|
||||
<string name="ignore">Пропустить</string>
|
||||
<string name="license">Лицензия</string>
|
||||
<string name="download_already_exists_summary">Вы все еще хотите скачать\?</string>
|
||||
<string name="modify_download_card">Изменить карту загрузки</string>
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@
|
|||
<string name="remember_download_type_summary">Zgjidh llojin e fundit të shkarkimit për shkarkimin aktual</string>
|
||||
<string name="length">Gjatësia</string>
|
||||
<string name="schedule">Orar</string>
|
||||
<string name="skip">Injoro</string>
|
||||
<string name="ignore">Injoro</string>
|
||||
<string name="license">Liçensa</string>
|
||||
<string name="download_already_exists_summary">Do sërisht ta shkarkosh\?</string>
|
||||
<string name="modify_download_card">Modifiko Kartën e Shkarkimit</string>
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@
|
|||
<string name="schedule">Розклад</string>
|
||||
<string name="user_agent_header">Заголовок User-Agent</string>
|
||||
<string name="search_command_hint">Пошук з команд</string>
|
||||
<string name="skip">Пропустити</string>
|
||||
<string name="ignore">Пропустити</string>
|
||||
<string name="license">Ліцензія</string>
|
||||
<string name="download_already_exists_summary">Ви все ще хочете завантажити\?</string>
|
||||
<string name="modify_download_card">Змінити картку завантаження</string>
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@
|
|||
<string name="schedule">Lịch trình</string>
|
||||
<string name="user_agent_header">Tiêu đề tác nhân người dùng</string>
|
||||
<string name="search_command_hint">Tìm kiếm từ lệnh</string>
|
||||
<string name="skip">Bỏ qua</string>
|
||||
<string name="ignore">Bỏ qua</string>
|
||||
<string name="license">Giấy phép</string>
|
||||
<string name="download_already_exists_summary">Bạn vẫn muốn tải xuống\?</string>
|
||||
<string name="modify_download_card">Sửa đổi thẻ tải xuống</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">为当前项目选择上次打开的下载类型</string>
|
||||
<string name="schedule">安排时间</string>
|
||||
<string name="search_command_hint">搜索命令行模板</string>
|
||||
<string name="skip">跳过</string>
|
||||
<string name="ignore">跳过</string>
|
||||
<string name="license">许可证</string>
|
||||
<string name="download_already_exists_summary">你仍要下载吗?</string>
|
||||
<string name="modify_download_card">修改下载卡片</string>
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@
|
|||
<string name="remember_download_type_summary">使用上次的下載類型</string>
|
||||
<string name="schedule">排程設定</string>
|
||||
<string name="search_command_hint">指令搜尋</string>
|
||||
<string name="skip">略過此項</string>
|
||||
<string name="ignore">略過此項</string>
|
||||
<string name="license">使用授權</string>
|
||||
<string name="download_already_exists_summary">是否繼續進行下載?</string>
|
||||
<string name="modify_download_card">編輯下載資訊卡片</string>
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@
|
|||
<string name="extra_command">Extra Command</string>
|
||||
<string name="use_cookies">Use Cookies</string>
|
||||
<string name="embed_metadata">Embed Metadata</string>
|
||||
<string name="embed_metadata_summary">Embed and parse metadata to the audio file</string>
|
||||
<string name="embed_metadata_summary">Parse and embed metadata to the audio file</string>
|
||||
<string name="update_formats_background">Update Formats in Background</string>
|
||||
<string name="auto_update_ytdlp">Auto-Update yt-dlp</string>
|
||||
<string name="use_sponsorblock">Use SponsorBlock</string>
|
||||
|
|
@ -316,7 +316,7 @@
|
|||
<string name="license">License</string>
|
||||
<string name="download_already_exists_summary">Do you still want to download?</string>
|
||||
<string name="schedule">Schedule</string>
|
||||
<string name="skip">Skip</string>
|
||||
<string name="ignore">Ignore</string>
|
||||
<string name="modify_download_card">Modify Download Card</string>
|
||||
<string name="export_file">Export File</string>
|
||||
</resources>
|
||||
|
|
@ -39,6 +39,7 @@ plugins {
|
|||
id 'com.android.library' version '8.1.1' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "1.8.10" apply false
|
||||
id "org.jetbrains.kotlin.plugin.parcelize" version "1.8.10" apply false
|
||||
id 'com.android.test' version '8.1.1' apply false
|
||||
id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue