added new download card again...
This commit is contained in:
parent
19eab5e054
commit
7f813ebd96
47 changed files with 1511 additions and 728 deletions
|
|
@ -320,7 +320,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<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" />
|
||||
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material/icons/materialicons/history/baseline_history_24.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
@ -330,8 +330,7 @@
|
|||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="color" value="00a6ff" />
|
||||
<entry key="outputName" value="ic_concurrent_downloads" />
|
||||
<entry key="outputName" value="ic_history" />
|
||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
|
||||
</map>
|
||||
</option>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JetCodeStyleSettings>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
|
|
@ -109,5 +116,8 @@
|
|||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
|
|
@ -2,12 +2,18 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "c8effa77edcd8cf5e46a79fd1a791535",
|
||||
"identityHash": "94d37ae85390ef5198651df2480a02bf",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "results",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
|
|
@ -49,12 +55,6 @@
|
|||
"columnName": "playlistTitle",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
|
@ -68,18 +68,18 @@
|
|||
},
|
||||
{
|
||||
"tableName": "formats",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` INTEGER NOT NULL, `format` TEXT NOT NULL, `format_id` TEXT NOT NULL, `ext` TEXT NOT NULL, `filesize` INTEGER NOT NULL, `format_note` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `itemId` INTEGER NOT NULL, `format_id` TEXT NOT NULL, `container` TEXT NOT NULL, `filesize` INTEGER NOT NULL, `format_note` TEXT NOT NULL, `encoding` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "itemId",
|
||||
"columnName": "itemId",
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "format",
|
||||
"columnName": "format",
|
||||
"affinity": "TEXT",
|
||||
"fieldPath": "itemId",
|
||||
"columnName": "itemId",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
|
|
@ -89,8 +89,8 @@
|
|||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "ext",
|
||||
"columnName": "ext",
|
||||
"fieldPath": "container",
|
||||
"columnName": "container",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
|
|
@ -107,10 +107,10 @@
|
|||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
"fieldPath": "encoding",
|
||||
"columnName": "encoding",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
|
@ -124,8 +124,14 @@
|
|||
},
|
||||
{
|
||||
"tableName": "history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `time` INTEGER NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `time` INTEGER NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
|
|
@ -179,12 +185,6 @@
|
|||
"columnName": "website",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
|
@ -198,8 +198,14 @@
|
|||
},
|
||||
{
|
||||
"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, `audioFormat` TEXT NOT NULL, `videoFormat` TEXT NOT NULL, `audioFormatId` TEXT NOT NULL, `videoFormatId` TEXT NOT NULL, `customTemplateId` INTEGER 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, `ext` TEXT NOT NULL, `filesize` 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}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `audioFormatId` TEXT NOT NULL, `videoFormatId` TEXT NOT NULL, `customTemplateId` INTEGER 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, `ext` TEXT NOT NULL, `filesize` TEXT NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `workID` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
|
|
@ -236,18 +242,6 @@
|
|||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "audioFormat",
|
||||
"columnName": "audioFormat",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "videoFormat",
|
||||
"columnName": "videoFormat",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "audioFormatId",
|
||||
"columnName": "audioFormatId",
|
||||
|
|
@ -345,12 +339,6 @@
|
|||
"columnName": "workID",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
|
@ -364,8 +352,14 @@
|
|||
},
|
||||
{
|
||||
"tableName": "commandTemplates",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`title` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
|
|
@ -377,12 +371,6 @@
|
|||
"columnName": "content",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
|
@ -398,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, 'c8effa77edcd8cf5e46a79fd1a791535')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '94d37ae85390ef5198651df2480a02bf')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ import androidx.work.WorkManager
|
|||
import com.deniscerri.ytdlnis.DownloaderService.LocalBinder
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding
|
||||
import com.deniscerri.ytdlnis.ui.DownloadsFragment
|
||||
import com.deniscerri.ytdlnis.ui.HistoryFragment
|
||||
import com.deniscerri.ytdlnis.ui.HomeFragment
|
||||
import com.deniscerri.ytdlnis.ui.MoreFragment
|
||||
import com.deniscerri.ytdlnis.ui.settings.SettingsActivity
|
||||
|
|
@ -43,7 +43,7 @@ class MainActivity : AppCompatActivity() {
|
|||
private lateinit var binding: ActivityMainBinding
|
||||
lateinit var context: Context
|
||||
private lateinit var homeFragment: HomeFragment
|
||||
private lateinit var downloadsFragment: DownloadsFragment
|
||||
private lateinit var historyFragment: HistoryFragment
|
||||
var downloaderService: DownloaderService? = null
|
||||
private lateinit var workManager: WorkManager
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class MainActivity : AppCompatActivity() {
|
|||
workManager = WorkManager.getInstance(context)
|
||||
|
||||
homeFragment = HomeFragment()
|
||||
downloadsFragment = DownloadsFragment()
|
||||
historyFragment = HistoryFragment()
|
||||
moreFragment = MoreFragment()
|
||||
initFragments()
|
||||
binding.bottomNavigationView.setOnItemSelectedListener { item: MenuItem ->
|
||||
|
|
@ -97,13 +97,13 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
replaceFragment(homeFragment)
|
||||
}
|
||||
R.id.downloads -> {
|
||||
if (lastFragment === downloadsFragment) {
|
||||
downloadsFragment.scrollToTop()
|
||||
R.id.history -> {
|
||||
if (lastFragment === historyFragment) {
|
||||
historyFragment.scrollToTop()
|
||||
} else {
|
||||
this.title = getString(R.string.downloads)
|
||||
}
|
||||
replaceFragment(downloadsFragment)
|
||||
replaceFragment(historyFragment)
|
||||
}
|
||||
R.id.more -> {
|
||||
if (lastFragment === moreFragment) {
|
||||
|
|
@ -151,7 +151,7 @@ class MainActivity : AppCompatActivity() {
|
|||
if (Intent.ACTION_SEND == action && type != null) {
|
||||
Log.e(TAG, action)
|
||||
homeFragment = HomeFragment()
|
||||
downloadsFragment = DownloadsFragment()
|
||||
historyFragment = HistoryFragment()
|
||||
moreFragment = MoreFragment()
|
||||
if (type.equals("application/txt", ignoreCase = true)) {
|
||||
try {
|
||||
|
|
@ -185,9 +185,9 @@ class MainActivity : AppCompatActivity() {
|
|||
private fun initFragments() {
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.frame_layout, homeFragment)
|
||||
.add(R.id.frame_layout, downloadsFragment)
|
||||
.add(R.id.frame_layout, historyFragment)
|
||||
.add(R.id.frame_layout, moreFragment)
|
||||
.hide(downloadsFragment)
|
||||
.hide(historyFragment)
|
||||
.hide(moreFragment)
|
||||
.commit()
|
||||
lastFragment = homeFragment
|
||||
|
|
|
|||
|
|
@ -101,13 +101,13 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
|
|||
}
|
||||
|
||||
card.setOnClickListener {
|
||||
onItemClickListener.onCardClick(item.id!!)
|
||||
onItemClickListener.onCardClick(item.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onCardClick(itemID: Int)
|
||||
fun onCardClick(itemID: Long)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
|
|
@ -28,7 +29,7 @@ import java.text.SimpleDateFormat
|
|||
import java.util.*
|
||||
|
||||
class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<HistoryItem?, HistoryAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val checkedItems: ArrayList<Int>
|
||||
private val checkedItems: ArrayList<Long>
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
|
||||
|
|
@ -48,16 +49,16 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.downloads_card, parent, false)
|
||||
.inflate(R.layout.history_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val video = getItem(position)
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.downloads_image_view)
|
||||
val imageURL = video!!.thumb
|
||||
val imageURL = item!!.thumb
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
if (imageURL.isNotEmpty()) {
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
|
|
@ -67,28 +68,28 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val videoTitle = card.findViewById<TextView>(R.id.downloads_title)
|
||||
var title = video.title
|
||||
val itemTitle = card.findViewById<TextView>(R.id.downloads_title)
|
||||
var title = item.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
videoTitle.text = title
|
||||
itemTitle.text = title
|
||||
|
||||
// Bottom Info ----------------------------------
|
||||
val bottomInfo = card.findViewById<TextView>(R.id.downloads_info_bottom)
|
||||
var info = video.author
|
||||
if (video.duration.isNotEmpty()) {
|
||||
if (video.author.isNotEmpty()) info += " • "
|
||||
info += video.duration
|
||||
var info = item.author
|
||||
if (item.duration.isNotEmpty()) {
|
||||
if (item.author.isNotEmpty()) info += " • "
|
||||
info += item.duration
|
||||
}
|
||||
bottomInfo.text = info
|
||||
|
||||
// TIME DOWNLOADED ----------------------------------
|
||||
val datetime = card.findViewById<TextView>(R.id.downloads_info_time)
|
||||
val time = video.time
|
||||
val time = item.time
|
||||
val downloadedTime: String
|
||||
if (time == 0L) {
|
||||
downloadedTime = activity.getString(R.string.currently_downloading) + " " + video.type
|
||||
downloadedTime = activity.getString(R.string.currently_downloading) + " " + item.type
|
||||
} else {
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(time * 1000L)
|
||||
|
|
@ -108,7 +109,7 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
var filePresent = true
|
||||
|
||||
//IS IN THE FILE SYSTEM?
|
||||
val path = video.downloadPath
|
||||
val path = item.downloadPath
|
||||
val file = File(path)
|
||||
if (!file.exists() && path.isNotEmpty()) {
|
||||
filePresent = false
|
||||
|
|
@ -119,15 +120,15 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
})
|
||||
thumbnail.alpha = 0.7f
|
||||
}
|
||||
if (video.type.isNotEmpty()) {
|
||||
if (video.type == "audio") {
|
||||
if (item.type.isNotEmpty()) {
|
||||
if (item.type == "audio") {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_music)
|
||||
} else {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
|
||||
}
|
||||
}
|
||||
if (btn.hasOnClickListeners()) btn.setOnClickListener(null)
|
||||
if (checkedItems.contains(position)) {
|
||||
if (checkedItems.contains(item.id)) {
|
||||
card.isChecked = true
|
||||
card.strokeWidth = 5
|
||||
} else {
|
||||
|
|
@ -136,49 +137,54 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
}
|
||||
val finalFilePresent = filePresent
|
||||
card.setOnLongClickListener {
|
||||
checkCard(card, position)
|
||||
checkCard(card, item.id)
|
||||
true
|
||||
}
|
||||
card.setOnClickListener {
|
||||
if (checkedItems.size > 0) {
|
||||
checkCard(card, video.id!!)
|
||||
checkCard(card, item.id)
|
||||
} else {
|
||||
onItemClickListener.onCardClick(video.id!!, finalFilePresent)
|
||||
onItemClickListener.onCardClick(item.id, finalFilePresent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCard(card: MaterialCardView, videoID: Int) {
|
||||
private fun checkCard(card: MaterialCardView, itemID: Long) {
|
||||
if (card.isChecked) {
|
||||
card.strokeWidth = 0
|
||||
checkedItems.removeAt(videoID)
|
||||
checkedItems.remove(itemID)
|
||||
} else {
|
||||
card.strokeWidth = 5
|
||||
checkedItems.add(videoID)
|
||||
checkedItems.add(itemID)
|
||||
}
|
||||
card.isChecked = !card.isChecked
|
||||
onItemClickListener.onCardSelect(videoID, card.isChecked)
|
||||
onItemClickListener.onCardSelect(itemID, card.isChecked)
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onCardClick(position: Int, isPresent: Boolean)
|
||||
fun onCardSelect(position: Int, isChecked: Boolean)
|
||||
fun onCardClick(itemID: Long, isPresent: Boolean)
|
||||
fun onCardSelect(itemID: Long, isChecked: Boolean)
|
||||
fun onButtonClick(position: Int)
|
||||
}
|
||||
|
||||
fun clearCheckedVideos() {
|
||||
val size = checkedItems.size
|
||||
for (i in 0 until size) {
|
||||
val position = checkedItems[i]
|
||||
notifyItemChanged(position)
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun clearCheckeditems() {
|
||||
for (i in 0 until itemCount){
|
||||
val item = getItem(i)
|
||||
if (checkedItems.find { it == item?.id } != null){
|
||||
checkedItems.remove(item?.id)
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
|
||||
checkedItems.clear()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<HistoryItem> = object : DiffUtil.ItemCallback<HistoryItem>() {
|
||||
override fun areItemsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
|
||||
return oldItem.id === newItem.id
|
||||
val ranged = arrayListOf(oldItem.id, newItem.id)
|
||||
return ranged[0] == ranged[1]
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: HistoryItem, newItem: HistoryItem): Boolean {
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ class HomeAdapter(onItemClickListener: OnItemClickListener, activity: Activity)
|
|||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: ResultItem, newItem: ResultItem): Boolean {
|
||||
return oldItem.url == newItem.url
|
||||
return oldItem.url == newItem.url && oldItem.title == newItem.title && oldItem.author == newItem.author
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ interface CommandTemplateDao {
|
|||
fun getAllTemplates() : List<CommandTemplate>
|
||||
|
||||
@Query("SELECT * FROM commandTemplates WHERE id=:id LIMIT 1")
|
||||
fun getTemplateById(id: Int) : CommandTemplate
|
||||
fun getTemplate(id: Long) : CommandTemplate
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insert(item: CommandTemplate)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ interface DownloadDao {
|
|||
@Query("SELECT * FROM downloads WHERE id=:id LIMIT 1")
|
||||
fun getDownloadById(id: Int) : DownloadItem
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insert(item: DownloadItem)
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(item: DownloadItem) : Long
|
||||
|
||||
@Query("DELETE FROM downloads")
|
||||
suspend fun deleteAll()
|
||||
|
|
@ -35,4 +35,7 @@ interface DownloadDao {
|
|||
|
||||
@Update(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun update(item: DownloadItem)
|
||||
|
||||
@Query("SELECT * FROM downloads ORDER BY id DESC LIMIT 1")
|
||||
fun getLatest() : DownloadItem
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import com.deniscerri.ytdlnis.database.models.ResultItem
|
|||
@Dao
|
||||
interface FormatDao {
|
||||
@Query("SELECT * FROM formats WHERE itemId=:itemId")
|
||||
fun getFormatsByItemId(itemId: Int) : List<Format>
|
||||
fun getFormatsByItemId(itemId: Long) : List<Format>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(item: Format)
|
||||
|
|
@ -20,6 +20,6 @@ interface FormatDao {
|
|||
suspend fun deleteAll()
|
||||
|
||||
@Query("DELETE FROM formats WHERE itemId=:itemId")
|
||||
suspend fun deleteFromatsByItemId(itemId: Int)
|
||||
suspend fun deleteFromatsByItemId(itemId: Long)
|
||||
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ interface HistoryDao {
|
|||
suspend fun insert(item: HistoryItem)
|
||||
|
||||
@Query("DELETE FROM history WHERE id=:id")
|
||||
suspend fun delete(id: Int)
|
||||
suspend fun delete(id: Long)
|
||||
|
||||
@Query("DELETE FROM history")
|
||||
suspend fun deleteAll()
|
||||
|
|
|
|||
|
|
@ -24,4 +24,7 @@ interface ResultDao {
|
|||
@Query("DELETE FROM results")
|
||||
suspend fun deleteAll()
|
||||
|
||||
@Query("SELECT * FROM results WHERE url=:url LIMIT 1")
|
||||
fun getResultByURL(url: String) : ResultItem
|
||||
|
||||
}
|
||||
|
|
@ -6,9 +6,8 @@ import androidx.room.PrimaryKey
|
|||
|
||||
@Entity(tableName = "commandTemplates")
|
||||
data class CommandTemplate(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long,
|
||||
val title: String,
|
||||
val content: String
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
)
|
||||
|
|
@ -6,33 +6,30 @@ import androidx.room.PrimaryKey
|
|||
|
||||
@Entity(tableName = "downloads")
|
||||
data class DownloadItem(
|
||||
val url: String,
|
||||
var title: String,
|
||||
var author: String,
|
||||
val thumb: String,
|
||||
val duration: String,
|
||||
val type: String,
|
||||
var audioFormat: String,
|
||||
var videoFormat: String,
|
||||
var audioFormatId: String,
|
||||
var videoFormatId: String,
|
||||
var customTemplateId: Int,
|
||||
val formatDesc: String,
|
||||
@ColumnInfo(defaultValue = "0")
|
||||
val removeAudio: Boolean,
|
||||
val downloadPath: String,
|
||||
val website: String,
|
||||
val downloadSize: String,
|
||||
val playlistTitle: String,
|
||||
val embedSubs: Boolean,
|
||||
val addChapters: Boolean,
|
||||
val SaveThumb: Boolean,
|
||||
var ext: String,
|
||||
var filesize: String,
|
||||
@ColumnInfo(defaultValue = "Queued")
|
||||
var status: String,
|
||||
val workID: Int
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
var id: Long,
|
||||
val url: String,
|
||||
var title: String,
|
||||
var author: String,
|
||||
val thumb: String,
|
||||
val duration: String,
|
||||
var type: String,
|
||||
var audioFormatId: String,
|
||||
var videoFormatId: String,
|
||||
var customTemplateId: Long,
|
||||
var formatDesc: String,
|
||||
@ColumnInfo(defaultValue = "0")
|
||||
val removeAudio: Boolean,
|
||||
val downloadPath: String,
|
||||
val website: String,
|
||||
val downloadSize: String,
|
||||
val playlistTitle: String,
|
||||
val embedSubs: Boolean,
|
||||
val addChapters: Boolean,
|
||||
val SaveThumb: Boolean,
|
||||
var ext: String,
|
||||
var filesize: String,
|
||||
@ColumnInfo(defaultValue = "Queued")
|
||||
var status: String,
|
||||
val workID: Int
|
||||
)
|
||||
|
|
@ -6,18 +6,17 @@ import com.google.gson.annotations.SerializedName
|
|||
|
||||
@Entity(tableName = "formats")
|
||||
data class Format(
|
||||
var itemId: Int,
|
||||
@SerializedName(value = "format", alternate = ["type"])
|
||||
val format: String,
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long,
|
||||
var itemId: Long,
|
||||
@SerializedName(value = "format_id", alternate = ["itag"])
|
||||
val format_id: String,
|
||||
@SerializedName(value = "ext", alternate = ["container", ""])
|
||||
val ext: String,
|
||||
@SerializedName(value = "filesize", alternate = ["clen"])
|
||||
@SerializedName(value = "ext", alternate = ["container"])
|
||||
val container: String,
|
||||
@SerializedName(value = "filesize", alternate = ["clen", "filesize_approx"])
|
||||
val filesize: Long,
|
||||
@SerializedName(value = "format_note", alternate = ["resolution", "audioQuality"])
|
||||
val format_note: String
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
val format_note: String,
|
||||
@SerializedName(value = "encoding", alternate = ["vcodec", "acodec", "video_ext"])
|
||||
val encoding: String
|
||||
)
|
||||
|
|
@ -5,6 +5,8 @@ import androidx.room.PrimaryKey
|
|||
|
||||
@Entity(tableName = "history")
|
||||
data class HistoryItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long,
|
||||
val url: String,
|
||||
val title: String,
|
||||
val author: String,
|
||||
|
|
@ -14,7 +16,4 @@ data class HistoryItem(
|
|||
val time: Long,
|
||||
val downloadPath: String,
|
||||
val website: String
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
)
|
||||
|
|
@ -5,14 +5,13 @@ import androidx.room.PrimaryKey
|
|||
|
||||
@Entity(tableName = "results")
|
||||
data class ResultItem(
|
||||
val url: String,
|
||||
var title: String,
|
||||
var author: String,
|
||||
val duration: String,
|
||||
val thumb: String,
|
||||
val website: String,
|
||||
var playlistTitle: String
|
||||
){
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int? = null
|
||||
}
|
||||
var id: Long,
|
||||
val url: String,
|
||||
var title: String,
|
||||
var author: String,
|
||||
val duration: String,
|
||||
val thumb: String,
|
||||
val website: String,
|
||||
var playlistTitle: String
|
||||
)
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.deniscerri.ytdlnis.database.repository
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
|
|
@ -9,11 +10,11 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
val activeDownloads : LiveData<List<DownloadItem>> = downloadDao.getActiveDownloads()
|
||||
|
||||
enum class status {
|
||||
Active, Queued, Errored
|
||||
Active, Queued, Errored, Processing
|
||||
}
|
||||
|
||||
suspend fun insert(item: DownloadItem){
|
||||
downloadDao.insert(item)
|
||||
suspend fun insert(item: DownloadItem) : Long {
|
||||
return downloadDao.insert(item)
|
||||
}
|
||||
|
||||
suspend fun delete(item: DownloadItem){
|
||||
|
|
@ -37,4 +38,8 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
|||
update(item);
|
||||
}
|
||||
|
||||
fun getLatest() : DownloadItem {
|
||||
return downloadDao.getLatest()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ class HistoryRepository(private val historyDao: HistoryDao) {
|
|||
val fileUtil = FileUtil()
|
||||
items.value?.forEach { item ->
|
||||
if (!fileUtil.exists(item.downloadPath)){
|
||||
historyDao.delete(item.id!!)
|
||||
historyDao.delete(item.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class ResultRepository(private val resultDao: ResultDao, private val formatDao:
|
|||
private suspend fun addFormats(formats : ArrayList<Format>, id: Long){
|
||||
formats.forEach { f ->
|
||||
if (f.filesize == 0L) return@forEach
|
||||
f.itemId = id.toInt()
|
||||
f.itemId = id
|
||||
formatDao.insert(f)
|
||||
}
|
||||
}
|
||||
|
|
@ -122,11 +122,15 @@ class ResultRepository(private val resultDao: ResultDao, private val formatDao:
|
|||
}
|
||||
|
||||
fun getFormats(item: ResultItem): List<Format> {
|
||||
return formatDao.getFormatsByItemId(item.id!!)
|
||||
return formatDao.getFormatsByItemId(item.id)
|
||||
}
|
||||
|
||||
fun getTemplates() : List<CommandTemplate> {
|
||||
return commandTemplateDao.getAllTemplates()
|
||||
}
|
||||
|
||||
fun getItemByURL(url: String): ResultItem {
|
||||
return resultDao.getResultByURL(url)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.deniscerri.ytdlnis.database.viewmodel
|
|||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.deniscerri.ytdlnis.database.DBManager
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
|
|
@ -27,8 +28,13 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
|
||||
}
|
||||
|
||||
fun insertDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO){
|
||||
repository.insert(item)
|
||||
fun insertDownload(item: DownloadItem) : LiveData<Long> {
|
||||
val result = MutableLiveData<Long>()
|
||||
viewModelScope.launch(Dispatchers.IO){
|
||||
val id = repository.insert(item)
|
||||
result.postValue(id)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun deleteDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO) {
|
||||
|
|
@ -38,4 +44,8 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
|||
fun updateDownload(item: DownloadItem) = viewModelScope.launch(Dispatchers.IO){
|
||||
repository.update(item);
|
||||
}
|
||||
|
||||
fun getLatest() : DownloadItem {
|
||||
return repository.getLatest()
|
||||
}
|
||||
}
|
||||
|
|
@ -95,29 +95,38 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
|
|||
}
|
||||
|
||||
fun getFormats(item: ResultItem, type: String) : List<Format> {
|
||||
val list = repository.getFormats(item)
|
||||
var list = repository.getFormats(item)
|
||||
val formats = mutableListOf<Format>()
|
||||
if (list.isEmpty()){
|
||||
when(type){
|
||||
"audio" -> {
|
||||
val audioFormats = getApplication<App>().resources.getStringArray(R.array.audio_formats)
|
||||
audioFormats.forEach { formats.add(Format(item.id!!, it, "", "", 0, it)) }
|
||||
}
|
||||
"video" -> {
|
||||
val videoFormats = getApplication<App>().resources.getStringArray(R.array.video_formats)
|
||||
videoFormats.forEach { formats.add(Format(item.id!!, it, "", "", 0, it)) }
|
||||
}
|
||||
}
|
||||
return formats
|
||||
}
|
||||
val audioFormats = getApplication<App>().resources.getStringArray(R.array.audio_formats)
|
||||
val videoFormats = getApplication<App>().resources.getStringArray(R.array.video_formats)
|
||||
|
||||
when(type){
|
||||
"audio" -> return list.filter { it.format.contains("audio", ignoreCase = true) }
|
||||
"video" -> return list.filter { !it.format.contains("audio", ignoreCase = true) }
|
||||
"audio" -> {
|
||||
list = list.filter { it.format_note.contains("audio", ignoreCase = true) }
|
||||
if (list.isEmpty()) {
|
||||
audioFormats.forEach { formats.add(Format(0, item.id, it, "", 0, it, "")) }
|
||||
return formats
|
||||
}
|
||||
return list
|
||||
}
|
||||
"video" -> {
|
||||
list = list.filter { !it.format_note.contains("audio", ignoreCase = true) }
|
||||
if (list.isEmpty()) {
|
||||
videoFormats.forEach { formats.add(Format(0, item.id, it, "", 0, it, "")) }
|
||||
return formats
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
val templates = repository.getTemplates()
|
||||
templates.forEach {
|
||||
formats.add(Format(item.id!!, it.title, it.id.toString(), "", 0, it.content))
|
||||
formats.add(Format(0, item.id, it.title, "", 0, it.content, ""))
|
||||
}
|
||||
return formats
|
||||
}
|
||||
|
||||
fun getItemByURL(url: String) : ResultItem {
|
||||
return repository.getItemByURL(url)
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ import com.deniscerri.ytdlnis.database.DatabaseManager
|
|||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.HistoryViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentDownloadsBinding
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHistoryBinding
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
|
|
@ -39,7 +39,7 @@ import java.io.File
|
|||
/**
|
||||
* A fragment representing a list of Items.
|
||||
*/
|
||||
class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
||||
class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
||||
OnClickListener, OnLongClickListener {
|
||||
private lateinit var historyViewModel : HistoryViewModel
|
||||
|
||||
|
|
@ -66,14 +66,14 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
private var deleteFab: ExtendedFloatingActionButton? = null
|
||||
private var fileUtil: FileUtil? = null
|
||||
|
||||
private var _binding : FragmentDownloadsBinding? = null
|
||||
private var _binding : FragmentHistoryBinding? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentDownloadsBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_downloads, container, false)
|
||||
_binding = FragmentHistoryBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_history, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
sortChip.setOnClickListener {
|
||||
sortSheet = BottomSheetDialog(requireContext())
|
||||
sortSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
sortSheet!!.setContentView(R.layout.downloads_sort_sheet)
|
||||
sortSheet!!.setContentView(R.layout.history_sort_sheet)
|
||||
val newest = sortSheet!!.findViewById<TextView>(R.id.newest)
|
||||
val oldest = sortSheet!!.findViewById<TextView>(R.id.oldest)
|
||||
newest!!.setOnClickListener {
|
||||
|
|
@ -309,13 +309,13 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.bottomsheet_remove_button -> {
|
||||
removeItem(v.tag as Int)
|
||||
removeItem(v.tag as Long)
|
||||
}
|
||||
R.id.bottom_sheet_link -> {
|
||||
openLinkIntent(v.tag as Int)
|
||||
openLinkIntent(v.tag as Long)
|
||||
}
|
||||
R.id.bottomsheet_open_file_button -> {
|
||||
openFileIntent(v.tag as Int)
|
||||
openFileIntent(v.tag as Long)
|
||||
}
|
||||
R.id.delete_selected_fab -> {
|
||||
removeSelectedItems()
|
||||
|
|
@ -326,7 +326,7 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
override fun onLongClick(v: View): Boolean {
|
||||
val id = v.id
|
||||
if (id == R.id.bottom_sheet_link) {
|
||||
copyLinkToClipBoard(v.tag as Int)
|
||||
copyLinkToClipBoard(v.tag as Long)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -347,13 +347,13 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
historyViewModel.delete(item, deleteFile[0])
|
||||
}
|
||||
selectedObjects = ArrayList()
|
||||
historyAdapter!!.clearCheckedVideos()
|
||||
historyAdapter!!.clearCheckeditems()
|
||||
deleteFab!!.visibility = GONE
|
||||
}
|
||||
deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun removeItem(id: Int) {
|
||||
private fun removeItem(id: Long) {
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
val deleteFile = booleanArrayOf(false)
|
||||
val v = findItem(id)
|
||||
|
|
@ -370,7 +370,7 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun copyLinkToClipBoard(id: Int) {
|
||||
private fun copyLinkToClipBoard(id: Long) {
|
||||
val url = findItem(id)?.url
|
||||
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(getString(R.string.url), url)
|
||||
|
|
@ -380,7 +380,7 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
.show()
|
||||
}
|
||||
|
||||
private fun openLinkIntent(id: Int) {
|
||||
private fun openLinkIntent(id: Long) {
|
||||
val url = findItem(id)?.url
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = Uri.parse(url)
|
||||
|
|
@ -388,7 +388,7 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
startActivity(i)
|
||||
}
|
||||
|
||||
private fun openFileIntent(id: Int) {
|
||||
private fun openFileIntent(id: Long) {
|
||||
val downloadPath = findItem(id)!!.downloadPath
|
||||
val file = File(downloadPath)
|
||||
val uri = FileProvider.getUriForFile(
|
||||
|
|
@ -403,11 +403,11 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
startActivity(i)
|
||||
}
|
||||
|
||||
override fun onCardClick(id: Int, isFilePresent: Boolean) {
|
||||
override fun onCardClick(videoID: Long, isPresent: Boolean) {
|
||||
bottomSheet = BottomSheetDialog(fragmentContext!!)
|
||||
bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet!!.setContentView(R.layout.downloads_bottom_sheet)
|
||||
val video = findItem(id)
|
||||
bottomSheet!!.setContentView(R.layout.history_item_details_bottom_sheet)
|
||||
val video = findItem(videoID)
|
||||
val title = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_title)
|
||||
title!!.text = video!!.title
|
||||
val author = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_author)
|
||||
|
|
@ -415,16 +415,16 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
val link = bottomSheet!!.findViewById<Button>(R.id.bottom_sheet_link)
|
||||
val url = video.url
|
||||
link!!.text = url
|
||||
link.tag = id
|
||||
link.tag = videoID
|
||||
link.setOnClickListener(this)
|
||||
link.setOnLongClickListener(this)
|
||||
val remove = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.tag = id
|
||||
remove!!.tag = videoID
|
||||
remove.setOnClickListener(this)
|
||||
val openFile = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_open_file_button)
|
||||
openFile!!.tag = id
|
||||
openFile!!.tag = videoID
|
||||
openFile.setOnClickListener(this)
|
||||
if (!isFilePresent) openFile.visibility = GONE
|
||||
if (!isPresent) openFile.visibility = GONE
|
||||
bottomSheet!!.show()
|
||||
bottomSheet!!.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
|
|
@ -432,9 +432,9 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
)
|
||||
}
|
||||
|
||||
override fun onCardSelect(id: Int, add: Boolean) {
|
||||
val item = findItem(id)
|
||||
if (add) selectedObjects!!.add(item!!)
|
||||
override fun onCardSelect(videoID: Long, isChecked: Boolean) {
|
||||
val item = findItem(videoID)
|
||||
if (isChecked) selectedObjects!!.add(item!!)
|
||||
else selectedObjects!!.remove(item)
|
||||
if (selectedObjects!!.size > 1) {
|
||||
deleteFab!!.visibility = VISIBLE
|
||||
|
|
@ -454,7 +454,7 @@ class DownloadsFragment : Fragment(), HistoryAdapter.OnItemClickListener,
|
|||
// }
|
||||
}
|
||||
|
||||
private fun findItem(id : Int): HistoryItem? {
|
||||
private fun findItem(id : Long): HistoryItem? {
|
||||
return downloadsList?.find { it?.id == id }
|
||||
}
|
||||
|
||||
|
|
@ -4,12 +4,11 @@ import android.annotation.SuppressLint
|
|||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.Editable
|
||||
import android.text.InputType
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.View.GONE
|
||||
|
|
@ -17,7 +16,6 @@ import android.view.View.VISIBLE
|
|||
import android.widget.*
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.text.trimmedLength
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
|
@ -28,9 +26,12 @@ import com.deniscerri.ytdlnis.adapter.HomeAdapter
|
|||
import com.deniscerri.ytdlnis.database.DatabaseManager
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentDownloadsBinding
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.service.DownloadInfo
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.InfoUtil
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
|
|
@ -43,7 +44,6 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu
|
|||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import kotlin.math.log10
|
||||
|
|
@ -65,6 +65,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
private var downloadInfo: DownloadInfo? = null
|
||||
|
||||
private lateinit var resultViewModel : ResultViewModel
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
|
||||
private var downloading = false
|
||||
private var fragmentView: View? = null
|
||||
|
|
@ -86,13 +87,13 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
private var deleteFab: ExtendedFloatingActionButton? = null
|
||||
private var fileUtil: FileUtil? = null
|
||||
|
||||
private var _binding : FragmentDownloadsBinding? = null
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentDownloadsBinding.inflate(inflater, container, false)
|
||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_home, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
|
|
@ -117,6 +118,8 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
selectedObjects = ArrayList()
|
||||
downloading = mainActivity!!.isDownloadServiceRunning()
|
||||
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
|
||||
downloadQueue = ArrayList()
|
||||
resultsList = mutableListOf()
|
||||
selectedObjects = ArrayList()
|
||||
|
|
@ -141,7 +144,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
homeAdapter!!.submitList(it)
|
||||
resultsList = it
|
||||
if(it.size > 1){
|
||||
if (it[0].playlistTitle.isNotEmpty() || it[0].playlistTitle != "ytdlnis-TRENDING"){
|
||||
if (it[0].playlistTitle.isNotEmpty() || it[0].playlistTitle != getString(R.string.trendingPlaylist)){
|
||||
downloadAllFabCoordinator!!.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
|
|
@ -205,68 +208,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// private fun initCards() {
|
||||
// val uiHandler = Handler(Looper.getMainLooper())
|
||||
// try {
|
||||
// val thread = Thread {
|
||||
// databaseManager = DatabaseManager(context)
|
||||
// resultsList = databaseManager!!.results
|
||||
// var playlistTitle = ""
|
||||
// try {
|
||||
// playlistTitle = resultsList.get(0).playlistTitle
|
||||
// } catch (ignored: Exception) {
|
||||
// }
|
||||
// if (resultsList.size == 0 || playlistTitle == getString(R.string.trendingPlaylist) && !downloading) {
|
||||
// try {
|
||||
// databaseManager!!.clearResults()
|
||||
// uiHandler.post {
|
||||
// shimmerCards!!.startShimmer()
|
||||
// shimmerCards!!.visibility = View.VISIBLE
|
||||
// }
|
||||
// infoUtil = InfoUtil(context!!)
|
||||
// resultsList = infoUtil!!.getTrending(context!!)
|
||||
// databaseManager!!.addToResults(resultsList)
|
||||
// } catch (e: Exception) {
|
||||
// Log.e(TAG, e.toString())
|
||||
// }
|
||||
// } else {
|
||||
// if (!downloading) {
|
||||
// homeAdapter!!.add(resultsList)
|
||||
// for (i in resultsList.indices) {
|
||||
// val tmp = resultsList.get(i)
|
||||
// if (tmp!!.isDownloading) {
|
||||
// updateDownloadingStatusOnResult(tmp, "audio", false)
|
||||
// updateDownloadingStatusOnResult(tmp, "video", false)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// uiHandler.post {
|
||||
// if (homeAdapter!!.itemCount != resultsList.size) {
|
||||
// homeAdapter!!.add(resultsList)
|
||||
// }
|
||||
// shimmerCards!!.stopShimmer()
|
||||
// shimmerCards!!.visibility = View.GONE
|
||||
// }
|
||||
// databaseManager!!.close()
|
||||
// if (resultsList != null) {
|
||||
// uiHandler.post { scrollToTop() }
|
||||
// if (resultsList!!.size > 1 && resultsList!![1]!!.isPlaylistItem == 1) {
|
||||
// uiHandler.post { downloadAllFabCoordinator!!.visibility = View.VISIBLE }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// thread.start()
|
||||
// } catch (e: Exception) {
|
||||
// Log.e(TAG, e.toString())
|
||||
// uiHandler.post {
|
||||
// shimmerCards!!.stopShimmer()
|
||||
// shimmerCards!!.visibility = View.GONE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun initMenu() {
|
||||
val onActionExpandListener: MenuItem.OnActionExpandListener =
|
||||
object : MenuItem.OnActionExpandListener {
|
||||
|
|
@ -407,7 +348,10 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
if (sharedPreferences.getBoolean("download_card", true)) {
|
||||
// selectedObjects!!.clear()
|
||||
// selectedObjects!!.add(item!!)
|
||||
showConfigureSingleDownloadCard(item!!, type)
|
||||
//showConfigureSingleDownloadCard(createDownloadItem(item!!, type), item)
|
||||
createDownloadItem(item!!, type){
|
||||
showSingleDownloadSheet(it)
|
||||
}
|
||||
} else {
|
||||
// downloadQueue!!.add(vid)
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
|
|
@ -418,6 +362,38 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
}
|
||||
}
|
||||
|
||||
private fun showSingleDownloadSheet(item : DownloadItem){
|
||||
val bottomSheet = DownloadBottomSheetDialog(item)
|
||||
bottomSheet.show(parentFragmentManager, null)
|
||||
}
|
||||
|
||||
private fun createDownloadItem(item: ResultItem, type: String, itemCreated: (DownloadItem) -> Unit) : DownloadItem {
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
|
||||
|
||||
val downloadItem = DownloadItem(0,
|
||||
item.url,
|
||||
item.title,
|
||||
item.author,
|
||||
item.thumb,
|
||||
item.duration,
|
||||
type,
|
||||
"", "", 0, "", false,
|
||||
"", item.website, "", item.playlistTitle, embedSubs, addChapters, saveThumb, "",
|
||||
"", DownloadRepository.status.Processing.toString(), 0
|
||||
)
|
||||
|
||||
downloadViewModel.insertDownload(downloadItem).observe(viewLifecycleOwner) {
|
||||
downloadItem.id = it
|
||||
itemCreated(downloadItem)
|
||||
}
|
||||
return downloadItem
|
||||
}
|
||||
|
||||
|
||||
fun updateDownloadStatusOnResult(v: ResultItem?, type: String?, downloaded: Boolean) {
|
||||
// if (v != null) {
|
||||
|
|
@ -576,275 +552,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun showConfigureSingleDownloadCard(item: ResultItem, type: String) {
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
|
||||
var downloadItem = DownloadItem(
|
||||
item.url,
|
||||
item.title,
|
||||
item.author,
|
||||
item.thumb,
|
||||
item.duration,
|
||||
type,
|
||||
"", "", "", "", 0, "", false,
|
||||
"", item.website, "", item.playlistTitle, embedSubs, addChapters, saveThumb, "",
|
||||
"", "", 0
|
||||
)
|
||||
|
||||
val editor = sharedPreferences.edit()
|
||||
try {
|
||||
bottomSheet = BottomSheetDialog(fragmentContext!!)
|
||||
bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet!!.setContentView(R.layout.home_download_single_bottom_sheet)
|
||||
val title = bottomSheet!!.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
title!!.editText!!.setText(item.title)
|
||||
title.editText!!.addTextChangedListener(object: TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
item.title = p0.toString()
|
||||
resultViewModel.update(item)
|
||||
}
|
||||
})
|
||||
|
||||
val author = bottomSheet!!.findViewById<TextInputLayout>(R.id.author_textinput)
|
||||
author!!.editText!!.setText(item.author)
|
||||
author.editText!!.addTextChangedListener(object: TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
item.author = p0.toString()
|
||||
resultViewModel.update(item)
|
||||
}
|
||||
})
|
||||
|
||||
var formats = resultViewModel.getFormats(item, type)
|
||||
Log.e(TAG, formats.toString())
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
it.format_note.replace("AUDIO_QUALITY_", "") +
|
||||
if (it.filesize == 0L) "" else " / " + convertFileSize(it.filesize)
|
||||
else it.format_note +
|
||||
if (it.filesize == 0L) "" else " / " + convertFileSize(it.filesize)}
|
||||
|
||||
val format = bottomSheet!!.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView = bottomSheet!!.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, formatTitles))
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
when(type){
|
||||
"audio" -> {
|
||||
downloadItem.audioFormat = formats[index].format
|
||||
downloadItem.audioFormatId = formats[index].format_id
|
||||
}
|
||||
|
||||
"video" -> {
|
||||
downloadItem.videoFormat = formats[index].format
|
||||
downloadItem.videoFormatId = formats[index].format_id
|
||||
}
|
||||
|
||||
"command" -> {
|
||||
downloadItem.customTemplateId = formats[index].format_id.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var selectedContainer : String
|
||||
val containers = when (type){
|
||||
"audio" -> requireContext().resources.getStringArray(R.array.audio_containers)
|
||||
"video" -> requireContext().resources.getStringArray(R.array.video_containers)
|
||||
else -> null
|
||||
}
|
||||
val container = bottomSheet!!.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView = bottomSheet!!.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
if (containers == null){
|
||||
containerAutoCompleteTextView!!.setText(getString(R.string.custom_command), false)
|
||||
containerAutoCompleteTextView.isClickable = false
|
||||
containerAutoCompleteTextView.isLongClickable = false
|
||||
}else{
|
||||
// val containerTitles = containers.map {
|
||||
// if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
// it.format_note.replace("AUDIO_QUALITY_", "") + " / " + convertFileSize(it.filesize)
|
||||
// else it.format_note + " / " + convertFileSize(it.filesize) }
|
||||
|
||||
selectedContainer = when(type){
|
||||
"audio" -> formats.find { downloadItem.audioFormat == it.format }?.ext ?: sharedPreferences.getString("audio_format", "mp3")!!
|
||||
else -> formats.find { downloadItem.videoFormat == it.format }?.ext ?: sharedPreferences.getString("video_format", "DEFAULT")!!
|
||||
}
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
}
|
||||
}
|
||||
|
||||
// when(type) {
|
||||
// "audio" -> {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// if (type == "audio") {
|
||||
//
|
||||
// val audioFormats = context!!.resources.getStringArray(R.array.music_formats)
|
||||
// val audioFormat = bottomSheet!!.findViewById<TextInputLayout>(R.id.audio_format)
|
||||
// val autoCompleteTextView =
|
||||
// bottomSheet!!.findViewById<AutoCompleteTextView>(R.id.audio_format_textview)
|
||||
// val preference = sharedPreferences.getString("audio_format", "mp3")
|
||||
// autoCompleteTextView!!.setText(preference, false)
|
||||
// (audioFormat!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
// AdapterView.OnItemClickListener { adapterView: AdapterView<*>?, view: View?, index: Int, l: Long ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.audioFormat = audioFormats[index]
|
||||
// }
|
||||
// editor.putString("audio_format", audioFormats[index])
|
||||
// editor.apply()
|
||||
// }
|
||||
// } else {
|
||||
// bottomSheet!!.setContentView(R.layout.home_download_video_bottom_sheet)
|
||||
// val title = bottomSheet!!.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
// if (selectedObjects!!.size > 1) {
|
||||
// title!!.editText!!.setText(getString(R.string.mutliple_titles))
|
||||
// title.editText!!.isClickable = false
|
||||
// title.editText!!.isLongClickable = false
|
||||
// } else {
|
||||
// title!!.editText!!.setText(selectedObjects!![0]!!.title)
|
||||
// title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
// override fun beforeTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun onTextChanged(
|
||||
// charSequence: CharSequence,
|
||||
// i: Int,
|
||||
// i1: Int,
|
||||
// i2: Int
|
||||
// ) {
|
||||
// }
|
||||
//
|
||||
// override fun afterTextChanged(editable: Editable) {
|
||||
// val index = resultsList!!.indexOf(selectedObjects!![0])
|
||||
// resultsList!![index]!!.title = editable.toString()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// val videoFormats = context!!.resources.getStringArray(R.array.video_containers)
|
||||
// val videoQualities = context!!.resources.getStringArray(R.array.video_formats)
|
||||
// val videoFormat = bottomSheet!!.findViewById<TextInputLayout>(R.id.video_format)
|
||||
// var autoCompleteTextView =
|
||||
// bottomSheet!!.findViewById<AutoCompleteTextView>(R.id.video_format_textview)
|
||||
// var preference = sharedPreferences.getString("video_format", "webm")
|
||||
// autoCompleteTextView!!.setText(preference, false)
|
||||
// (videoFormat!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
// AdapterView.OnItemClickListener { adapterView: AdapterView<*>?, view: View?, index: Int, l: Long ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.videoFormat = videoFormats[index]
|
||||
// }
|
||||
// editor.putString("video_format", videoFormats[index])
|
||||
// editor.apply()
|
||||
// }
|
||||
// val videoQuality = bottomSheet!!.findViewById<TextInputLayout>(R.id.video_quality)
|
||||
// autoCompleteTextView = bottomSheet!!.findViewById(R.id.video_quality_textview)
|
||||
// preference = sharedPreferences.getString("video_quality", "Best Quality")
|
||||
// autoCompleteTextView!!.setText(preference, false)
|
||||
// (videoQuality!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
// AdapterView.OnItemClickListener { adapterView: AdapterView<*>?, view: View?, index: Int, l: Long ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.videoQuality = videoQualities[index]
|
||||
// }
|
||||
// editor.putString("video_quality", videoQualities[index])
|
||||
// editor.apply()
|
||||
// }
|
||||
// val embedSubs = bottomSheet!!.findViewById<Chip>(R.id.embed_subtitles)
|
||||
// embedSubs!!.isChecked = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
// embedSubs.setOnClickListener { view: View? ->
|
||||
// if (embedSubs.isChecked) {
|
||||
// editor.putBoolean("embed_subtitles", true)
|
||||
// } else {
|
||||
// editor.putBoolean("embed_subtitles", false)
|
||||
// }
|
||||
// editor.apply()
|
||||
// }
|
||||
// val addChapters = bottomSheet!!.findViewById<Chip>(R.id.add_chapters)
|
||||
// addChapters!!.isChecked = sharedPreferences.getBoolean("add_chapters", false)
|
||||
// addChapters.setOnClickListener { view: View? ->
|
||||
// if (addChapters.isChecked) {
|
||||
// editor.putBoolean("add_chapters", true)
|
||||
// } else {
|
||||
// editor.putBoolean("add_chapters", false)
|
||||
// }
|
||||
// editor.apply()
|
||||
// }
|
||||
// val saveThumbnail = bottomSheet!!.findViewById<Chip>(R.id.save_thumbnail)
|
||||
// saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
// saveThumbnail.setOnClickListener { view: View? ->
|
||||
// if (saveThumbnail.isChecked) {
|
||||
// editor.putBoolean("write_thumbnail", true)
|
||||
// } else {
|
||||
// editor.putBoolean("write_thumbnail", false)
|
||||
// }
|
||||
// editor.apply()
|
||||
// }
|
||||
// }
|
||||
// val cancel = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_cancel_button)
|
||||
// cancel!!.setOnClickListener { view: View? -> bottomSheet!!.cancel() }
|
||||
// val download = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
// download!!.setOnClickListener { view: View? ->
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// selectedObjects = ArrayList()
|
||||
// homeAdapter!!.clearCheckedVideos()
|
||||
// downloadFabs!!.visibility = View.GONE
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
// bottomSheet!!.cancel()
|
||||
// }
|
||||
bottomSheet!!.show()
|
||||
bottomSheet!!.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.printStackTrace().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertFileSize(s: Long): String{
|
||||
if (s <= 0) return "0"
|
||||
val units = arrayOf("B", "kB", "MB", "GB", "TB")
|
||||
val digitGroups = (log10(s.toDouble()) / log10(1024.0)).toInt()
|
||||
return DecimalFormat("#,##0.#").format(s / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "HomeFragment"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,154 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.ui.HomeFragment
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
class DownloadAudioFragment(item: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private lateinit var resultViewModel : ResultViewModel
|
||||
private lateinit var fileUtil : FileUtil
|
||||
private val downloadItem = item
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_download_audio, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
|
||||
fileUtil = FileUtil()
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val resultItem = resultViewModel.getItemByURL(downloadItem.url)
|
||||
val type = downloadItem.type
|
||||
|
||||
val sharedPreferences =
|
||||
requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
|
||||
try {
|
||||
val title = view.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
title!!.editText!!.setText(downloadItem.title)
|
||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
resultItem.title = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
}
|
||||
})
|
||||
|
||||
val author = view.findViewById<TextInputLayout>(R.id.author_textinput)
|
||||
author!!.editText!!.setText(downloadItem.author)
|
||||
author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
resultItem.author = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
}
|
||||
})
|
||||
|
||||
val saveDir = view.findViewById<TextInputLayout>(R.id.outputPath)
|
||||
saveDir!!.editText!!.setText(
|
||||
sharedPreferences.getString(
|
||||
"music_path",
|
||||
getString(R.string.music_path)
|
||||
)
|
||||
)
|
||||
saveDir.editText!!.isFocusable = false;
|
||||
saveDir.editText!!.isClickable = true;
|
||||
saveDir.editText!!.setOnClickListener {
|
||||
Toast.makeText(context, "TEST", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
val formats = resultViewModel.getFormats(resultItem, type)
|
||||
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
it.format_note.replace("AUDIO_QUALITY_", "") +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
else it.format_note +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
}
|
||||
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
formatTitles
|
||||
)
|
||||
)
|
||||
if (formatTitles.isNotEmpty()){
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.formatDesc = formats[index].format_note
|
||||
downloadItem.audioFormatId = formats[index].format_id
|
||||
}
|
||||
|
||||
val containers = requireContext().resources.getStringArray(R.array.audio_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
|
||||
container?.isEnabled = true
|
||||
containerAutoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
containers
|
||||
)
|
||||
)
|
||||
val selectedContainer: String = formats.find { downloadItem.formatDesc == it.format_note }?.container
|
||||
?: sharedPreferences.getString("audio_format", "mp3")!!
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
}
|
||||
|
||||
}catch (e : Exception){
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.get
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
|
||||
class DownloadBottomSheetDialog(item: DownloadItem) : BottomSheetDialogFragment() {
|
||||
private lateinit var tabLayout: TabLayout
|
||||
private lateinit var viewPager2: ViewPager2
|
||||
private lateinit var fragmentAdapter : DownloadFragmentAdapter
|
||||
private val downloadItem = item
|
||||
private lateinit var downloadViewModel: DownloadViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
override fun setupDialog(dialog: Dialog, style: Int) {
|
||||
super.setupDialog(dialog, style)
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.download_bottom_sheet, null)
|
||||
dialog.setContentView(view)
|
||||
|
||||
tabLayout = view.findViewById(R.id.download_tablayout)
|
||||
viewPager2 = view.findViewById(R.id.download_viewpager)
|
||||
|
||||
val fragmentManager = parentFragmentManager
|
||||
fragmentAdapter = DownloadFragmentAdapter(downloadItem, fragmentManager, lifecycle)
|
||||
viewPager2.adapter = fragmentAdapter
|
||||
|
||||
when(downloadItem.type) {
|
||||
"audio" -> {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(0))
|
||||
viewPager2.setCurrentItem(0, false)
|
||||
}
|
||||
"video" -> {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(1))
|
||||
viewPager2.setCurrentItem(1, false)
|
||||
}
|
||||
"command" -> {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(2))
|
||||
viewPager2.setCurrentItem(2, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||
viewPager2.currentItem = tab!!.position
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab?) {
|
||||
}
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab?) {
|
||||
}
|
||||
})
|
||||
|
||||
viewPager2.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(position))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCancel(dialog: DialogInterface) {
|
||||
super.onCancel(dialog)
|
||||
downloadViewModel.deleteDownload(downloadItem)
|
||||
}
|
||||
|
||||
fun dismissSelf(){
|
||||
this.dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
|
||||
class DownloadCommandFragment(item: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private val downloadItem = item
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_download_command, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
return fragmentView
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
|
||||
class DownloadFragmentAdapter (item : DownloadItem, fragmentManager : FragmentManager, lifecycle : Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
private val downloadItem = item
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return 3
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
when (position) {
|
||||
0 -> {
|
||||
downloadItem.type = "audio"
|
||||
return DownloadAudioFragment(downloadItem)
|
||||
}
|
||||
1 -> {
|
||||
downloadItem.type = "video"
|
||||
return DownloadVideoFragment(downloadItem)
|
||||
}
|
||||
}
|
||||
downloadItem.type = "command"
|
||||
return DownloadCommandFragment(downloadItem)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadcard
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.deniscerri.ytdlnis.MainActivity
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
class DownloadVideoFragment(item: DownloadItem) : Fragment() {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private var mainActivity: MainActivity? = null
|
||||
private lateinit var resultViewModel : ResultViewModel
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var fileUtil : FileUtil
|
||||
private val downloadItem = item
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||
fragmentView = inflater.inflate(R.layout.fragment_download_video, container, false)
|
||||
activity = getActivity()
|
||||
mainActivity = activity as MainActivity?
|
||||
resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java]
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
fileUtil = FileUtil()
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val resultItem = resultViewModel.getItemByURL(downloadItem.url)
|
||||
val type = downloadItem.type
|
||||
|
||||
val sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE)
|
||||
val editor = sharedPreferences.edit()
|
||||
|
||||
try {
|
||||
val title = view.findViewById<TextInputLayout>(R.id.title_textinput)
|
||||
title!!.editText!!.setText(downloadItem.title)
|
||||
title.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.title = p0.toString()
|
||||
resultItem.title = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
|
||||
val author = view.findViewById<TextInputLayout>(R.id.author_textinput)
|
||||
author!!.editText!!.setText(downloadItem.author)
|
||||
author.editText!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
downloadItem.author = p0.toString()
|
||||
resultItem.author = p0.toString()
|
||||
resultViewModel.update(resultItem)
|
||||
downloadViewModel.updateDownload(downloadItem)
|
||||
}
|
||||
})
|
||||
|
||||
val saveDir = view.findViewById<TextInputLayout>(R.id.outputPath)
|
||||
saveDir!!.editText!!.setText(
|
||||
sharedPreferences.getString(
|
||||
"video_path",
|
||||
getString(R.string.video_path)
|
||||
)
|
||||
)
|
||||
saveDir.editText!!.isFocusable = false;
|
||||
saveDir.editText!!.isClickable = true;
|
||||
saveDir.editText!!.setOnClickListener {
|
||||
Toast.makeText(context, "TEST", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
val formats = resultViewModel.getFormats(resultItem, type)
|
||||
|
||||
val formatTitles = formats.map {
|
||||
if (it.format_note.contains("AUDIO_QUALITY_"))
|
||||
it.format_note.replace("AUDIO_QUALITY_", "") +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
else it.format_note +
|
||||
if (it.filesize == 0L) "" else " / " + fileUtil.convertFileSize(it.filesize)
|
||||
}
|
||||
|
||||
val format = view.findViewById<TextInputLayout>(R.id.format)
|
||||
val autoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.format_textview)
|
||||
autoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
formatTitles
|
||||
)
|
||||
)
|
||||
if (formatTitles.isNotEmpty()) {
|
||||
autoCompleteTextView!!.setText(formatTitles[formats.lastIndex], false)
|
||||
}
|
||||
(format!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.formatDesc = formats[index].format_note
|
||||
downloadItem.videoFormatId = formats[index].format_id
|
||||
}
|
||||
|
||||
val containers = requireContext().resources.getStringArray(R.array.video_containers)
|
||||
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
|
||||
val containerAutoCompleteTextView =
|
||||
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
|
||||
|
||||
container?.isEnabled = true
|
||||
containerAutoCompleteTextView?.setAdapter(
|
||||
ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
containers
|
||||
)
|
||||
)
|
||||
val selectedContainer: String =
|
||||
formats.find { downloadItem.formatDesc == it.format_note }?.container
|
||||
?: sharedPreferences.getString("video_format", "DEFAULT")!!
|
||||
containerAutoCompleteTextView!!.setText(selectedContainer, false)
|
||||
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
|
||||
downloadItem.ext = containers[index]
|
||||
}
|
||||
|
||||
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
|
||||
embedSubs!!.isChecked = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||
|
||||
val addChapters = view.findViewById<Chip>(R.id.add_chapters)
|
||||
addChapters!!.isChecked = sharedPreferences.getBoolean("add_chapters", false)
|
||||
|
||||
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
|
||||
saveThumbnail!!.isChecked = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||
|
||||
|
||||
val cancel = view.findViewById<Button>(R.id.bottomsheet_cancel_button)
|
||||
cancel!!.setOnClickListener {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
val download = view.findViewById<Button>(R.id.bottomsheet_download_button)
|
||||
download!!.setOnClickListener {
|
||||
// for (i in selectedObjects!!.indices) {
|
||||
// val vid = findVideo(
|
||||
// selectedObjects!![i]!!.getURL()
|
||||
// )
|
||||
// vid!!.downloadedType = type
|
||||
// updateDownloadingStatusOnResult(vid, type, true)
|
||||
// homeAdapter!!.notifyItemChanged(resultsList!!.indexOf(vid))
|
||||
// downloadQueue!!.add(vid)
|
||||
// }
|
||||
// selectedObjects = ArrayList()
|
||||
// homeAdapter!!.clearCheckedVideos()
|
||||
// downloadFabs!!.visibility = View.GONE
|
||||
// if (isStoragePermissionGranted) {
|
||||
// mainActivity!!.startDownloadService(downloadQueue, listener)
|
||||
// downloadQueue!!.clear()
|
||||
// }
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,9 @@ import com.deniscerri.ytdlnis.database.models.DownloadItem
|
|||
import java.io.File
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.pow
|
||||
|
||||
class FileUtil() {
|
||||
|
||||
|
|
@ -118,4 +121,11 @@ class FileUtil() {
|
|||
}
|
||||
originDir.delete()
|
||||
}
|
||||
|
||||
fun convertFileSize(s: Long): String{
|
||||
if (s <= 0) return "0"
|
||||
val units = arrayOf("B", "kB", "MB", "GB", "TB")
|
||||
val digitGroups = (log10(s.toDouble()) / log10(1024.0)).toInt()
|
||||
return DecimalFormat("#,##0.#").format(s / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
|
||||
}
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ class InfoUtil(context: Context) {
|
|||
val downloadedVideo = databaseManager!!.checkDownloaded(url, "video")
|
||||
val isPlaylist = 0
|
||||
video = ResultItemWithFormats(
|
||||
ResultItem(
|
||||
ResultItem(0,
|
||||
url,
|
||||
title,
|
||||
author,
|
||||
|
|
@ -299,7 +299,7 @@ class InfoUtil(context: Context) {
|
|||
}
|
||||
|
||||
video = ResultItemWithFormats(
|
||||
ResultItem(
|
||||
ResultItem(0,
|
||||
url,
|
||||
title,
|
||||
author,
|
||||
|
|
@ -514,8 +514,9 @@ class InfoUtil(context: Context) {
|
|||
formats.add(Gson().fromJson(format, Format::class.java))
|
||||
}
|
||||
}
|
||||
Log.e(TAG, formats.toString())
|
||||
items.add(ResultItemWithFormats(
|
||||
ResultItem(
|
||||
ResultItem(0,
|
||||
url,
|
||||
title,
|
||||
author!!,
|
||||
|
|
|
|||
|
|
@ -97,12 +97,9 @@ class DownloadWorker(
|
|||
request.addOption("-x")
|
||||
var audioQualityId : String = downloadItem.audioFormatId
|
||||
if (audioQualityId == "0") audioQualityId = "ba"
|
||||
var format = downloadItem.audioFormat
|
||||
if (format.isEmpty()){
|
||||
format = sharedPreferences.getString("audio_format", "")!!
|
||||
}
|
||||
var ext = downloadItem.ext
|
||||
request.addOption("-f", audioQualityId)
|
||||
request.addOption("--audio-format", format)
|
||||
request.addOption("--audio-format", ext)
|
||||
request.addOption("--embed-metadata")
|
||||
|
||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||
|
|
@ -142,15 +139,13 @@ class DownloadWorker(
|
|||
if (embedSubs) {
|
||||
request.addOption("--embed-subs", "")
|
||||
}
|
||||
var videoQualityId = downloadItem.videoFormatId
|
||||
val audioQualityId = downloadItem.audioFormatId
|
||||
if (videoQualityId.isEmpty()) videoQualityId = "bestvideo"
|
||||
val formatArgument = StringBuilder(videoQualityId)
|
||||
if (videoQualityId != "worst"){
|
||||
if (audioQualityId != "0") formatArgument.append("+", audioQualityId, "/best")
|
||||
}
|
||||
var videoFormatID = downloadItem.videoFormatId
|
||||
val audioFormatID = downloadItem.audioFormatId
|
||||
if (videoFormatID.isEmpty()) videoFormatID = "bestvideo"
|
||||
val formatArgument = StringBuilder(videoFormatID)
|
||||
if (audioFormatID != "0") formatArgument.append("+", audioFormatID, "/best")
|
||||
request.addOption("-f", formatArgument.toString())
|
||||
var format = downloadItem.videoFormat
|
||||
var format = downloadItem.ext
|
||||
if (format.isNotEmpty()) {
|
||||
format = sharedPreferences.getString("video_format", "")!!
|
||||
if (format != "DEFAULT") request.addOption("--merge-output-format", format)
|
||||
|
|
@ -166,7 +161,7 @@ class DownloadWorker(
|
|||
}
|
||||
"command" -> {
|
||||
val commandRegex = "\"([^\"]*)\"|(\\S+)"
|
||||
val command = commandTemplateDao.getTemplateById(downloadItem.customTemplateId)
|
||||
val command = commandTemplateDao.getTemplate(downloadItem.customTemplateId)
|
||||
val m = Pattern.compile(commandRegex).matcher(command.content)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
|
|
@ -198,7 +193,7 @@ class DownloadWorker(
|
|||
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)
|
||||
val historyItem = HistoryItem(0, downloadItem.url, downloadItem.title, downloadItem.author, downloadItem.duration, downloadItem.thumb, downloadItem.type, unixtime, downloadItem.downloadPath, downloadItem.website)
|
||||
runBlocking {
|
||||
historyDao.insert(historyItem)
|
||||
}
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_history.xml
Normal file
5
app/src/main/res/drawable/ic_history.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
|
||||
</vector>
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
android:id="@+id/bottomNavigationView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:labelVisibilityMode="labeled"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
|
|
|
|||
58
app/src/main/res/layout/download_bottom_sheet.xml
Normal file
58
app/src/main/res/layout/download_bottom_sheet.xml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="20sp"
|
||||
android:paddingTop="10dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="15sp"
|
||||
android:paddingBottom="10dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/configure_download" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
app:tabMode="scrollable"
|
||||
app:tabGravity="center"
|
||||
android:id="@+id/download_tablayout" >
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/audio" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/video" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/run_command" />
|
||||
|
||||
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/download_viewpager" />
|
||||
|
||||
</LinearLayout>
|
||||
159
app/src/main/res/layout/fragment_download_audio.xml
Normal file
159
app/src/main/res/layout/fragment_download_audio.xml
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
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:padding="10dp"
|
||||
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="10dp"
|
||||
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_height="wrap_content"
|
||||
android:layout_weight="40"
|
||||
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/downloadContainer"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/container">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/container_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/audio_containers"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="10dp"
|
||||
android:hint="@string/format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/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/outputPath"
|
||||
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>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_clock" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
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:text="@string/cancel"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_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>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
200
app/src/main/res/layout/fragment_download_command.xml
Normal file
200
app/src/main/res/layout/fragment_download_command.xml
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
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:padding="10dp"
|
||||
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="10dp"
|
||||
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_height="wrap_content"
|
||||
android:layout_weight="40"
|
||||
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/downloadContainer"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/container">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/container_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/audio_containers"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="10dp"
|
||||
android:hint="@string/format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/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/outputPath"
|
||||
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>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/adjust_commands"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_clock" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
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:text="@string/cancel"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_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>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
216
app/src/main/res/layout/fragment_download_video.xml
Normal file
216
app/src/main/res/layout/fragment_download_video.xml
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
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:padding="10dp"
|
||||
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="10dp"
|
||||
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_height="wrap_content"
|
||||
android:layout_weight="40"
|
||||
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/downloadContainer"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="45"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/container">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/container_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/audio_containers"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="10dp"
|
||||
android:hint="@string/format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/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/outputPath"
|
||||
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>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/adjust_video"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
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
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_clock" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
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:text="@string/cancel"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_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>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
||||
app:title="@string/downloads"
|
||||
app:title="@string/history"
|
||||
app:menu="@menu/downloads_menu"
|
||||
android:theme="@style/Toolbar"
|
||||
/>
|
||||
|
|
@ -130,25 +130,25 @@
|
|||
android:layout_margin="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
<include layout="@layout/downloads_card_shimmer" />
|
||||
<include layout="@layout/history_card_shimmer" />
|
||||
|
||||
|
||||
|
||||
|
|
@ -178,11 +178,11 @@
|
|||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
<include layout="@layout/downloads_no_results"
|
||||
<include layout="@layout/history_no_results"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
<include layout="@layout/downloads_bottom_sheet"
|
||||
<include layout="@layout/history_item_details_bottom_sheet"
|
||||
android:visibility="gone" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_textinput"
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -27,33 +26,35 @@
|
|||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/author_textinput"
|
||||
android:layout_width="match_parent"
|
||||
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>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="15dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/author_textinput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="40"
|
||||
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/downloadContainer"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="30"
|
||||
android:layout_weight="45"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/container">
|
||||
|
||||
|
|
@ -67,30 +68,29 @@
|
|||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:paddingStart="10dp"
|
||||
android:layout_weight="65"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/format_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="none"
|
||||
app:simpleItems="@array/audio_formats"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/format"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="20dp"
|
||||
android:hint="@string/format">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/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/outputPath_textinput"
|
||||
android:id="@+id/outputPath"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:errorEnabled="true"
|
||||
|
|
@ -100,12 +100,12 @@
|
|||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="text"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/downloadChipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:selectionRequired="true"
|
||||
|
|
@ -144,108 +144,9 @@
|
|||
|
||||
</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>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
<item android:title="@string/home"
|
||||
android:icon="@drawable/ic_home"
|
||||
android:id="@+id/home"/>
|
||||
<item android:title="@string/history"
|
||||
android:icon="@drawable/ic_history"
|
||||
android:id="@+id/history"/>
|
||||
<item android:title="@string/downloads"
|
||||
android:icon="@drawable/ic_downloads"
|
||||
android:id="@+id/downloads"/>
|
||||
|
|
|
|||
|
|
@ -165,4 +165,6 @@
|
|||
<string name="defaultValue">Default</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="container">Container</string>
|
||||
<string name="template">Template</string>
|
||||
<string name="history">History</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue