fixed bugs with custom command and other small things
This commit is contained in:
parent
895476aa01
commit
5fed145313
24 changed files with 765 additions and 600 deletions
|
|
@ -320,7 +320,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/content_paste/baseline_content_paste_24.xml" />
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/content_copy/baseline_content_copy_24.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
@ -330,7 +330,7 @@
|
|||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="outputName" value="ic_clipboard" />
|
||||
<entry key="outputName" value="ic_copy" />
|
||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\adaptiveproduct_youtube_foreground_color_108 (1).svg" />
|
||||
</map>
|
||||
</option>
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
import org.w3c.dom.Text
|
||||
import java.io.File
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class CancelledDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, CancelledDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
private var fileUtil: FileUtil
|
||||
|
||||
init {
|
||||
this.onItemClickListener = onItemClickListener
|
||||
this.activity = activity
|
||||
fileUtil = FileUtil()
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: MaterialCardView
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.queued_download_card_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.queued_download_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.image_view)
|
||||
val imageURL = item!!.thumb
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
if (imageURL.isNotEmpty()) {
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
} else {
|
||||
uiHandler.post { Picasso.get().load(R.color.black).into(thumbnail) }
|
||||
}
|
||||
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemTitle = card.findViewById<TextView>(R.id.title)
|
||||
var title = item.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title
|
||||
|
||||
val formatNote = card.findViewById<TextView>(R.id.format_note)
|
||||
formatNote.text = item.format.format_note
|
||||
val codec = card.findViewById<TextView>(R.id.codec)
|
||||
val codecText =
|
||||
if (item.format.encoding != "") {
|
||||
item.format.encoding.uppercase()
|
||||
}else if (item.format.vcodec != "none" && item.format.vcodec != ""){
|
||||
item.format.vcodec.uppercase()
|
||||
} else {
|
||||
item.format.acodec.uppercase()
|
||||
}
|
||||
if (codecText == "" || codecText == "none"){
|
||||
codec.visibility = View.GONE
|
||||
}else{
|
||||
codec.visibility = View.VISIBLE
|
||||
codec.text = codecText
|
||||
}
|
||||
|
||||
val fileSize = card.findViewById<TextView>(R.id.file_size)
|
||||
fileSize.text = fileUtil.convertFileSize(item.format.filesize)
|
||||
val downloadStartTime = card.findViewById<TextView>(R.id.time)
|
||||
val time = item.downloadStartTime
|
||||
if (time == 0L) {
|
||||
downloadStartTime.visibility = View.GONE
|
||||
} else {
|
||||
downloadStartTime.visibility = View.VISIBLE
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(time * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
downloadStartTime.text = "$day $month $year - $timeString"
|
||||
}
|
||||
|
||||
// CANCEL BUTTON ----------------------------------
|
||||
val cancelButton = card.findViewById<MaterialButton>(R.id.queued_download_cancel)
|
||||
if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
|
||||
|
||||
cancelButton.setOnClickListener {
|
||||
onItemClickListener.onQueuedCancelClick(item.id)
|
||||
}
|
||||
|
||||
}
|
||||
interface OnItemClickListener {
|
||||
fun onQueuedCancelClick(itemID: Long)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<DownloadItem> = object : DiffUtil.ItemCallback<DownloadItem>() {
|
||||
override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||
val ranged = arrayListOf(oldItem.id, newItem.id)
|
||||
return ranged[0] == ranged[1]
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||
return oldItem.url == newItem.url && oldItem.format.format_id == newItem.format.format_id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +1,33 @@
|
|||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.DownloadVideoFragment
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
import org.w3c.dom.Text
|
||||
import java.io.File
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class ErroredDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, ErroredDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, GenericDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
private var fileUtil: FileUtil
|
||||
|
|
@ -47,40 +41,43 @@ class ErroredDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: MaterialCardView
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.queued_download_card_view)
|
||||
cardView = itemView.findViewById(R.id.download_card_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.queued_download_card, parent, false)
|
||||
.inflate(R.layout.generic_download_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.image_view)
|
||||
val imageURL = item!!.thumb
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
if (imageURL.isNotEmpty()) {
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
} else {
|
||||
uiHandler.post { Picasso.get().load(R.color.black).into(thumbnail) }
|
||||
}
|
||||
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemTitle = card.findViewById<TextView>(R.id.title)
|
||||
var title = item.title
|
||||
var title = item!!.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemUrl = card.findViewById<TextView>(R.id.url)
|
||||
itemUrl.text = item.url
|
||||
|
||||
val type = card.findViewById<TextView>(R.id.type)
|
||||
type!!.text = item.type.toString().uppercase()
|
||||
|
||||
val formatNote = card.findViewById<TextView>(R.id.format_note)
|
||||
formatNote.text = item.format.format_note
|
||||
if (item.type == DownloadViewModel.Type.command){
|
||||
formatNote.visibility = View.GONE
|
||||
}else{
|
||||
formatNote.text = item.format.format_note
|
||||
}
|
||||
|
||||
|
||||
val codec = card.findViewById<TextView>(R.id.codec)
|
||||
val codecText =
|
||||
if (item.format.encoding != "") {
|
||||
|
|
@ -98,35 +95,34 @@ class ErroredDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
}
|
||||
|
||||
val fileSize = card.findViewById<TextView>(R.id.file_size)
|
||||
fileSize.text = fileUtil.convertFileSize(item.format.filesize)
|
||||
val downloadStartTime = card.findViewById<TextView>(R.id.time)
|
||||
val time = item.downloadStartTime
|
||||
if (time == 0L) {
|
||||
downloadStartTime.visibility = View.GONE
|
||||
} else {
|
||||
downloadStartTime.visibility = View.VISIBLE
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(time * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
downloadStartTime.text = "$day $month $year - $timeString"
|
||||
val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize)
|
||||
if (fileSizeReadable == "?") fileSize.visibility = View.GONE
|
||||
else fileSize.text = fileSizeReadable
|
||||
|
||||
// ACTION BUTTON ----------------------------------
|
||||
val actionButton = card.findViewById<MaterialButton>(R.id.action_button)
|
||||
if (actionButton.hasOnClickListeners()) actionButton.setOnClickListener(null)
|
||||
|
||||
when(item.status){
|
||||
DownloadRepository.Status.Cancelled.toString() -> actionButton.setIconResource(R.drawable.ic_refresh)
|
||||
DownloadRepository.Status.Queued.toString() -> actionButton.setIconResource(R.drawable.ic_baseline_delete_outline_24)
|
||||
else -> actionButton.setIconResource(R.drawable.ic_baseline_file_open_24)
|
||||
}
|
||||
|
||||
// CANCEL BUTTON ----------------------------------
|
||||
val cancelButton = card.findViewById<MaterialButton>(R.id.queued_download_cancel)
|
||||
if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
|
||||
|
||||
cancelButton.setOnClickListener {
|
||||
onItemClickListener.onQueuedCancelClick(item.id)
|
||||
|
||||
actionButton.setOnClickListener {
|
||||
onItemClickListener.onActionButtonClick(item.id)
|
||||
}
|
||||
|
||||
card.setOnClickListener {
|
||||
onItemClickListener.onCardClick(item.id)
|
||||
}
|
||||
|
||||
}
|
||||
interface OnItemClickListener {
|
||||
fun onQueuedCancelClick(itemID: Long)
|
||||
fun onActionButtonClick(itemID: Long)
|
||||
fun onCardClick(itemID: Long)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
@ -124,8 +124,10 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
|
|||
}
|
||||
if (item.type == DownloadViewModel.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 {
|
||||
} else if (item.type == DownloadViewModel.Type.video) {
|
||||
if (filePresent) btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video_downloaded) else btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_video)
|
||||
}else{
|
||||
btn.icon = ContextCompat.getDrawable(activity, R.drawable.ic_terminal)
|
||||
}
|
||||
if (btn.hasOnClickListeners()) btn.setOnClickListener(null)
|
||||
if (checkedItems.contains(item.id)) {
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
package com.deniscerri.ytdlnis.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.squareup.picasso.Picasso
|
||||
import org.w3c.dom.Text
|
||||
import java.io.File
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class QueuedDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<DownloadItem?, QueuedDownloadAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
|
||||
private val onItemClickListener: OnItemClickListener
|
||||
private val activity: Activity
|
||||
private var fileUtil: FileUtil
|
||||
|
||||
init {
|
||||
this.onItemClickListener = onItemClickListener
|
||||
this.activity = activity
|
||||
fileUtil = FileUtil()
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) {
|
||||
val cardView: MaterialCardView
|
||||
init {
|
||||
cardView = itemView.findViewById(R.id.queued_download_card_view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val cardView = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.queued_download_card, parent, false)
|
||||
return ViewHolder(cardView, onItemClickListener)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
val card = holder.cardView
|
||||
// THUMBNAIL ----------------------------------
|
||||
val thumbnail = card.findViewById<ImageView>(R.id.image_view)
|
||||
val imageURL = item!!.thumb
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
if (imageURL.isNotEmpty()) {
|
||||
uiHandler.post { Picasso.get().load(imageURL).into(thumbnail) }
|
||||
} else {
|
||||
uiHandler.post { Picasso.get().load(R.color.black).into(thumbnail) }
|
||||
}
|
||||
thumbnail.setColorFilter(Color.argb(95, 0, 0, 0))
|
||||
|
||||
// TITLE ----------------------------------
|
||||
val itemTitle = card.findViewById<TextView>(R.id.title)
|
||||
var title = item.title
|
||||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title
|
||||
|
||||
val formatNote = card.findViewById<TextView>(R.id.format_note)
|
||||
formatNote.text = item.format.format_note
|
||||
val codec = card.findViewById<TextView>(R.id.codec)
|
||||
val codecText =
|
||||
if (item.format.encoding != "") {
|
||||
item.format.encoding.uppercase()
|
||||
}else if (item.format.vcodec != "none" && item.format.vcodec != ""){
|
||||
item.format.vcodec.uppercase()
|
||||
} else {
|
||||
item.format.acodec.uppercase()
|
||||
}
|
||||
if (codecText == "" || codecText == "none"){
|
||||
codec.visibility = View.GONE
|
||||
}else{
|
||||
codec.visibility = View.VISIBLE
|
||||
codec.text = codecText
|
||||
}
|
||||
|
||||
val fileSize = card.findViewById<TextView>(R.id.file_size)
|
||||
fileSize.text = fileUtil.convertFileSize(item.format.filesize)
|
||||
val downloadStartTime = card.findViewById<TextView>(R.id.time)
|
||||
val time = item.downloadStartTime
|
||||
if (time == 0L) {
|
||||
downloadStartTime.visibility = View.GONE
|
||||
} else {
|
||||
downloadStartTime.visibility = View.VISIBLE
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(time * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
downloadStartTime.text = "$day $month $year - $timeString"
|
||||
}
|
||||
|
||||
// CANCEL BUTTON ----------------------------------
|
||||
val cancelButton = card.findViewById<MaterialButton>(R.id.queued_download_cancel)
|
||||
if (cancelButton.hasOnClickListeners()) cancelButton.setOnClickListener(null)
|
||||
|
||||
cancelButton.setOnClickListener {
|
||||
onItemClickListener.onQueuedCancelClick(item.id)
|
||||
}
|
||||
|
||||
}
|
||||
interface OnItemClickListener {
|
||||
fun onQueuedCancelClick(itemID: Long)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK: DiffUtil.ItemCallback<DownloadItem> = object : DiffUtil.ItemCallback<DownloadItem>() {
|
||||
override fun areItemsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||
val ranged = arrayListOf(oldItem.id, newItem.id)
|
||||
return ranged[0] == ranged[1]
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: DownloadItem, newItem: DownloadItem): Boolean {
|
||||
return oldItem.url == newItem.url && oldItem.format.format_id == newItem.format.format_id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -47,11 +47,11 @@ class TemplatesAdapter(onItemClickListener: OnItemClickListener, activity: Activ
|
|||
val content = card.findViewById<TextView>(R.id.content)
|
||||
content.text = item?.content
|
||||
|
||||
val check = card.findViewById<Button>(R.id.check)
|
||||
|
||||
check.setOnClickListener {
|
||||
onItemClickListener.onSelected(item!!)
|
||||
}
|
||||
// val check = card.findViewById<Button>(R.id.check)
|
||||
//
|
||||
// check.setOnClickListener {
|
||||
// onItemClickListener.onSelected(item!!)
|
||||
// }
|
||||
|
||||
title.setOnClickListener {
|
||||
onItemClickListener.onItemClick(item!!)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.deniscerri.ytdlnis.ui
|
|||
import android.app.Activity
|
||||
import android.content.*
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
|
@ -13,7 +12,6 @@ import android.view.*
|
|||
import android.view.View.*
|
||||
import android.widget.*
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
|
|
@ -28,6 +26,7 @@ import com.deniscerri.ytdlnis.database.repository.HistoryRepository.HistorySort
|
|||
import com.deniscerri.ytdlnis.database.viewmodel.HistoryViewModel
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHistoryBinding
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.UiUtil
|
||||
import com.facebook.shimmer.ShimmerFrameLayout
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
|
|
@ -64,7 +63,7 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
private var selectedObjects: ArrayList<HistoryItem>? = null
|
||||
private var deleteFab: ExtendedFloatingActionButton? = null
|
||||
private var fileUtil: FileUtil? = null
|
||||
|
||||
private var uiUtil: UiUtil? = null
|
||||
private var _binding : FragmentHistoryBinding? = null
|
||||
|
||||
override fun onCreateView(
|
||||
|
|
@ -91,6 +90,7 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
websiteGroup = view.findViewById(R.id.website_chip_group)
|
||||
deleteFab = view.findViewById(R.id.delete_selected_fab)
|
||||
fileUtil = FileUtil()
|
||||
uiUtil = UiUtil(FileUtil())
|
||||
deleteFab?.tag = "deleteSelected"
|
||||
deleteFab?.setOnClickListener{
|
||||
removeSelectedItems()
|
||||
|
|
@ -144,7 +144,7 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
initChips()
|
||||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
private fun scrollToTop() {
|
||||
recyclerView!!.scrollToPosition(0)
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
(topAppBar!!.parent as AppBarLayout).setExpanded(
|
||||
|
|
@ -372,41 +372,13 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
deleteDialog.show()
|
||||
}
|
||||
|
||||
private fun copyLinkToClipBoard(url: String) {
|
||||
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(getString(R.string.url), url)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
Toast.makeText(context, getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun openLinkIntent(url: String) {
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = Uri.parse(url)
|
||||
if (bottomSheet != null) bottomSheet!!.hide()
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
private fun openFileIntent(downloadPath: String) {
|
||||
val file = File(downloadPath)
|
||||
val uri = FileProvider.getUriForFile(
|
||||
fragmentContext!!,
|
||||
fragmentContext!!.packageName + ".fileprovider",
|
||||
file
|
||||
)
|
||||
val mime = mainActivity!!.contentResolver.getType(uri)
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.setDataAndType(uri, mime)
|
||||
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
override fun onCardClick(videoID: Long, isPresent: Boolean) {
|
||||
override fun onCardClick(itemID: Long, isPresent: Boolean) {
|
||||
bottomSheet = BottomSheetDialog(fragmentContext!!)
|
||||
bottomSheet!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet!!.setContentView(R.layout.history_item_details_bottom_sheet)
|
||||
val video = findItem(videoID)
|
||||
val video = findItem(itemID)
|
||||
val title = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_title)
|
||||
title!!.text = video!!.title
|
||||
val author = bottomSheet!!.findViewById<TextView>(R.id.bottom_sheet_author)
|
||||
|
|
@ -414,23 +386,23 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
val link = bottomSheet!!.findViewById<Button>(R.id.bottom_sheet_link)
|
||||
val url = video.url
|
||||
link!!.text = url
|
||||
link.tag = videoID
|
||||
link.tag = itemID
|
||||
link.setOnClickListener{
|
||||
openLinkIntent(video.url)
|
||||
uiUtil!!.openLinkIntent(requireContext(), video.url, bottomSheet)
|
||||
}
|
||||
link.setOnLongClickListener{
|
||||
copyLinkToClipBoard(video.url)
|
||||
uiUtil!!.copyLinkToClipBoard(requireContext(), video.url, bottomSheet)
|
||||
true
|
||||
}
|
||||
val remove = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.tag = videoID
|
||||
remove!!.tag = itemID
|
||||
remove.setOnClickListener{
|
||||
removeItem(video)
|
||||
}
|
||||
val openFile = bottomSheet!!.findViewById<Button>(R.id.bottomsheet_open_file_button)
|
||||
openFile!!.tag = videoID
|
||||
openFile!!.tag = itemID
|
||||
openFile.setOnClickListener{
|
||||
openFileIntent(video.downloadPath)
|
||||
uiUtil!!.openFileIntent(requireContext(), video.downloadPath)
|
||||
}
|
||||
if (!isPresent) openFile.visibility = GONE
|
||||
bottomSheet!!.show()
|
||||
|
|
@ -440,8 +412,8 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
|||
)
|
||||
}
|
||||
|
||||
override fun onCardSelect(videoID: Long, isChecked: Boolean) {
|
||||
val item = findItem(videoID)
|
||||
override fun onCardSelect(itemID: Long, isChecked: Boolean) {
|
||||
val item = findItem(itemID)
|
||||
if (isChecked) selectedObjects!!.add(item!!)
|
||||
else selectedObjects!!.remove(item)
|
||||
if (selectedObjects!!.size > 1) {
|
||||
|
|
|
|||
|
|
@ -1,55 +1,50 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadqueue
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.DialogInterface
|
||||
import android.content.res.Configuration
|
||||
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.widget.AdapterView
|
||||
import android.view.Window
|
||||
import android.widget.AdapterView.OnItemClickListener
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.ActiveDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.CancelledDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.FormatSelectionBottomSheetDialog
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.OnFormatClickListener
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.UiUtil
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.launch
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.w3c.dom.Text
|
||||
import java.sql.Date
|
||||
import java.sql.Timestamp
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
class CancelledDownloadsFragment() : Fragment(), CancelledDownloadAdapter.OnItemClickListener, OnItemClickListener {
|
||||
class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var cancelledRecyclerView : RecyclerView
|
||||
private lateinit var cancelledDownloads : CancelledDownloadAdapter
|
||||
lateinit var downloadItem: DownloadItem
|
||||
private lateinit var cancelledDownloads : GenericDownloadAdapter
|
||||
private lateinit var items : List<DownloadItem>
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var uiUtil : UiUtil
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
|
@ -60,6 +55,9 @@ class CancelledDownloadsFragment() : Fragment(), CancelledDownloadAdapter.OnItem
|
|||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||
activity = getActivity()
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
items = listOf()
|
||||
fileUtil = FileUtil()
|
||||
uiUtil = UiUtil(fileUtil)
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +65,7 @@ class CancelledDownloadsFragment() : Fragment(), CancelledDownloadAdapter.OnItem
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
cancelledDownloads =
|
||||
CancelledDownloadAdapter(
|
||||
GenericDownloadAdapter(
|
||||
this,
|
||||
requireActivity()
|
||||
)
|
||||
|
|
@ -83,17 +81,112 @@ class CancelledDownloadsFragment() : Fragment(), CancelledDownloadAdapter.OnItem
|
|||
}
|
||||
|
||||
downloadViewModel.cancelledDownloads.observe(viewLifecycleOwner) {
|
||||
items = it
|
||||
cancelledDownloads.submitList(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onQueuedCancelClick(itemID: Long) {
|
||||
TODO("Not yet implemented")
|
||||
override fun onActionButtonClick(itemID: Long) {
|
||||
val item = items.find { it.id == itemID }
|
||||
if (item != null){
|
||||
downloadViewModel.queueDownloads(listOf(item))
|
||||
}else{
|
||||
Toast.makeText(requireContext(), getString(R.string.error_restarting_download), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemClick(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
|
||||
TODO("Not yet implemented")
|
||||
override fun onCardClick(itemID: Long) {
|
||||
val item = items.find { it.id == itemID } ?: return
|
||||
|
||||
val bottomSheet = BottomSheetDialog(requireContext())
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.download_details_bottom_sheet)
|
||||
|
||||
val title = bottomSheet.findViewById<TextView>(R.id.bottom_sheet_title)
|
||||
title!!.text = item.title
|
||||
|
||||
val author = bottomSheet.findViewById<TextView>(R.id.bottom_sheet_author)
|
||||
author!!.text = item.author
|
||||
|
||||
val type = bottomSheet.findViewById<TextView>(R.id.type)
|
||||
val formatNote = bottomSheet.findViewById<TextView>(R.id.format_note)
|
||||
val codec = bottomSheet.findViewById<TextView>(R.id.codec)
|
||||
val fileSize = bottomSheet.findViewById<TextView>(R.id.file_size)
|
||||
val scheduledTime = bottomSheet.findViewById<LinearLayout>(R.id.scheduled_time_linear)
|
||||
|
||||
type!!.text = item.type.toString().uppercase()
|
||||
|
||||
if (item.format.format_note == "?") formatNote!!.visibility = View.GONE
|
||||
else formatNote!!.text = item.format.format_note
|
||||
|
||||
val codecText =
|
||||
if (item.format.encoding != "") {
|
||||
item.format.encoding.uppercase()
|
||||
}else if (item.format.vcodec != "none" && item.format.vcodec != ""){
|
||||
item.format.vcodec.uppercase()
|
||||
} else {
|
||||
item.format.acodec.uppercase()
|
||||
}
|
||||
if (codecText == "" || codecText == "none"){
|
||||
codec!!.visibility = View.GONE
|
||||
}else{
|
||||
codec!!.visibility = View.VISIBLE
|
||||
codec.text = codecText
|
||||
}
|
||||
|
||||
val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize)
|
||||
if (fileSizeReadable == "?") fileSize!!.visibility = View.GONE
|
||||
else fileSize!!.text = fileSizeReadable
|
||||
|
||||
val link = bottomSheet.findViewById<Button>(R.id.bottom_sheet_link)
|
||||
link!!.text = item.url
|
||||
link.tag = itemID
|
||||
link.setOnClickListener{
|
||||
uiUtil.openLinkIntent(requireContext(), item.url, bottomSheet)
|
||||
}
|
||||
link.setOnLongClickListener{
|
||||
uiUtil.copyLinkToClipBoard(requireContext(), item.url, bottomSheet)
|
||||
true
|
||||
}
|
||||
|
||||
if (item.downloadStartTime == 0L){
|
||||
scheduledTime!!.visibility = View.GONE
|
||||
}else{
|
||||
val time = bottomSheet.findViewById<TextView>(R.id.time)
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(item.downloadStartTime * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
val formattedTime = "$day $month $year - $timeString"
|
||||
time!!.text = formattedTime
|
||||
}
|
||||
|
||||
val remove = bottomSheet.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.tag = itemID
|
||||
remove.setOnClickListener{
|
||||
removeItem(item, bottomSheet)
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun removeItem(item: DownloadItem, bottomSheet: BottomSheetDialog?){
|
||||
bottomSheet?.hide()
|
||||
val deleteDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + item.title + "\"!")
|
||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
downloadViewModel.deleteDownload(item)
|
||||
}
|
||||
deleteDialog.show()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,37 +2,14 @@ package com.deniscerri.ytdlnis.ui.downloadqueue
|
|||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.ActiveDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.QueuedDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.database.dao.CommandTemplateDao
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.*
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
|
||||
class DownloadQueueActivity : AppCompatActivity(){
|
||||
|
|
|
|||
|
|
@ -1,56 +1,49 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadqueue
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.DialogInterface
|
||||
import android.content.res.Configuration
|
||||
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.AdapterView.OnItemClickListener
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.ActiveDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.ErroredDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.FormatSelectionBottomSheetDialog
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.OnFormatClickListener
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.UiUtil
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.launch
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.File
|
||||
import java.sql.Date
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
class ErroredDownloadsFragment() : Fragment(), ErroredDownloadAdapter.OnItemClickListener, OnItemClickListener {
|
||||
class ErroredDownloadsFragment() : Fragment(), GenericDownloadAdapter.OnItemClickListener, OnItemClickListener {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var erroredRecyclerView : RecyclerView
|
||||
private lateinit var erroredDownloads : ErroredDownloadAdapter
|
||||
lateinit var downloadItem: DownloadItem
|
||||
|
||||
private lateinit var erroredDownloads : GenericDownloadAdapter
|
||||
private lateinit var items : List<DownloadItem>
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var uiUtil : UiUtil
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
|
@ -60,6 +53,9 @@ class ErroredDownloadsFragment() : Fragment(), ErroredDownloadAdapter.OnItemClic
|
|||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||
activity = getActivity()
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
items = listOf()
|
||||
fileUtil = FileUtil()
|
||||
uiUtil = UiUtil(fileUtil)
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +63,7 @@ class ErroredDownloadsFragment() : Fragment(), ErroredDownloadAdapter.OnItemClic
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
erroredDownloads =
|
||||
ErroredDownloadAdapter(
|
||||
GenericDownloadAdapter(
|
||||
this,
|
||||
requireActivity()
|
||||
)
|
||||
|
|
@ -83,14 +79,110 @@ class ErroredDownloadsFragment() : Fragment(), ErroredDownloadAdapter.OnItemClic
|
|||
}
|
||||
|
||||
downloadViewModel.erroredDownloads.observe(viewLifecycleOwner) {
|
||||
items = it
|
||||
erroredDownloads.submitList(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onQueuedCancelClick(itemID: Long) {
|
||||
override fun onActionButtonClick(itemID: Long) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onCardClick(itemID: Long) {
|
||||
val item = items.find { it.id == itemID } ?: return
|
||||
|
||||
val bottomSheet = BottomSheetDialog(requireContext())
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.download_details_bottom_sheet)
|
||||
|
||||
val title = bottomSheet.findViewById<TextView>(R.id.bottom_sheet_title)
|
||||
title!!.text = item.title
|
||||
|
||||
val author = bottomSheet.findViewById<TextView>(R.id.bottom_sheet_author)
|
||||
author!!.text = item.author
|
||||
|
||||
val type = bottomSheet.findViewById<TextView>(R.id.type)
|
||||
val formatNote = bottomSheet.findViewById<TextView>(R.id.format_note)
|
||||
val codec = bottomSheet.findViewById<TextView>(R.id.codec)
|
||||
val fileSize = bottomSheet.findViewById<TextView>(R.id.file_size)
|
||||
val scheduledTime = bottomSheet.findViewById<LinearLayout>(R.id.scheduled_time_linear)
|
||||
|
||||
type!!.text = item.type.toString().uppercase()
|
||||
|
||||
|
||||
if (item.format.format_note == "?") formatNote!!.visibility = View.GONE
|
||||
else formatNote!!.text = item.format.format_note
|
||||
|
||||
val codecText =
|
||||
if (item.format.encoding != "") {
|
||||
item.format.encoding.uppercase()
|
||||
}else if (item.format.vcodec != "none" && item.format.vcodec != ""){
|
||||
item.format.vcodec.uppercase()
|
||||
} else {
|
||||
item.format.acodec.uppercase()
|
||||
}
|
||||
if (codecText == "" || codecText == "none"){
|
||||
codec!!.visibility = View.GONE
|
||||
}else{
|
||||
codec!!.visibility = View.VISIBLE
|
||||
codec.text = codecText
|
||||
}
|
||||
|
||||
val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize)
|
||||
if (fileSizeReadable == "?") fileSize!!.visibility = View.GONE
|
||||
else fileSize!!.text = fileSizeReadable
|
||||
|
||||
val link = bottomSheet.findViewById<Button>(R.id.bottom_sheet_link)
|
||||
link!!.text = item.url
|
||||
link.tag = itemID
|
||||
link.setOnClickListener{
|
||||
uiUtil.openLinkIntent(requireContext(), item.url, bottomSheet)
|
||||
}
|
||||
link.setOnLongClickListener{
|
||||
uiUtil.copyLinkToClipBoard(requireContext(), item.url, bottomSheet)
|
||||
true
|
||||
}
|
||||
|
||||
if (item.downloadStartTime == 0L){
|
||||
scheduledTime!!.visibility = View.GONE
|
||||
}else{
|
||||
val time = bottomSheet.findViewById<TextView>(R.id.time)
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(item.downloadStartTime * 1000L)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
val formattedTime = "$day $month $year - $timeString"
|
||||
time!!.text = formattedTime
|
||||
}
|
||||
|
||||
val remove = bottomSheet.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.tag = itemID
|
||||
remove.setOnClickListener{
|
||||
removeItem(item, bottomSheet)
|
||||
}
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeItem(item: DownloadItem, bottomSheet: BottomSheetDialog?){
|
||||
bottomSheet?.hide()
|
||||
val deleteDialog = MaterialAlertDialogBuilder(requireContext()!!)
|
||||
deleteDialog.setTitle(getString(R.string.you_are_going_to_delete) + " \"" + item.title + "\"!")
|
||||
deleteDialog.setNegativeButton(getString(R.string.cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.cancel() }
|
||||
deleteDialog.setPositiveButton(getString(R.string.ok)) { _: DialogInterface?, _: Int ->
|
||||
downloadViewModel.deleteDownload(item)
|
||||
}
|
||||
deleteDialog.show()
|
||||
}
|
||||
|
||||
override fun onItemClick(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,16 @@
|
|||
package com.deniscerri.ytdlnis.ui.downloadqueue
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
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.View.OnClickListener
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.view.Window
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
|
@ -25,35 +19,35 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.WorkManager
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.adapter.ActiveDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.QueuedDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.adapter.GenericDownloadAdapter
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel.Type
|
||||
import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.FormatSelectionBottomSheetDialog
|
||||
import com.deniscerri.ytdlnis.ui.downloadcard.OnFormatClickListener
|
||||
import com.deniscerri.ytdlnis.util.FileUtil
|
||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||
import com.deniscerri.ytdlnis.util.UiUtil
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.sql.Date
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
class QueuedDownloadsFragment() : Fragment(), QueuedDownloadAdapter.OnItemClickListener, OnClickListener {
|
||||
class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
||||
private var _binding : FragmentHomeBinding? = null
|
||||
private var fragmentView: View? = null
|
||||
private var activity: Activity? = null
|
||||
private lateinit var downloadViewModel : DownloadViewModel
|
||||
private lateinit var queuedRecyclerView : RecyclerView
|
||||
private lateinit var queuedDownloads : QueuedDownloadAdapter
|
||||
private lateinit var queuedDownloads : GenericDownloadAdapter
|
||||
private lateinit var notificationUtil: NotificationUtil
|
||||
private lateinit var items : List<DownloadItem>
|
||||
private lateinit var fileUtil: FileUtil
|
||||
private lateinit var uiUtil: UiUtil
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
|
@ -65,6 +59,9 @@ class QueuedDownloadsFragment() : Fragment(), QueuedDownloadAdapter.OnItemClickL
|
|||
activity = getActivity()
|
||||
notificationUtil = NotificationUtil(requireContext())
|
||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||
items = listOf()
|
||||
fileUtil = FileUtil()
|
||||
uiUtil = UiUtil(fileUtil)
|
||||
return fragmentView
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +69,7 @@ class QueuedDownloadsFragment() : Fragment(), QueuedDownloadAdapter.OnItemClickL
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
queuedDownloads =
|
||||
QueuedDownloadAdapter(
|
||||
GenericDownloadAdapter(
|
||||
this,
|
||||
requireActivity()
|
||||
)
|
||||
|
|
@ -88,11 +85,12 @@ class QueuedDownloadsFragment() : Fragment(), QueuedDownloadAdapter.OnItemClickL
|
|||
}
|
||||
|
||||
downloadViewModel.queuedDownloads.observe(viewLifecycleOwner) {
|
||||
items = it
|
||||
queuedDownloads.submitList(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onQueuedCancelClick(itemID: Long) {
|
||||
override fun onActionButtonClick(itemID: Long) {
|
||||
lifecycleScope.launch{
|
||||
withContext(Dispatchers.IO){
|
||||
downloadViewModel.deleteDownload(downloadViewModel.getItemByID(itemID))
|
||||
|
|
@ -101,6 +99,86 @@ class QueuedDownloadsFragment() : Fragment(), QueuedDownloadAdapter.OnItemClickL
|
|||
cancelDownload(itemID)
|
||||
}
|
||||
|
||||
override fun onCardClick(itemID: Long) {
|
||||
val item = items.find { it.id == itemID } ?: return
|
||||
|
||||
val bottomSheet = BottomSheetDialog(requireContext())
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.download_details_bottom_sheet)
|
||||
|
||||
val title = bottomSheet.findViewById<TextView>(R.id.bottom_sheet_title)
|
||||
title!!.text = item.title
|
||||
|
||||
val author = bottomSheet.findViewById<TextView>(R.id.bottom_sheet_author)
|
||||
author!!.text = item.author
|
||||
|
||||
val type = bottomSheet.findViewById<TextView>(R.id.type)
|
||||
val formatNote = bottomSheet.findViewById<TextView>(R.id.format_note)
|
||||
val codec = bottomSheet.findViewById<TextView>(R.id.codec)
|
||||
val fileSize = bottomSheet.findViewById<TextView>(R.id.file_size)
|
||||
val scheduledTime = bottomSheet.findViewById<LinearLayout>(R.id.scheduled_time_linear)
|
||||
|
||||
type!!.text = item.type.toString().uppercase()
|
||||
|
||||
if (item.format.format_note == "?") formatNote!!.visibility = View.GONE
|
||||
else formatNote!!.text = item.format.format_note
|
||||
|
||||
val codecText =
|
||||
if (item.format.encoding != "") {
|
||||
item.format.encoding.uppercase()
|
||||
}else if (item.format.vcodec != "none" && item.format.vcodec != ""){
|
||||
item.format.vcodec.uppercase()
|
||||
} else {
|
||||
item.format.acodec.uppercase()
|
||||
}
|
||||
if (codecText == "" || codecText == "none"){
|
||||
codec!!.visibility = View.GONE
|
||||
}else{
|
||||
codec!!.visibility = View.VISIBLE
|
||||
codec.text = codecText
|
||||
}
|
||||
|
||||
val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize)
|
||||
if (fileSizeReadable == "?") fileSize!!.visibility = View.GONE
|
||||
else fileSize!!.text = fileSizeReadable
|
||||
|
||||
val link = bottomSheet.findViewById<Button>(R.id.bottom_sheet_link)
|
||||
link!!.text = item.url
|
||||
link.tag = itemID
|
||||
link.setOnClickListener{
|
||||
uiUtil.openLinkIntent(requireContext(), item.url, bottomSheet)
|
||||
}
|
||||
link.setOnLongClickListener{
|
||||
uiUtil.copyLinkToClipBoard(requireContext(), item.url, bottomSheet)
|
||||
true
|
||||
}
|
||||
|
||||
if (item.downloadStartTime == 0L){
|
||||
scheduledTime!!.visibility = View.GONE
|
||||
}else{
|
||||
val time = bottomSheet.findViewById<TextView>(R.id.time)
|
||||
val cal = Calendar.getInstance()
|
||||
val date = Date(item.downloadStartTime)
|
||||
cal.time = date
|
||||
val day = cal[Calendar.DAY_OF_MONTH]
|
||||
val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault())
|
||||
val year = cal[Calendar.YEAR]
|
||||
val formatter: DateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val timeString = formatter.format(date)
|
||||
val formattedTime = "$day $month $year - $timeString"
|
||||
time!!.text = formattedTime
|
||||
}
|
||||
|
||||
val remove = bottomSheet.findViewById<Button>(R.id.bottomsheet_remove_button)
|
||||
remove!!.visibility = View.GONE
|
||||
|
||||
bottomSheet.show()
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
|
||||
private fun cancelDownload(itemID: Long){
|
||||
val id = itemID.toInt()
|
||||
YoutubeDL.getInstance().destroyProcessById(id.toString())
|
||||
|
|
@ -108,9 +186,4 @@ class QueuedDownloadsFragment() : Fragment(), QueuedDownloadAdapter.OnItemClickL
|
|||
notificationUtil.cancelDownloadNotification(id)
|
||||
}
|
||||
|
||||
override fun onClick(p0: View?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -100,10 +100,8 @@ class TerminalActivity : AppCompatActivity() {
|
|||
|
||||
|
||||
private fun startDownload(command: String?) {
|
||||
var cmd: String = ""
|
||||
if (command!!.contains("yt-dlp")) cmd = command.replace("yt-dlp", "")
|
||||
else cmd = command
|
||||
cmd = cmd.trim()
|
||||
val cmd = if (command!!.contains("yt-dlp")) command.replace("yt-dlp", "")
|
||||
else command
|
||||
|
||||
downloadID = System.currentTimeMillis().toInt()
|
||||
|
||||
|
|
@ -126,23 +124,20 @@ class TerminalActivity : AppCompatActivity() {
|
|||
notify(downloadID, commandNotification)
|
||||
}
|
||||
}
|
||||
val commandRegex = "(-\\S+)|(\\S+)"
|
||||
val request = YoutubeDLRequest(emptyList())
|
||||
|
||||
val tempFolder = StringBuilder(context!!.cacheDir.absolutePath + """/${command}##terminal""")
|
||||
val tempFolder = StringBuilder(context!!.cacheDir.absolutePath + """/${System.currentTimeMillis()}##terminal""")
|
||||
val tempFileDir = File(tempFolder.toString())
|
||||
tempFileDir.delete()
|
||||
tempFileDir.mkdir()
|
||||
|
||||
Log.e(TAG, cmd)
|
||||
val m = Pattern.compile(commandRegex).matcher(cmd)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
}
|
||||
request.addOption(
|
||||
"--config-locations",
|
||||
File(cacheDir, "config${System.currentTimeMillis()}.txt").apply {
|
||||
writeText(cmd)
|
||||
}.absolutePath
|
||||
)
|
||||
|
||||
|
||||
request.addOption("-P", tempFileDir.absolutePath)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,28 @@
|
|||
package com.deniscerri.ytdlnis.ui.more.downloadLogs
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.FileObserver
|
||||
import android.text.method.ScrollingMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import java.io.File
|
||||
|
||||
|
||||
class DownloadLogActivity : AppCompatActivity() {
|
||||
private lateinit var content: TextView
|
||||
private lateinit var contentScrollView : NestedScrollView
|
||||
private lateinit var contentScrollView : ScrollView
|
||||
private lateinit var topAppBar: MaterialToolbar
|
||||
private lateinit var observer: FileObserver
|
||||
private lateinit var copyLog : ExtendedFloatingActionButton
|
||||
var context: Context? = null
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -30,8 +36,17 @@ class DownloadLogActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
content = findViewById(R.id.content)
|
||||
content.movementMethod = ScrollingMovementMethod()
|
||||
contentScrollView = findViewById(R.id.content_scrollview)
|
||||
|
||||
copyLog = findViewById(R.id.copy_log)
|
||||
copyLog.setOnClickListener {
|
||||
val clipboard: ClipboardManager =
|
||||
getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip: ClipData = ClipData.newPlainText("Download Log", content.text)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
}
|
||||
|
||||
val path = intent.getStringExtra("path")
|
||||
if (path == null) {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
|
|
@ -57,6 +72,7 @@ class DownloadLogActivity : AppCompatActivity() {
|
|||
runOnUiThread{
|
||||
content.text = File(path).readText()
|
||||
content.scrollTo(0, content.height)
|
||||
contentScrollView.fullScroll(View.FOCUS_DOWN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package com.deniscerri.ytdlnis.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
|
|
@ -11,10 +14,12 @@ import android.view.ViewGroup
|
|||
import android.view.Window
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.CommandTemplate
|
||||
|
|
@ -25,6 +30,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
|||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import java.io.File
|
||||
|
||||
class UiUtil(private val fileUtil: FileUtil) {
|
||||
fun populateFormatCard(formatCard : ConstraintLayout, chosenFormat: Format){
|
||||
|
|
@ -165,5 +171,34 @@ class UiUtil(private val fileUtil: FileUtil) {
|
|||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
fun copyLinkToClipBoard(context: Context, url: String, bottomSheet: BottomSheetDialog?) {
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(context.getString(R.string.url), url)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
bottomSheet?.hide()
|
||||
Toast.makeText(context, context.getString(R.string.link_copied_to_clipboard), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun openLinkIntent(context: Context, url: String, bottomSheet: BottomSheetDialog?) {
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = Uri.parse(url)
|
||||
bottomSheet?.hide()
|
||||
context.startActivity(i)
|
||||
}
|
||||
|
||||
|
||||
fun openFileIntent(fragmentContext: Context, downloadPath: String) {
|
||||
val file = File(downloadPath)
|
||||
val uri = FileProvider.getUriForFile(
|
||||
fragmentContext,
|
||||
fragmentContext.packageName + ".fileprovider",
|
||||
file
|
||||
)
|
||||
val mime = fragmentContext.contentResolver.getType(uri)
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.setDataAndType(uri, mime)
|
||||
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
fragmentContext.startActivity(i)
|
||||
}
|
||||
}
|
||||
|
|
@ -184,15 +184,13 @@ class DownloadWorker(
|
|||
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
|
||||
}
|
||||
DownloadViewModel.Type.command -> {
|
||||
val commandRegex = "\"([^\"]*)\"|(-\\S+)"
|
||||
val m = Pattern.compile(commandRegex).matcher(downloadItem.format.format_note)
|
||||
while (m.find()) {
|
||||
if (m.group(1) != null) {
|
||||
request.addOption(m.group(1)!!)
|
||||
} else {
|
||||
request.addOption(m.group(2)!!)
|
||||
}
|
||||
}
|
||||
request.addOption(
|
||||
"--config-locations",
|
||||
File(context.cacheDir, "config${System.currentTimeMillis()}.txt").apply {
|
||||
writeText(downloadItem.format.format_note)
|
||||
}.absolutePath
|
||||
)
|
||||
|
||||
request.addOption("-P", tempFileDir.absolutePath)
|
||||
|
||||
}
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_copy.xml
Normal file
5
app/src/main/res/drawable/ic_copy.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?attr/colorAccent" android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
|
||||
</vector>
|
||||
|
|
@ -23,26 +23,37 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
<ScrollView
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:id="@+id/content_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:fillViewport="true"
|
||||
android:paddingBottom="150dp"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/content"
|
||||
android:padding="10dp"
|
||||
android:scrollHorizontally="true"
|
||||
android:fontFamily="monospace"
|
||||
android:textSize="15sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textIsSelectable="true"
|
||||
android:gravity="bottom"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</ScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/copy_log"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:contentDescription="@string/copy_log"
|
||||
android:text="@string/copy_log"
|
||||
app:icon="@drawable/ic_copy"/>
|
||||
|
||||
<include layout="@layout/history_no_results"
|
||||
android:visibility="gone" />
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:gravity="start"
|
||||
android:maxLines="5" />
|
||||
android:maxLines="10" />
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/custom_command_scrollview"
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
android:id="@+id/custom_command_output"
|
||||
android:layout_width="match_parent"
|
||||
android:textIsSelectable="true"
|
||||
android:fontFamily="monospace"
|
||||
android:gravity="bottom"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
android:layout_marginEnd="10dp"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@+id/divider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
|
@ -26,28 +26,28 @@
|
|||
android:layout_marginEnd="15dp"
|
||||
android:maxLines="2"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/divider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
style="@style/Divider.Vertical"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/check"
|
||||
app:layout_constraintStart_toEndOf="@+id/title"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<!-- <View-->
|
||||
<!-- android:id="@+id/divider"-->
|
||||
<!-- style="@style/Divider.Vertical"-->
|
||||
<!-- android:layout_height="0dp"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintEnd_toStartOf="@+id/check"-->
|
||||
<!-- app:layout_constraintStart_toEndOf="@+id/title"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent" />-->
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/check"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minWidth="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.558" />
|
||||
<!-- <RadioButton-->
|
||||
<!-- android:id="@+id/check"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:gravity="center"-->
|
||||
<!-- android:minWidth="0dp"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||
<!-- app:layout_constraintVertical_bias="0.558" />-->
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
|||
183
app/src/main/res/layout/download_details_bottom_sheet.xml
Normal file
183
app/src/main/res/layout/download_details_bottom_sheet.xml
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout android:id="@+id/downloads_element_bottom_sheet"
|
||||
style="@style/Widget.Material3.BottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="25sp"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_author"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginStart="20dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/url">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/type"
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorAccent"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/format_note"
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/codec"
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_size"
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Tertiary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/scheduled_time_linear"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/bottomsheet_schedule_button"
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_clock"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/bottomsheet_download_button"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.TextButton.Icon"
|
||||
android:id="@+id/bottom_sheet_link"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="15sp"
|
||||
android:layout_gravity="center"
|
||||
app:icon="@drawable/ic_link"
|
||||
android:text="@string/app_name" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="end"
|
||||
android:layout_margin="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
|
||||
android:id="@+id/bottomsheet_remove_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:icon="@drawable/ic_baseline_delete_outline_24"
|
||||
android:text="@string/Remove" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:maxLines="4"
|
||||
android:maxLines="10"
|
||||
android:inputType="textMultiLine"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,30 +9,21 @@
|
|||
<RelativeLayout
|
||||
android:id="@+id/queued_download_relative_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintDimensionRatio="H,3:1"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/queued_download_card_view"
|
||||
android:id="@+id/download_card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="10dp"
|
||||
app:cardMaxElevation="12dp"
|
||||
android:checkable="true"
|
||||
app:strokeWidth="0dp"
|
||||
app:cardPreventCornerOverlap="true"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/image_view"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
|
@ -42,53 +33,46 @@
|
|||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:shadowColor="@color/black"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowRadius="2"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@+id/queued_download_cancel"
|
||||
app:layout_constraintEnd_toStartOf="@+id/action_button"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.0" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/url"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/queued_download_cancel"
|
||||
android:id="@+id/action_button"
|
||||
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="55dp"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_margin="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:icon="@drawable/ic_baseline_delete_outline_24"
|
||||
app:icon="@drawable/ic_refresh"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/format_note"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:textSize="15sp"
|
||||
android:shadowColor="@color/black"
|
||||
android:shadowDx="4"
|
||||
android:shadowDy="4"
|
||||
android:shadowRadius="1.5"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||
app:layout_constraintVertical_bias="1.0" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout3"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -96,9 +80,41 @@
|
|||
android:layout_gravity="bottom"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/format_note">
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/url">
|
||||
|
||||
<TextView
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
|
||||
android:id="@+id/type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/format_note"
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/codec"
|
||||
|
|
@ -132,22 +148,6 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time"
|
||||
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:minWidth="30dp"
|
||||
android:paddingHorizontal="10dp"
|
||||
app:cornerRadius="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
app:endIconMode="custom"
|
||||
app:endIconDrawable="@drawable/ic_plus"
|
||||
android:hint="@string/create_template"
|
||||
android:hint="@string/create_shortcut"
|
||||
style="@style/Widget.Material3.TextInputLayout.FilledBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
|
|
|
|||
|
|
@ -193,4 +193,8 @@
|
|||
<string name="shortcuts_desc">Use commonly used commands to create templates</string>
|
||||
<string name="cancelled">Cancelled</string>
|
||||
<string name="errored">Errored</string>
|
||||
<string name="copy_log">Copy log</string>
|
||||
<string name="create_shortcut">Create Shortcut</string>
|
||||
<string name="error_restarting_download">Error trying to restart the download</string>
|
||||
<string name="delete_temp_file_too">Delete temporary files from the device</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue