added split by chapters

This commit is contained in:
Denis Çerri 2023-03-11 12:12:34 +01:00
parent 724702ffc1
commit f26fd7498d
No known key found for this signature in database
GPG key ID: 95C43D517D830350
28 changed files with 416 additions and 458 deletions

View file

@ -19,7 +19,6 @@ import androidx.core.app.ActivityCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.work.WorkManager
import com.deniscerri.ytdlnis.databinding.ActivityMainBinding
import com.deniscerri.ytdlnis.service.IDownloaderListener
import com.deniscerri.ytdlnis.service.IDownloaderService
@ -45,7 +44,6 @@ class MainActivity : AppCompatActivity() {
lateinit var context: Context
private lateinit var homeFragment: HomeFragment
private lateinit var historyFragment: HistoryFragment
private lateinit var workManager: WorkManager
override fun onCreate(savedInstanceState: Bundle?) {
@ -58,7 +56,6 @@ class MainActivity : AppCompatActivity() {
askPermissions()
checkUpdate()
fm = supportFragmentManager
workManager = WorkManager.getInstance(context)
homeFragment = HomeFragment()
historyFragment = HistoryFragment()
@ -171,9 +168,6 @@ class MainActivity : AppCompatActivity() {
lastFragment = f
}
fun cancelAllDownloads() {
workManager.cancelAllWork();
}
private fun checkUpdate() {
val preferences = context.getSharedPreferences("root_preferences", MODE_PRIVATE)

View file

@ -19,6 +19,7 @@ import com.deniscerri.ytdlnis.database.repository.DownloadRepository
import com.deniscerri.ytdlnis.util.FileUtil
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
import com.google.android.material.chip.Chip
import com.squareup.picasso.Picasso
import java.io.File
@ -72,10 +73,10 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
val itemUrl = card.findViewById<TextView>(R.id.subtitle)
itemUrl.text = item.url
val formatNote = card.findViewById<TextView>(R.id.format_note)
val formatNote = card.findViewById<Chip>(R.id.format_note)
formatNote!!.text = item.format.format_note.uppercase()
val codec = card.findViewById<TextView>(R.id.codec)
val codec = card.findViewById<Chip>(R.id.codec)
val codecText =
if (item.format.encoding != "") {
item.format.encoding.uppercase()
@ -91,7 +92,7 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
codec.text = codecText
}
val fileSize = card.findViewById<TextView>(R.id.file_size)
val fileSize = card.findViewById<Chip>(R.id.file_size)
val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize)
if (fileSizeReadable == "?") fileSize.visibility = View.GONE
else fileSize.text = fileSizeReadable

View file

@ -37,8 +37,11 @@ interface DownloadDao {
@Query("DELETE FROM downloads WHERE id=:id")
suspend fun delete(id: Long)
@Query("DELETE FROM downloads WHERE status='Processing'")
suspend fun deleteProcessing()
@Query("DELETE FROM downloads WHERE status='Cancelled'")
suspend fun deleteCancelled()
@Query("DELETE FROM downloads WHERE status='Error'")
suspend fun deleteErrored()
@Query("DELETE FROM downloads WHERE status='Processing' AND id=:id")
suspend fun deleteSingleProcessing(id: Long)

View file

@ -2,4 +2,5 @@ package com.deniscerri.ytdlnis.database.models
data class AudioPreferences(
var embedThumb: Boolean = true,
var splitByChapters: Boolean = false,
)

View file

@ -3,4 +3,5 @@ package com.deniscerri.ytdlnis.database.models
data class VideoPreferences (
var embedSubs: Boolean = true,
var addChapters: Boolean = true,
var splitByChapters: Boolean = false,
)

View file

@ -40,8 +40,12 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
return downloadDao.getDownloadById(id)
}
suspend fun deleteProcessing(){
downloadDao.deleteProcessing()
suspend fun deleteCancelled(){
downloadDao.deleteCancelled()
}
suspend fun deleteErrored(){
downloadDao.deleteErrored()
}
suspend fun deleteSingleProcessing(item: DownloadItem){

View file

@ -207,8 +207,12 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
return result
}
fun deleteProcessing() = viewModelScope.launch(Dispatchers.IO) {
repository.deleteProcessing()
fun deleteCancelled() = viewModelScope.launch(Dispatchers.IO) {
repository.deleteCancelled()
}
fun deleteErrored() = viewModelScope.launch(Dispatchers.IO) {
repository.deleteErrored()
}
fun cloneDownloadItem(item: DownloadItem) : DownloadItem {

View file

@ -264,7 +264,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
}
searchBar!!.setOnMenuItemClickListener { m: MenuItem ->
when (val itemId = m.itemId) {
when (m.itemId) {
R.id.delete_results -> {
resultViewModel.getTrending()
selectedObjects = ArrayList()
@ -272,12 +272,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
downloadAllFabCoordinator!!.visibility = GONE
downloadFabs!!.visibility = GONE
}
R.id.cancel_download -> {
try {
mainActivity!!.cancelAllDownloads()
searchBar!!.menu.findItem(itemId).isVisible = false
} catch (ignored: Exception) {}
}
R.id.delete_search -> {
resultViewModel.deleteAllSearchQueryHistory()
searchSuggestionsLinearLayout!!.removeAllViews()

View file

@ -173,6 +173,12 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
downloadItem.audioPreferences.embedThumb = embedThumb.isChecked
}
val splitByChapters = view.findViewById<Chip>(R.id.split_by_chapters)
splitByChapters!!.isChecked = downloadItem.audioPreferences.splitByChapters
splitByChapters.setOnClickListener {
downloadItem.audioPreferences.splitByChapters = splitByChapters.isChecked
}
val copyURL = view.findViewById<Chip>(R.id.copy_url)
copyURL.setOnClickListener {
val clipboard: ClipboardManager =

View file

@ -188,6 +188,20 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
downloadItem.videoPreferences.addChapters = addChapters.isChecked
}
val splitByChapters = view.findViewById<Chip>(R.id.split_by_chapters)
splitByChapters!!.isChecked = downloadItem.audioPreferences.splitByChapters
splitByChapters.setOnClickListener {
if (splitByChapters.isChecked){
addChapters.isEnabled = false
addChapters.isChecked = false
downloadItem.videoPreferences.addChapters = false
}else{
addChapters.isEnabled = true
}
downloadItem.videoPreferences.splitByChapters = splitByChapters.isChecked
}
val saveThumbnail = view.findViewById<Chip>(R.id.save_thumbnail)
saveThumbnail!!.isChecked = downloadItem.SaveThumb
saveThumbnail.setOnClickListener {

View file

@ -12,6 +12,7 @@ import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
@ -25,6 +26,7 @@ import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.sql.Date
import java.text.DateFormat
@ -97,23 +99,30 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.download_details_bottom_sheet)
bottomSheet.setContentView(R.layout.history_item_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)
// BUTTON ----------------------------------
val buttonLayout = bottomSheet.findViewById<LinearLayout>(R.id.downloads_download_button_layout)
val btn = buttonLayout!!.findViewById<MaterialButton>(R.id.downloads_download_button_type)
if (item.type == DownloadViewModel.Type.audio) {
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_music)
} else if (item.type == DownloadViewModel.Type.video) {
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_video)
}else{
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_terminal)
}
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
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
View.GONE
else formatNote!!.text = item.format.format_note
val codecText =
@ -136,7 +145,8 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
else fileSize!!.text = fileSizeReadable
val link = bottomSheet.findViewById<Button>(R.id.bottom_sheet_link)
link!!.text = item.url
val url = item.url
link!!.text = url
link.tag = itemID
link.setOnClickListener{
uiUtil.openLinkIntent(requireContext(), item.url, bottomSheet)
@ -145,28 +155,22 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
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)
}
val openFile = bottomSheet.findViewById<Button>(R.id.bottomsheet_open_file_button)
openFile!!.visibility = View.GONE
val redownload = bottomSheet.findViewById<Button>(R.id.bottomsheet_redownload_button)
redownload!!.tag = itemID
redownload.setOnClickListener{
downloadViewModel.queueDownloads(listOf(item))
bottomSheet.cancel()
}
openFile.visibility = View.GONE
bottomSheet.show()
bottomSheet.window!!.setLayout(

View file

@ -2,10 +2,16 @@ package com.deniscerri.ytdlnis.ui.downloads
import android.content.Context
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import androidx.work.WorkManager
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.google.android.material.appbar.MaterialToolbar
@ -15,7 +21,7 @@ import com.google.android.material.tabs.TabLayout
class DownloadQueueActivity : AppCompatActivity(){
private lateinit var downloadViewModel: DownloadViewModel
private lateinit var topAppBar: MaterialToolbar
private lateinit var workManager: WorkManager
private lateinit var tabLayout: TabLayout
private lateinit var viewPager2: ViewPager2
private lateinit var fragmentAdapter : DownloadListFragmentAdapter
@ -26,7 +32,8 @@ class DownloadQueueActivity : AppCompatActivity(){
setContentView(R.layout.activity_download_queue)
context = baseContext
val view : View = window.decorView.findViewById(android.R.id.content)
workManager = WorkManager.getInstance(this)
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
topAppBar = findViewById(R.id.logs_toolbar)
topAppBar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
@ -81,24 +88,38 @@ class DownloadQueueActivity : AppCompatActivity(){
}
})
//initMenu()
initMenu()
// downloadViewModel.activeDownloads.observe(this){
// if (it.isEmpty()) tabLayout.getTabAt(0)!!.view.visibility = View.GONE
// else tabLayout.getTabAt(0)!!.view.visibility = View.VISIBLE
// }
}
// private fun initMenu() {
// topAppBar.setOnMenuItemClickListener { m: MenuItem ->
// val itemId = m.itemId
// if (itemId == R.id.remove_logs) {
// try{
// logFolder.listFiles()!!.forEach {
// it.delete()
// }
// }catch (e: Exception){
// Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
// }
// }
// true
// }
// }
private fun initMenu() {
topAppBar.setOnMenuItemClickListener { m: MenuItem ->
try{
when(m.itemId){
R.id.clear_queue -> {
cancelAllDownloads()
}
R.id.clear_cancelled -> {
downloadViewModel.deleteCancelled()
}
R.id.clear_errored -> {
downloadViewModel.deleteErrored()
}
}
}catch (e: Exception){
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
}
true
}
}
private fun cancelAllDownloads() {
workManager.cancelAllWork();
}
companion object {

View file

@ -14,6 +14,7 @@ import android.widget.AdapterView.OnItemClickListener
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
@ -28,6 +29,7 @@ import com.deniscerri.ytdlnis.ui.more.downloadLogs.DownloadLogActivity
import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.File
import java.sql.Date
@ -99,24 +101,30 @@ class ErroredDownloadsFragment() : Fragment(), GenericDownloadAdapter.OnItemClic
val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.download_details_bottom_sheet)
bottomSheet.setContentView(R.layout.history_item_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)
// BUTTON ----------------------------------
val buttonLayout = bottomSheet.findViewById<LinearLayout>(R.id.downloads_download_button_layout)
val btn = buttonLayout!!.findViewById<MaterialButton>(R.id.downloads_download_button_type)
if (item.type == DownloadViewModel.Type.audio) {
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_music)
} else if (item.type == DownloadViewModel.Type.video) {
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_video)
}else{
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_terminal)
}
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
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
View.GONE
else formatNote!!.text = item.format.format_note
val codecText =
@ -139,7 +147,8 @@ class ErroredDownloadsFragment() : Fragment(), GenericDownloadAdapter.OnItemClic
else fileSize!!.text = fileSizeReadable
val link = bottomSheet.findViewById<Button>(R.id.bottom_sheet_link)
link!!.text = item.url
val url = item.url
link!!.text = url
link.tag = itemID
link.setOnClickListener{
uiUtil.openLinkIntent(requireContext(), item.url, bottomSheet)
@ -148,28 +157,22 @@ class ErroredDownloadsFragment() : Fragment(), GenericDownloadAdapter.OnItemClic
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)
}
val openFile = bottomSheet.findViewById<Button>(R.id.bottomsheet_open_file_button)
openFile!!.visibility = View.GONE
val redownload = bottomSheet.findViewById<Button>(R.id.bottomsheet_redownload_button)
redownload!!.tag = itemID
redownload.setOnClickListener{
downloadViewModel.queueDownloads(listOf(item))
bottomSheet.cancel()
}
openFile.visibility = View.GONE
bottomSheet.show()
bottomSheet.window!!.setLayout(

View file

@ -234,9 +234,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
deleteDialog.show()
}
}
R.id.remove_downloading -> {
}
}
true
}

View file

@ -10,6 +10,7 @@ import android.view.Window
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@ -26,6 +27,7 @@ import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.NotificationUtil
import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.yausername.youtubedl_android.YoutubeDL
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -103,23 +105,30 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.download_details_bottom_sheet)
bottomSheet.setContentView(R.layout.history_item_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)
// BUTTON ----------------------------------
val buttonLayout = bottomSheet.findViewById<LinearLayout>(R.id.downloads_download_button_layout)
val btn = buttonLayout!!.findViewById<MaterialButton>(R.id.downloads_download_button_type)
if (item.type == DownloadViewModel.Type.audio) {
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_music)
} else if (item.type == DownloadViewModel.Type.video) {
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_video)
}else{
btn.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_terminal)
}
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
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
View.GONE
else formatNote!!.text = item.format.format_note
val codecText =
@ -142,7 +151,8 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
else fileSize!!.text = fileSizeReadable
val link = bottomSheet.findViewById<Button>(R.id.bottom_sheet_link)
link!!.text = item.url
val url = item.url
link!!.text = url
link.tag = itemID
link.setOnClickListener{
uiUtil.openLinkIntent(requireContext(), item.url, bottomSheet)
@ -151,25 +161,16 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
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
remove!!.tag = itemID
remove.setOnClickListener{
cancelDownload(itemID)
}
val openFile = bottomSheet.findViewById<Button>(R.id.bottomsheet_open_file_button)
openFile!!.visibility = View.GONE
val redownload = bottomSheet.findViewById<Button>(R.id.bottomsheet_redownload_button)
redownload!!.visibility = View.GONE
bottomSheet.show()
bottomSheet.window!!.setLayout(

View file

@ -39,7 +39,6 @@ class DownloadWorker(
val dbManager = DBManager.getInstance(context)
val dao = dbManager.downloadDao
val repository = DownloadRepository(dao)
val commandTemplateDao = dbManager.commandTemplateDao
val historyDao = dbManager.historyDao
val handler = Handler(Looper.getMainLooper())
@ -125,8 +124,6 @@ class DownloadWorker(
val ext = downloadItem.format.container
if(ext != context.getString(R.string.defaultValue) && ext != "webm"){
request.addOption("--audio-format", ext)
}else{
request.addOption("--audio-format", sharedPreferences.getString("audio_format", "mp3")!!)
}
request.addOption("--embed-metadata")
@ -149,7 +146,14 @@ class DownloadWorker(
} else {
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
}
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
if (downloadItem.audioPreferences.splitByChapters){
request.addOption("--split-chapters")
request.addOption("-P", tempFileDir.absolutePath)
}else{
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
}
}
DownloadViewModel.Type.video -> {
if (downloadItem.videoPreferences.addChapters) {
@ -182,7 +186,13 @@ class DownloadWorker(
}
}
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
if (downloadItem.videoPreferences.splitByChapters){
request.addOption("--split-chapters")
request.addOption("-P", tempFileDir.absolutePath)
}else{
request.addOption("-o", tempFileDir.absolutePath + "/${downloadItem.customFileNameTemplate}.%(ext)s")
}
}
DownloadViewModel.Type.command -> {
request.addOption(

View file

@ -17,6 +17,7 @@
android:id="@+id/logs_toolbar"
android:elevation="0dp"
app:title="@string/download_queue"
app:menu="@menu/download_queue_menu"
android:layout_width="match_parent"
app:navigationIcon="@drawable/ic_back"
android:layout_height="match_parent"/>
@ -47,7 +48,7 @@
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/added_to_queue" />
android:text="@string/in_queue" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"

View file

@ -8,7 +8,7 @@
<com.google.android.material.card.MaterialCardView
android:id="@+id/download_card_view"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_height="120dp"
android:layout_margin="10dp"
android:checkable="true"
app:cardCornerRadius="10dp"
@ -78,72 +78,72 @@
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:paddingBottom="5dp"
android:paddingStart="10dp"
android:paddingEnd="0dp"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_author">
app:layout_constraintTop_toBottomOf="@+id/title_author"
app:layout_constraintVertical_bias="1.0">
<TextView
android:id="@+id/format_note"
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
<com.google.android.material.chip.ChipGroup
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"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:layout_height="match_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" />
<com.google.android.material.chip.Chip
android:id="@+id/format_note"
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
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/colorTertiary"
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" />
<com.google.android.material.chip.Chip
android:id="@+id/codec"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.chip.Chip
android:id="@+id/file_size"
style="@style/Widget.Material3.FloatingActionButton.Large.Tertiary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<com.google.android.material.button.MaterialButton
android:id="@+id/action_button"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"

View file

@ -101,7 +101,7 @@
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingBottom="70dp"
android:paddingBottom="80dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

View file

@ -165,46 +165,49 @@
android:layout_height="wrap_content"
android:text="@string/adjust_audio" />
<HorizontalScrollView
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="wrap_content"
app:chipSpacingVertical="0dp"
app:singleLine="false"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
<com.google.android.material.chip.Chip
android:id="@+id/embed_thumb"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
app:singleLine="false"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/embed_thumb"/>
<com.google.android.material.chip.Chip
android:id="@+id/embed_thumb"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/embed_thumb"/>
<com.google.android.material.chip.Chip
android:id="@+id/split_by_chapters"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/split_by_chapters"/>
<com.google.android.material.chip.Chip
android:id="@+id/copy_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
android:minWidth="30dp"
android:layout_margin="10dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.chip.Chip
android:id="@+id/copy_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
android:minWidth="30dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.chip.ChipGroup>
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
</LinearLayout>

View file

@ -75,55 +75,50 @@
android:layout_height="wrap_content"
android:text="@string/adjust_templates" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/commands_chip_group"
<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="false"
app:chipSpacingVertical="0dp"
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"
app:selectionRequired="false"
app:singleLine="true"
app:singleSelection="false">
android:text="@string/new_template"
app:chipIcon="@drawable/ic_plus" />
<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.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.Chip
android:id="@+id/copy_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
android:minWidth="30dp"
android:layout_margin="10dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.chip.Chip
android:id="@+id/copy_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
android:minWidth="30dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.chip.ChipGroup>
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>

View file

@ -158,62 +158,65 @@
android:text="@string/adjust_video"
android:textSize="15sp" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipSpacingVertical="0dp"
app:singleLine="false">
<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"
app:singleLine="false">
android:checked="false"
android:text="@string/embed_subtitles" />
<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/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/split_by_chapters"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/split_by_chapters"/>
<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/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/copy_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
android:minWidth="30dp"
android:layout_margin="10dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.chip.Chip
android:id="@+id/copy_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
android:minWidth="30dp"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.chip.ChipGroup>
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
</LinearLayout>

View file

@ -1,142 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/downloads_card_constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:id="@+id/queued_download_relative_layout"
android:layout_width="0dp"
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/download_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
app:cardMaxElevation="12dp"
app:strokeWidth="0dp"
app:cardPreventCornerOverlap="true"
android:layout_margin="10dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
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:textSize="16sp"
android:textStyle="bold"
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/action_button"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Secondary"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_margin="10dp"
app:cornerRadius="10dp"
app:icon="@drawable/ic_refresh"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal"
android:padding="10dp"
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/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>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/clear_queue"
android:icon="@drawable/ic_delete_all"
android:title="@string/remove_downloading"
app:showAsAction="never" />
<item
android:id="@+id/clear_cancelled"
android:icon="@drawable/ic_delete_all"
android:title="@string/clear_cancelled"
app:showAsAction="never" />
<item
android:id="@+id/clear_errored"
android:icon="@drawable/ic_delete_all"
android:title="@string/clear_errored"
app:showAsAction="never" />
</menu>

View file

@ -28,11 +28,5 @@
android:title="@string/remove_duplicates"
app:showAsAction="never" />
<item
android:id="@+id/remove_downloading"
android:icon="@drawable/ic_delete_all"
android:title="@string/remove_downloading"
app:showAsAction="never" />
</menu>

View file

@ -3,13 +3,6 @@
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<!-- <item-->
<!-- android:id="@+id/search"-->
<!-- android:title="@string/search"-->
<!-- android:icon="@drawable/ic_search"-->
<!-- app:showAsAction="always|collapseActionView"-->
<!-- app:actionViewClass="androidx.appcompat.widget.SearchView"/>-->
<item
android:id="@+id/delete_results"
android:title="@string/remove_results"
@ -20,11 +13,6 @@
android:title="@string/remove_search_history"
app:showAsAction="never" />
<item
android:id="@+id/cancel_download"
android:title="@string/cancel_download"
android:visible="false"
app:showAsAction="never" />
</menu>

View file

@ -175,4 +175,34 @@
<string name="language">Gjuha</string>
<string name="download_queue">Rradha e Shkarkimeve</string>
<string name="running">Në Ekzekutim</string>
<string name="command">Komandë</string>
<string name="import_from_clipboard">Importo nga Clipboard</string>
<string name="export_from_clipboard">Eksporto te Clipboard</string>
<string name="shortcuts">Shkurtoret</string>
<string name="create_template">Krijo Shabllon</string>
<string name="edit">Redakto</string>
<string name="shortcuts_desc">Përdor komandat e përdorura zakonisht për të krijuar shabllone</string>
<string name="cancelled">Të Anulluar</string>
<string name="errored">Me Probleme</string>
<string name="copy_log">Kopjo Shënimin</string>
<string name="create_shortcut">Krijo Shkurtore</string>
<string name="error_restarting_download">Gabim në përpjekjen për të rifilluar shkarkimin</string>
<string name="delete_temp_file_too">Fshi skedarët e përkohshëm nga paisja</string>
<string name="update_template">Redakto Shabllonin</string>
<string name="create">Krijo</string>
<string name="update">Redakto</string>
<string name="preferred_download_type">Lloji i preferuar i Shkarkimit</string>
<string name="preferred_download_type_summary">Tabi i zgjedhur nga karta e shkarkimit</string>
<string name="confirm_delete_logs_desc">Fshi të gjithë listën e shënimeve, përgjithmmonë</string>
<string name="select">Zgjidh</string>
<string name="selected">Zgjedhur</string>
<string name="all_items_selected">Të gjithë janë zgjedhur</string>
<string name="access_all_directories">Lejo akses te të gjithë direktoritë</string>
<string name="access_all_directories_summary">Ler aplikacionin të shkarkojë në direktori të pasuportuara</string>
<string name="redownload">Rishkarko</string>
<string name="copy_url">Kopjo URL</string>
<string name="in_queue">Në Rradhë</string>
<string name="clear_cancelled">Fshi Të Anulluarit</string>
<string name="clear_errored">Fshi Me Probleme</string>
<string name="split_by_chapters">Ngaj sipas Kapitujve</string>
</resources>

View file

@ -210,4 +210,8 @@
<string name="access_all_directories_summary">Let the app download on directories that are restricted by default</string>
<string name="redownload">Redownload</string>
<string name="copy_url">Copy URL</string>
<string name="in_queue">In Queue</string>
<string name="clear_cancelled">Clear Cancelled</string>
<string name="clear_errored">Clear Errored</string>
<string name="split_by_chapters">Split By Chapters</string>
</resources>