added other download cards and recyclerview for cards to be queued for download
This commit is contained in:
parent
d124b8fb5f
commit
2371ab734d
22 changed files with 850 additions and 735 deletions
|
|
@ -320,7 +320,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/schedule/baseline_schedule_24.xml" />
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/keyboard_double_arrow_down/baseline_keyboard_double_arrow_down_24.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
@ -331,7 +331,7 @@
|
|||
<option name="values">
|
||||
<map>
|
||||
<entry key="color" value="00a6ff" />
|
||||
<entry key="outputName" value="ic_clock" />
|
||||
<entry key="outputName" value="ic_concurrent_downloads" />
|
||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
|
||||
</map>
|
||||
</option>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "6c48acc2155f9a895971bd84c84b7d4e",
|
||||
"identityHash": "5939be553c41327f4f64e1d62d008968",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "results",
|
||||
|
|
@ -198,7 +198,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "downloads",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `audioQualityId` TEXT NOT NULL, `videoQualityId` TEXT NOT NULL, `customTemplateId` INTEGER NOT NULL, `audioFormat` TEXT NOT NULL, `videoFormat` TEXT NOT NULL, `formatDesc` TEXT NOT NULL, `removeAudio` INTEGER NOT NULL DEFAULT 0, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `workID` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `audioQualityId` TEXT NOT NULL, `videoQualityId` TEXT NOT NULL, `customTemplateId` INTEGER NOT NULL, `audioFormat` TEXT NOT NULL, `videoFormat` TEXT NOT NULL, `formatDesc` TEXT NOT NULL, `removeAudio` INTEGER NOT NULL DEFAULT 0, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `embedSubs` INTEGER NOT NULL, `addChapters` INTEGER NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `workID` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "url",
|
||||
|
|
@ -303,6 +303,24 @@
|
|||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "embedSubs",
|
||||
"columnName": "embedSubs",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "addChapters",
|
||||
"columnName": "addChapters",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "SaveThumb",
|
||||
"columnName": "SaveThumb",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "status",
|
||||
"columnName": "status",
|
||||
|
|
@ -368,7 +386,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6c48acc2155f9a895971bd84c84b7d4e')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5939be553c41327f4f64e1d62d008968')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,8 @@ import android.os.Build
|
|||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.work.Configuration
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.deniscerri.ytdlnis.util.UpdateUtil
|
||||
import com.google.android.material.color.DynamicColors
|
||||
|
|
@ -23,12 +25,12 @@ import io.reactivex.observers.DisposableCompletableObserver
|
|||
import io.reactivex.plugins.RxJavaPlugins
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.File
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class App : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
DynamicColors.applyToActivitiesIfAvailable(this)
|
||||
notificationUtil = NotificationUtil(this)
|
||||
createNotificationChannels()
|
||||
PreferenceManager.setDefaultValues(
|
||||
this,
|
||||
|
|
@ -37,6 +39,15 @@ class App : Application() {
|
|||
R.xml.root_preferences,
|
||||
false
|
||||
)
|
||||
|
||||
WorkManager.initialize(
|
||||
this@App,
|
||||
Configuration.Builder()
|
||||
.setExecutor(Executors.newFixedThreadPool(
|
||||
getSharedPreferences("root_preferences", MODE_PRIVATE)
|
||||
.getInt("concurrent_downloads", 1)))
|
||||
.build())
|
||||
|
||||
configureRxJavaErrorHandler()
|
||||
Completable.fromAction { initLibraries() }.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
@ -79,12 +90,11 @@ class App : Application() {
|
|||
}
|
||||
|
||||
private fun createNotificationChannels() {
|
||||
val notificationUtil = NotificationUtil(this)
|
||||
notificationUtil.createNotificationChannel()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "App"
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
lateinit var notificationUtil: NotificationUtil
|
||||
}
|
||||
}
|
||||
|
|
@ -9,10 +9,7 @@ import android.os.Build
|
|||
import android.os.IBinder
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.workDataOf
|
||||
import androidx.work.*
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo
|
||||
import com.deniscerri.ytdlnis.service.IDownloaderListener
|
||||
|
|
@ -32,6 +29,7 @@ import io.reactivex.schedulers.Schedulers
|
|||
import java.io.File
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.regex.Pattern
|
||||
|
||||
|
||||
|
|
@ -43,7 +41,6 @@ class DownloaderService : Service() {
|
|||
private val downloadInfo = DownloadInfo()
|
||||
private var downloadQueue = LinkedList<ResultItem>()
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
private val notificationUtil = App.notificationUtil
|
||||
private var context: Context? = null
|
||||
var downloadProcessID = "processID"
|
||||
private var downloadNotificationID = 0
|
||||
|
|
@ -59,11 +56,11 @@ class DownloaderService : Service() {
|
|||
if (!downloadQueue.isEmpty()) {
|
||||
title = downloadQueue.peek()?.title
|
||||
}
|
||||
notificationUtil.updateDownloadNotification(
|
||||
downloadNotificationID,
|
||||
line!!, progress.toInt(), downloadQueue.size, title,
|
||||
notificationChannelID
|
||||
)
|
||||
// notificationUtil.updateDownloadNotification(
|
||||
// downloadNotificationID,
|
||||
// line!!, progress.toInt(), downloadQueue.size, title,
|
||||
// notificationChannelID
|
||||
// )
|
||||
try {
|
||||
for (activity in activities.keys) {
|
||||
activity.runOnUiThread {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
|
||||
class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener, activity: Activity) :
|
||||
ListAdapter<DownloadItem?, ConfigureMultipleDownloadsAdapter.ViewHolder?>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
|
||||
init {
|
||||
this.onItemClickListener = onItemClickListener
|
||||
this.activity = activity
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) :
|
||||
RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: MaterialCardView
|
||||
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.download_multiple_card_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.home_download_multiple_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.result_image_view)
|
||||
val imageURL = item!!.thumb
|
||||
if (imageURL.isNotEmpty()) {
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
thumbnail.setColorFilter(Color.argb(70, 0, 0, 0))
|
||||
} else {
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
uiHandler.post { Picasso.get().load(R.color.black).into(thumbnail) }
|
||||
thumbnail.setColorFilter(Color.argb(70, 0, 0, 0))
|
||||
}
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemTitle = card.findViewById<TextView>(R.id.result_title)
|
||||
var title = item.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title
|
||||
|
||||
// Author ----------------------------------
|
||||
val author = card.findViewById<TextView>(R.id.author)
|
||||
author.text = item.author
|
||||
|
||||
// Format
|
||||
val format = card.findViewById<TextView>(R.id.format)
|
||||
format.text = item.ext
|
||||
|
||||
// Quality
|
||||
val quality = card.findViewById<TextView>(R.id.quality)
|
||||
quality.text = item.formatDesc
|
||||
|
||||
// File Size
|
||||
val fileSize = card.findViewById<TextView>(R.id.filesize)
|
||||
fileSize.text = item.filesize
|
||||
|
||||
// Type Icon Button
|
||||
val btn = card.findViewById<MaterialButton>(R.id.download_type)
|
||||
|
||||
when(item.type) {
|
||||
"audio" -> {
|
||||
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music)
|
||||
}
|
||||
"video" -> {
|
||||
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
|
||||
}
|
||||
"command" -> {
|
||||
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_baseline_keyboard_arrow_right_24)
|
||||
}
|
||||
}
|
||||
|
||||
card.setOnClickListener {
|
||||
onItemClickListener.onCardClick(item.id!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onCardClick(itemID: Int)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<DownloadItem> =
|
||||
object : DiffUtil.ItemCallback<DownloadItem>() {
|
||||
override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||
return oldItem.id === newItem.id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||
return oldItem.url == newItem.url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,8 +15,11 @@ interface DownloadDao {
|
|||
@Query("SELECT * FROM downloads WHERE status='Active'")
|
||||
fun getActiveDownloads() : LiveData<List<DownloadItem>>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE status='Queued'")
|
||||
fun getQueuedDownloads() : List<DownloadItem>
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE workID=:workID")
|
||||
fun getDownloadsByWorkId(workID: Int) : List<DownloadItem>
|
||||
fun getDownloadByWorkId(workID: Int) : DownloadItem
|
||||
|
||||
@Query("SELECT * FROM downloads WHERE id=:id LIMIT 1")
|
||||
fun getDownloadById(id: Int) : DownloadItem
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@ data class DownloadItem(
|
|||
val embedSubs: Boolean,
|
||||
val addChapters: Boolean,
|
||||
val SaveThumb: Boolean,
|
||||
var ext: String,
|
||||
var filesize: String,
|
||||
@ColumnInfo(defaultValue = "Queued")
|
||||
val status: String,
|
||||
var status: String,
|
||||
val workID: Int
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
val allDownloads : LiveData<List<DownloadItem>> = downloadDao.getAllDownloads()
|
||||
val activeDownloads : LiveData<List<DownloadItem>> = downloadDao.getActiveDownloads()
|
||||
|
||||
enum class status {
|
||||
Active, Queued, Errored
|
||||
}
|
||||
|
||||
suspend fun insert(item: DownloadItem){
|
||||
downloadDao.insert(item)
|
||||
}
|
||||
|
|
@ -20,9 +24,17 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
downloadDao.update(item)
|
||||
}
|
||||
|
||||
fun getDownloadsByWorkID(workID: Int) : List<DownloadItem>{
|
||||
return downloadDao.getDownloadsByWorkId(workID)
|
||||
fun getDownloadByWorkID(workID: Int) : DownloadItem{
|
||||
return downloadDao.getDownloadByWorkId(workID)
|
||||
}
|
||||
|
||||
fun getQueuedDownloads() : List<DownloadItem>{
|
||||
return downloadDao.getQueuedDownloads()
|
||||
}
|
||||
|
||||
suspend fun setDownloadStatus(item: DownloadItem, status: status){
|
||||
item.status = status.toString()
|
||||
update(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
private var downloadCard: SwitchPreferenceCompat? = null
|
||||
private var apiKey: EditTextPreference? = null
|
||||
private var concurrentFragments: SeekBarPreference? = null
|
||||
private var concurrentDownloads: SeekBarPreference? = null
|
||||
private var limitRate: EditTextPreference? = null
|
||||
private var aria2: SwitchPreferenceCompat? = null
|
||||
private var sponsorblockFilters: MultiSelectListPreference? = null
|
||||
|
|
@ -55,6 +56,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
downloadCard = findPreference("download_card")
|
||||
apiKey = findPreference("api_key")
|
||||
concurrentFragments = findPreference("concurrent_fragments")
|
||||
concurrentDownloads = findPreference("concurrent_downloads")
|
||||
limitRate = findPreference("limit_rate")
|
||||
aria2 = findPreference("aria2")
|
||||
sponsorblockFilters = findPreference("sponsorblock_filter")
|
||||
|
|
@ -83,6 +85,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
editor.putBoolean("download_card", downloadCard!!.isChecked)
|
||||
editor.putString("api_key", apiKey!!.text)
|
||||
editor.putInt("concurrent_fragments", concurrentFragments!!.value)
|
||||
editor.putInt("concurrent_downloads", concurrentDownloads!!.value)
|
||||
editor.putString("limit_rate", limitRate!!.text)
|
||||
editor.putBoolean("aria2", aria2!!.isChecked)
|
||||
editor.putStringSet("sponsorblock_filters", sponsorblockFilters!!.values)
|
||||
|
|
@ -159,6 +162,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
editor.apply()
|
||||
true
|
||||
}
|
||||
concurrentDownloads!!.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
||||
val value = newValue.toString().toInt()
|
||||
editor.putInt("concurrent_downloads", value)
|
||||
editor.apply()
|
||||
true
|
||||
}
|
||||
limitRate!!.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
||||
editor.putString("limit_rate", newValue.toString())
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@ import android.os.SystemClock
|
|||
import android.provider.DocumentsContract
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ForegroundInfo
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import com.deniscerri.ytdlnis.BuildConfig
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
||||
|
|
@ -31,8 +31,8 @@ import java.util.regex.Pattern
|
|||
class DownloadWorker(
|
||||
private val context: Context,
|
||||
workerParams: WorkerParameters
|
||||
) : CoroutineWorker(context, workerParams) {
|
||||
override suspend fun doWork(): Result {
|
||||
) : Worker(context, workerParams) {
|
||||
override fun doWork(): Result {
|
||||
workID = inputData.getInt("workID", SystemClock.uptimeMillis().toInt())
|
||||
val notificationUtil = NotificationUtil(context)
|
||||
val dbManager = DBManager.getInstance(context)
|
||||
|
|
@ -41,183 +41,182 @@ class DownloadWorker(
|
|||
val commandTemplateDao = dbManager.commandTemplateDao
|
||||
val historyDao = dbManager.historyDao
|
||||
|
||||
queue = repository.getDownloadsByWorkID(workID) as MutableList<DownloadItem>
|
||||
|
||||
val downloadItem = repository.getDownloadByWorkID(workID)
|
||||
runBlocking{
|
||||
repository.setDownloadStatus(downloadItem, DownloadRepository.status.Active)
|
||||
}
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
val notification = notificationUtil.createDownloadServiceNotification(pendingIntent, queue[0].title, workID, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
|
||||
val notification = notificationUtil.createDownloadServiceNotification(pendingIntent, downloadItem.title, workID, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
|
||||
val foregroundInfo = ForegroundInfo(workID, notification)
|
||||
setForeground(foregroundInfo)
|
||||
setForegroundAsync(foregroundInfo)
|
||||
|
||||
while (queue.isNotEmpty()){
|
||||
val item = dao.getDownloadById(queue[0].id!!)
|
||||
queue.removeFirst()
|
||||
val url = item.url
|
||||
val request = YoutubeDLRequest(url)
|
||||
val type = item.type
|
||||
val downloadLocation = item.downloadPath
|
||||
|
||||
val url = downloadItem.url
|
||||
val request = YoutubeDLRequest(url)
|
||||
val type = downloadItem.type
|
||||
val downloadLocation = downloadItem.downloadPath
|
||||
|
||||
val tempFolder = StringBuilder(context.cacheDir.absolutePath + """/${item.title}##${item.type}""")
|
||||
when(type){
|
||||
"audio" -> tempFolder.append("##${item.audioQualityId}")
|
||||
"video" -> tempFolder.append("##${item.videoQualityId}")
|
||||
"command" -> tempFolder.append("##${item.customTemplateId}")
|
||||
val tempFolder = StringBuilder(context.cacheDir.absolutePath + """/${downloadItem.title}##${downloadItem.type}""")
|
||||
when(type){
|
||||
"audio" -> tempFolder.append("##${downloadItem.audioQualityId}")
|
||||
"video" -> tempFolder.append("##${downloadItem.videoQualityId}")
|
||||
"command" -> tempFolder.append("##${downloadItem.customTemplateId}")
|
||||
}
|
||||
var tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
val sharedPreferences = context.getSharedPreferences("root_preferences",
|
||||
Service.MODE_PRIVATE
|
||||
)
|
||||
val aria2 = sharedPreferences.getBoolean("aria2", false)
|
||||
if (aria2) {
|
||||
request.addOption("--downloader", "libaria2c.so")
|
||||
request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"")
|
||||
} else {
|
||||
val concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1)
|
||||
if (concurrentFragments > 1) request.addOption("-N", concurrentFragments)
|
||||
}
|
||||
val limitRate = sharedPreferences.getString("limit_rate", "")
|
||||
if (limitRate != "") request.addOption("-r", limitRate!!)
|
||||
val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
if (writeThumbnail) {
|
||||
request.addOption("--write-thumbnail")
|
||||
request.addOption("--convert-thumbnails", "png")
|
||||
}
|
||||
request.addOption("--no-mtime")
|
||||
val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||
if (sponsorBlockFilters!!.isNotEmpty()) {
|
||||
val filters = java.lang.String.join(",", sponsorBlockFilters)
|
||||
request.addOption("--sponsorblock-remove", filters)
|
||||
}
|
||||
|
||||
when(type){
|
||||
"audio" -> {
|
||||
request.addOption("-x")
|
||||
var audioQualityId : String = downloadItem.audioQualityId
|
||||
if (audioQualityId == "0") audioQualityId = "ba"
|
||||
var format = downloadItem.audioFormat
|
||||
if (format.isEmpty()){
|
||||
format = sharedPreferences.getString("audio_format", "")!!
|
||||
}
|
||||
request.addOption("-f", audioQualityId)
|
||||
request.addOption("--audio-format", format)
|
||||
request.addOption("--embed-metadata")
|
||||
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
if (embedThumb) {
|
||||
request.addOption("--embed-thumbnail")
|
||||
request.addOption("--convert-thumbnails", "png")
|
||||
try {
|
||||
val config = File(context.cacheDir, "config" + downloadItem.title + "##" + downloadItem.audioQualityId + ".txt")
|
||||
val configData =
|
||||
"--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
||||
config.writeText(configData)
|
||||
request.addOption("--config", config.absolutePath)
|
||||
} catch (ignored: Exception) {}
|
||||
}
|
||||
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
||||
request.addCommands(listOf("--replace-in-metadata", "title", ".*.", downloadItem.title))
|
||||
request.addCommands(listOf("--replace-in-metadata", "uploader", ".*.", downloadItem.author))
|
||||
|
||||
if (downloadItem.playlistTitle.isNotEmpty()) {
|
||||
request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
|
||||
request.addOption("--parse-metadata", "%(track_number,playlist_index)d:%(meta_track)s")
|
||||
} else {
|
||||
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
||||
}
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
}
|
||||
var tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
"video" -> {
|
||||
if (downloadLocation == context.getString(R.string.video_path)){
|
||||
tempFileDir = File(context.getString(R.string.video_path))
|
||||
}
|
||||
|
||||
val sharedPreferences = context.getSharedPreferences("root_preferences",
|
||||
Service.MODE_PRIVATE
|
||||
)
|
||||
val aria2 = sharedPreferences.getBoolean("aria2", false)
|
||||
if (aria2) {
|
||||
request.addOption("--downloader", "libaria2c.so")
|
||||
request.addOption("--external-downloader-args", "aria2c:\"--summary-interval=1\"")
|
||||
} else {
|
||||
val concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1)
|
||||
if (concurrentFragments > 1) request.addOption("-N", concurrentFragments)
|
||||
}
|
||||
val limitRate = sharedPreferences.getString("limit_rate", "")
|
||||
if (limitRate != "") request.addOption("-r", limitRate!!)
|
||||
val writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
if (writeThumbnail) {
|
||||
request.addOption("--write-thumbnail")
|
||||
request.addOption("--convert-thumbnails", "png")
|
||||
}
|
||||
request.addOption("--no-mtime")
|
||||
val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||
if (sponsorBlockFilters!!.isNotEmpty()) {
|
||||
val filters = java.lang.String.join(",", sponsorBlockFilters)
|
||||
request.addOption("--sponsorblock-remove", filters)
|
||||
}
|
||||
|
||||
when(type){
|
||||
"audio" -> {
|
||||
request.addOption("-x")
|
||||
var audioQualityId : String = item.audioQualityId
|
||||
if (audioQualityId == "0") audioQualityId = "ba"
|
||||
var format = item.audioFormat
|
||||
if (format.isEmpty()){
|
||||
format = sharedPreferences.getString("audio_format", "")!!
|
||||
}
|
||||
request.addOption("-f", audioQualityId)
|
||||
request.addOption("--audio-format", format)
|
||||
request.addOption("--embed-metadata")
|
||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||
if (addChapters) {
|
||||
request.addOption("--sponsorblock-mark", "all")
|
||||
}
|
||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
if (embedSubs) {
|
||||
request.addOption("--embed-subs", "")
|
||||
}
|
||||
var videoQualityId = downloadItem.videoQualityId
|
||||
val audioQualityId = downloadItem.audioQualityId
|
||||
if (videoQualityId.isEmpty()) videoQualityId = "bestvideo"
|
||||
val formatArgument = StringBuilder(videoQualityId)
|
||||
if (videoQualityId != "worst"){
|
||||
if (audioQualityId != "0") formatArgument.append("+", audioQualityId, "/best")
|
||||
}
|
||||
request.addOption("-f", formatArgument.toString())
|
||||
var format = downloadItem.videoFormat
|
||||
if (format.isNotEmpty()) {
|
||||
format = sharedPreferences.getString("video_format", "")!!
|
||||
if (format != "DEFAULT") request.addOption("--merge-output-format", format)
|
||||
}
|
||||
|
||||
if (format != "webm") {
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
if (embedThumb) {
|
||||
request.addOption("--embed-thumbnail")
|
||||
request.addOption("--convert-thumbnails", "png")
|
||||
try {
|
||||
val config = File(context.cacheDir, "config" + item.title + "##" + item.audioQualityId + ".txt")
|
||||
val configData =
|
||||
"--ppa \"ffmpeg: -c:v png -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
||||
config.writeText(configData)
|
||||
request.addOption("--config", config.absolutePath)
|
||||
} catch (ignored: Exception) {}
|
||||
}
|
||||
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
||||
request.addCommands(listOf("--replace-in-metadata", "title", ".*.", item.title))
|
||||
request.addCommands(listOf("--replace-in-metadata", "uploader", ".*.", item.author))
|
||||
|
||||
if (item.playlistTitle.isNotEmpty()) {
|
||||
request.addOption("--parse-metadata", "%(album,playlist,title)s:%(meta_album)s")
|
||||
request.addOption("--parse-metadata", "%(track_number,playlist_index)d:%(meta_track)s")
|
||||
} else {
|
||||
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
||||
}
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
}
|
||||
"video" -> {
|
||||
if (downloadLocation == context.getString(R.string.video_path)){
|
||||
tempFileDir = File(context.getString(R.string.video_path))
|
||||
}
|
||||
|
||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||
if (addChapters) {
|
||||
request.addOption("--sponsorblock-mark", "all")
|
||||
}
|
||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
if (embedSubs) {
|
||||
request.addOption("--embed-subs", "")
|
||||
}
|
||||
var videoQualityId = item.videoQualityId
|
||||
val audioQualityId = item.audioQualityId
|
||||
if (videoQualityId.isEmpty()) videoQualityId = "bestvideo"
|
||||
val formatArgument = StringBuilder(videoQualityId)
|
||||
if (videoQualityId != "worst"){
|
||||
if (audioQualityId != "0") formatArgument.append("+", audioQualityId, "/best")
|
||||
}
|
||||
request.addOption("-f", formatArgument.toString())
|
||||
var format = item.videoFormat
|
||||
if (format.isNotEmpty()) {
|
||||
format = sharedPreferences.getString("video_format", "")!!
|
||||
if (format != "DEFAULT") request.addOption("--merge-output-format", format)
|
||||
}
|
||||
|
||||
if (format != "webm") {
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
if (embedThumb) {
|
||||
request.addOption("--embed-thumbnail")
|
||||
}
|
||||
}
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
}
|
||||
"command" -> {
|
||||
val commandRegex = "\"([^\"]*)\"|(\\S+)"
|
||||
val command = commandTemplateDao.getTemplateById(item.customTemplateId)
|
||||
val m = Pattern.compile(commandRegex).matcher(command.content)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
request.addOption("-o", tempFileDir.absolutePath + "/%(uploader)s - %(title)s.%(ext)s")
|
||||
}
|
||||
|
||||
runCatching {
|
||||
YoutubeDL.getInstance().execute(request, item.id.toString()){ progress, _, line ->
|
||||
setProgressAsync(workDataOf("progress" to progress.toInt()))
|
||||
var title: String? = context.getString(R.string.download_start)
|
||||
if (queue.isNotEmpty()) {
|
||||
title = queue[0].title
|
||||
"command" -> {
|
||||
val commandRegex = "\"([^\"]*)\"|(\\S+)"
|
||||
val command = commandTemplateDao.getTemplateById(downloadItem.customTemplateId)
|
||||
val m = Pattern.compile(commandRegex).matcher(command.content)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
notificationUtil.updateDownloadNotification(
|
||||
workID,
|
||||
line, progress.toInt(), queue.size, title,
|
||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
}
|
||||
}.onSuccess {
|
||||
//move file from internal to set download directory
|
||||
moveFile(tempFileDir.absoluteFile, downloadLocation){ progress ->
|
||||
setProgressAsync(workDataOf("progress" to progress))
|
||||
}
|
||||
//put download in history
|
||||
val incognito = sharedPreferences.getBoolean("incognito", false)
|
||||
if (!incognito) {
|
||||
val unixtime = System.currentTimeMillis() / 1000
|
||||
val historyItem = HistoryItem(item.url, item.title, item.author, item.duration, item.thumb, item.type, unixtime, item.downloadPath, item.website)
|
||||
historyDao.insert(historyItem)
|
||||
}
|
||||
|
||||
}.onFailure {
|
||||
tempFileDir.delete()
|
||||
if (BuildConfig.DEBUG) {
|
||||
Toast.makeText(context, it.message, Toast.LENGTH_LONG).show()
|
||||
Log.e(DownloadWorker.TAG, context.getString(R.string.failed_download), it)
|
||||
}
|
||||
notificationUtil.updateDownloadNotification(
|
||||
workID,
|
||||
context.getString(R.string.failed_download), 0, 0, item.title,
|
||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
return Result.failure()
|
||||
}
|
||||
}
|
||||
|
||||
runCatching {
|
||||
YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line ->
|
||||
setProgressAsync(workDataOf("progress" to progress.toInt()))
|
||||
val title: String = downloadItem.title
|
||||
val queue = dao.getQueuedDownloads()
|
||||
notificationUtil.updateDownloadNotification(
|
||||
workID,
|
||||
line, progress.toInt(), queue.size, title,
|
||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
}
|
||||
}.onSuccess {
|
||||
//move file from internal to set download directory
|
||||
moveFile(tempFileDir.absoluteFile, downloadLocation){ progress ->
|
||||
setProgressAsync(workDataOf("progress" to progress))
|
||||
}
|
||||
//put download in history
|
||||
val incognito = sharedPreferences.getBoolean("incognito", false)
|
||||
if (!incognito) {
|
||||
val unixtime = System.currentTimeMillis() / 1000
|
||||
val historyItem = HistoryItem(downloadItem.url, downloadItem.title, downloadItem.author, downloadItem.duration, downloadItem.thumb, downloadItem.type, unixtime, downloadItem.downloadPath, downloadItem.website)
|
||||
runBlocking {
|
||||
historyDao.insert(historyItem)
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
tempFileDir.delete()
|
||||
if (BuildConfig.DEBUG) {
|
||||
Toast.makeText(context, it.message, Toast.LENGTH_LONG).show()
|
||||
Log.e(TAG, context.getString(R.string.failed_download), it)
|
||||
}
|
||||
notificationUtil.updateDownloadNotification(
|
||||
workID,
|
||||
context.getString(R.string.failed_download), 0, 0, downloadItem.title,
|
||||
NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID
|
||||
)
|
||||
return Result.failure()
|
||||
}
|
||||
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +246,6 @@ class DownloadWorker(
|
|||
companion object {
|
||||
var workID: Int = 0
|
||||
const val TAG = "DownloadWorker"
|
||||
lateinit var queue: MutableList<DownloadItem>
|
||||
}
|
||||
|
||||
}
|
||||
6
app/src/main/res/drawable/ic_concurrent_downloads.xml
Normal file
6
app/src/main/res/drawable/ic_concurrent_downloads.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M18,6.41l-1.41,-1.41l-4.59,4.58l-4.59,-4.58l-1.41,1.41l6,6z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M18,13l-1.41,-1.41l-4.59,4.58l-4.59,-4.58l-1.41,1.41l6,6z"/>
|
||||
</vector>
|
||||
|
|
@ -165,7 +165,4 @@
|
|||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<include layout="@layout/home_download_all_bottom_sheet"
|
||||
android:visibility="gone" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout android:id="@+id/history_element_bottom_sheet"
|
||||
style="@style/Widget.Material3.BottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="30dp"
|
||||
android:orientation="vertical"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/title"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/author_textinput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/author"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/audio_format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/audio_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/audio_format_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/music_formats"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -37,7 +38,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -87,33 +87,10 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/download_multiple_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:id="@+id/bottomsheet_audio_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_music"
|
||||
android:text="@string/audio" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:id="@+id/bottomsheet_video_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/video"
|
||||
app:icon="@drawable/ic_video"
|
||||
android:autoLink="all"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
163
app/src/main/res/layout/home_download_multiple_card.xml
Normal file
163
app/src/main/res/layout/home_download_multiple_card.xml
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/result_card_constraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/result_relative_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintDimensionRatio="H,3:1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/download_multiple_card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:cardCornerRadius="10dp"
|
||||
app:cardElevation="10dp"
|
||||
app:cardMaxElevation="12dp"
|
||||
app:cardPreventCornerOverlap="true"
|
||||
android:checkable="true"
|
||||
app:strokeWidth="0dp"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/result_image_view"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:dividerPadding="5dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.8"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/result_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingStart="10dp"
|
||||
android:textSize="17sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
android:shadowRadius="2"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowColor="@color/black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/author"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="bottom"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingStart="10dp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
android:shadowRadius="1.5"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowColor="@color/black" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
|
||||
android:id="@+id/download_type"
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="55dp"
|
||||
app:cornerRadius="10dp"
|
||||
android:layout_margin="10dp"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingStart="10dp"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/format"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:gravity="bottom"
|
||||
android:textSize="15sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
android:shadowRadius="1.5"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowColor="@color/black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quality"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:gravity="bottom"
|
||||
android:textSize="15sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
android:shadowRadius="1.5"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowColor="@color/black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/filesize"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="bottom"
|
||||
android:textSize="15sp"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
android:shadowRadius="1.5"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowColor="@color/black" />
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
60
app/src/main/res/layout/home_download_settings.xml
Normal file
60
app/src/main/res/layout/home_download_settings.xml
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout android:id="@+id/history_element_bottom_sheet"
|
||||
style="@style/Widget.Material3.BottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="25sp"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download" />
|
||||
|
||||
<include layout="@layout/home_download_settings_components" />
|
||||
|
||||
<View style="@style/Divider.Horizontal"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_cancel"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:id="@+id/bottomsheet_download_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ok"
|
||||
app:icon="@drawable/ic_check"
|
||||
android:autoLink="all"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
242
app/src/main/res/layout/home_download_settings_components.xml
Normal file
242
app/src/main/res/layout/home_download_settings_components.xml
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/title"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/author_textinput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/author"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/audio_format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/audio_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/audio_format_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/music_formats"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/outputPath_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/save_dir"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:selectionRequired="true"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/audioChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
android:text="@string/audio"
|
||||
app:chipIcon="@drawable/ic_music" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/videoChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/video"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
app:chipIcon="@drawable/ic_video" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/commandChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/run_command"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
app:chipIcon="@drawable/ic_baseline_keyboard_arrow_right_24" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/adjust_commands"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/adjust_templates" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/commands_chip_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:selectionRequired="false"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="false">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/newTemplate"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/new_template"
|
||||
app:chipIcon="@drawable/ic_plus" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/editSelected"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/edit_selected"
|
||||
app:chipIcon="@drawable/ic_edit" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/adjust_video"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/adjust_video" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
app:singleLine="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/embed_subtitles"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/embed_subtitles"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/add_chapters"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/add_chapter"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/save_thumbnail"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/save_thumb"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/remove_audio"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/remove_audio"/>
|
||||
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -23,242 +23,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/download" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_author"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/title"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/author_textinput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/author"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/audio_format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/audio_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/audio_format_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/music_formats"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/outputPath_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/save_dir"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:selectionRequired="true"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/audioChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
android:text="@string/audio"
|
||||
app:chipIcon="@drawable/ic_music" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/videoChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/video"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
app:chipIcon="@drawable/ic_video" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/commandChip"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/run_command"
|
||||
android:checkable="true"
|
||||
app:checkedIcon="@drawable/ic_check"
|
||||
app:chipIcon="@drawable/ic_baseline_keyboard_arrow_right_24" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/adjust_commands"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/adjust_templates" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/commands_chip_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:selectionRequired="false"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="false">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/newTemplate"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/new_template"
|
||||
app:chipIcon="@drawable/ic_plus" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/editSelected"
|
||||
style="@style/Widget.Material3.Chip.Assist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/edit_selected"
|
||||
app:chipIcon="@drawable/ic_edit" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/adjust_video"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/adjust_video" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
app:singleLine="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/embed_subtitles"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/embed_subtitles"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/add_chapters"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/add_chapter"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/save_thumbnail"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/save_thumb"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/remove_audio"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/remove_audio"/>
|
||||
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
<include layout="@layout/home_download_settings_components" />
|
||||
|
||||
<View style="@style/Divider.Horizontal"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,188 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout android:id="@+id/history_element_bottom_sheet"
|
||||
style="@style/Widget.Material3.BottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="25sp"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download_video" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_author"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="30dp"
|
||||
android:orientation="vertical"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_textinput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
android:hint="@string/title"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/video_format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/video_format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/video_format_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/video_formats"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/video_quality"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_weight="45"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/video_quality">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/video_quality_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/video_quality"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
app:singleLine="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/embed_subtitles"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/embed_subtitles"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/add_chapters"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/add_chapter"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/save_thumbnail"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/save_thumb"/>
|
||||
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:id="@+id/bottomsheet_cancel_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_cancel"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
|
||||
android:id="@+id/bottomsheet_download_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download"
|
||||
app:icon="@drawable/ic_down"
|
||||
android:autoLink="all"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">YTDLnis</string>
|
||||
<string name="search">Ara</string>
|
||||
<string name="remove_all"> Tümünü Kaldır</string>
|
||||
<string name="remove_results"> Clear Results</string>
|
||||
|
|
@ -65,9 +64,6 @@
|
|||
<string name="choose_range_desc">Çalma listesinden indirmek için bir aralık seçin (her şeyi indirmemek için).</string>
|
||||
<string name="last_cant_be_smaller_than_first">Son dizin ilkinden daha küçük olamaz.</string>
|
||||
<string name="first_cant_be_larger_than_last">İlk dizin son dizinden büyük olamaz.</string>
|
||||
<string name="music_path" translatable="false">/storage/emulated/0/Download</string>
|
||||
<string name="video_path" translatable="false">/storage/emulated/0/Download</string>
|
||||
<string name="command_path" translatable="false">/storage/emulated/0/Download</string>
|
||||
<string name="concurrent_fragments_summary">Eşzamanlı olarak indirilecek DASH/HLS yerel video parçalarının sayısı</string>
|
||||
<string name="concurrent_fragments">Eşzamanlı Parçalar</string>
|
||||
<string name="downloading">İndirme</string>
|
||||
|
|
@ -110,7 +106,6 @@
|
|||
<string name="newest_first">En yeni</string>
|
||||
<string name="oldest_first">En eski</string>
|
||||
<item type="id" name="cancelDownload"/>
|
||||
<string name="trendingPlaylist" translatable="false">ytdlnis-TRENDING</string>
|
||||
<string name="currently_downloading">İndiriliyor</string>
|
||||
<string name="remove_downloading">İndirmeleri İptal Et</string>
|
||||
<string name="confirm_delete_downloading_desc">İndirilmekte olan tüm öğeleri kaldırın ve indirme hizmetini durdurun?</string>
|
||||
|
|
|
|||
|
|
@ -158,4 +158,6 @@
|
|||
<string name="adjust_video">Adjust video</string>
|
||||
<string name="remove_audio">Remove Audio</string>
|
||||
<string name="schedule">Schedule</string>
|
||||
<string name="concurrent_downloads">Concurrent Downloads</string>
|
||||
<string name="concurrent_downloads_summary">Number of downloads executing at the same time</string>
|
||||
</resources>
|
||||
|
|
@ -56,6 +56,17 @@
|
|||
app:summary="@string/concurrent_fragments_summary"
|
||||
app:title="@string/concurrent_fragments" />
|
||||
|
||||
<SeekBarPreference
|
||||
android:defaultValue="1"
|
||||
android:icon="@drawable/ic_concurrent_downloads"
|
||||
android:max="5"
|
||||
app:key="concurrent_downloads"
|
||||
app:min="1"
|
||||
app:showSeekBarValue="true"
|
||||
android:dependency="aria2"
|
||||
app:summary="@string/concurrent_downloads_summary"
|
||||
app:title="@string/concurrent_downloads" />
|
||||
|
||||
<EditTextPreference
|
||||
android:icon="@drawable/ic_down"
|
||||
app:key="limit_rate"
|
||||
|
|
|
|||
Loading…
Reference in a new issue