diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e1b2cd3a..116c926e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -56,9 +56,7 @@
android:theme="@style/Theme.BottomSheet">
-
-
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
index d7fdcf7a..126d0756 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt
@@ -18,6 +18,7 @@ import android.view.View
import android.view.WindowInsets
import android.widget.CheckBox
import android.widget.TextView
+import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.app.ActivityCompat
@@ -39,7 +40,9 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
import com.deniscerri.ytdlnis.ui.BaseActivity
import com.deniscerri.ytdlnis.ui.HomeFragment
+import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog
import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity
+import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.ThemeUtil
import com.deniscerri.ytdlnis.util.UpdateUtil
import com.google.android.material.bottomnavigation.BottomNavigationView
@@ -54,8 +57,10 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.BufferedReader
+import java.io.File
import java.io.InputStreamReader
import java.io.Reader
+import java.net.URI
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import kotlin.system.exitProcess
@@ -332,26 +337,38 @@ class MainActivity : BaseActivity() {
}else{
intent.getParcelableExtra(Intent.EXTRA_STREAM)
}
- val `is` = contentResolver.openInputStream(uri!!)
- val textBuilder = StringBuilder()
- val reader: Reader = BufferedReader(
- InputStreamReader(
- `is`, Charset.forName(
- StandardCharsets.UTF_8.name()
+
+ if (preferences.getString("preferred_download_type", "video") == "command"){
+ val f = File(FileUtil.formatPath(uri?.path ?: ""))
+ if (!f.exists()){
+ Toast.makeText(context, "Couldn't read file", Toast.LENGTH_LONG).show()
+ return
+ }
+ val item = downloadViewModel.createEmptyResultItem(f.absolutePath)
+ val bottomSheet = DownloadBottomSheetDialog(item, DownloadViewModel.Type.command, null, true)
+ bottomSheet.show(supportFragmentManager, "downloadSingleSheet")
+ }else{
+ val `is` = contentResolver.openInputStream(uri!!)
+ val textBuilder = StringBuilder()
+ val reader: Reader = BufferedReader(
+ InputStreamReader(
+ `is`, Charset.forName(
+ StandardCharsets.UTF_8.name()
+ )
)
)
- )
- var c: Int
- while (reader.read().also { c = it } != -1) {
- textBuilder.append(c.toChar())
+ var c: Int
+ while (reader.read().also { c = it } != -1) {
+ textBuilder.append(c.toChar())
+ }
+ val bundle = Bundle()
+ bundle.putString("url", textBuilder.toString())
+ navController.popBackStack(R.id.homeFragment, true)
+ navController.navigate(
+ R.id.homeFragment,
+ bundle
+ )
}
- val bundle = Bundle()
- bundle.putString("url", textBuilder.toString())
- navController.popBackStack(R.id.homeFragment, true)
- navController.navigate(
- R.id.homeFragment,
- bundle
- )
} catch (e: Exception) {
e.printStackTrace()
}
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
index 7ef835dc..8dc50782 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt
@@ -104,6 +104,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
DownloadViewModel.Type.audio -> type.setIconResource(R.drawable.ic_music)
DownloadViewModel.Type.video -> type.setIconResource(R.drawable.ic_video)
DownloadViewModel.Type.command -> type.setIconResource(R.drawable.ic_terminal)
+ else -> {}
}
val formatDetailsChip = card.findViewById(R.id.format_note)
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt
index 6f1a6d89..6f5c972e 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/DownloadLogsAdapter.kt
@@ -66,6 +66,7 @@ class DownloadLogsAdapter(onItemClickListener: OnItemClickListener, activity: Ac
DownloadViewModel.Type.audio -> downloadTypeIcon.setIconResource(R.drawable.ic_music)
DownloadViewModel.Type.video -> downloadTypeIcon.setIconResource(R.drawable.ic_video)
DownloadViewModel.Type.command -> downloadTypeIcon.setIconResource(R.drawable.ic_terminal)
+ else -> {}
}
val formatNote = card.findViewById(R.id.format_note)
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt
index bc34fd41..4b29f743 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt
@@ -9,7 +9,7 @@ import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
data class DownloadItem(
@PrimaryKey(autoGenerate = true)
var id: Long,
- val url: String,
+ var url: String,
var title: String,
var author: String,
var thumb: String,
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt
index 6095dadc..5b132242 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/GithubRelease.kt
@@ -1,13 +1,20 @@
package com.deniscerri.ytdlnis.database.models
+import com.google.gson.annotations.SerializedName
+
data class GithubRelease(
+ @SerializedName(value = "tag_name")
var tag_name: String,
+ @SerializedName(value = "body")
var body: String,
+ @SerializedName(value = "assets")
var assets: List
)
data class GithubReleaseAsset(
+ @SerializedName(value = "name")
var name: String,
+ @SerializedName(value = "browser_download_url")
var browser_download_url: String
)
\ No newline at end of file
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt
index 61d06925..8deab4ea 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt
@@ -85,9 +85,15 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
private val dao: DownloadDao
enum class Type {
- audio, video, command
+ auto, audio, video, command
}
+ private val urlsForAudioType = listOf(
+ "music",
+ "audio",
+ "soundcloud"
+ )
+
init {
dbManager = DBManager.getInstance(application)
dao = dbManager.downloadDao
@@ -194,6 +200,13 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
return repository.getItemByID(id)
}
+ private fun getSuitableDownloadType(url: String): Type{
+ if (urlsForAudioType.any { url.contains(it) }){
+ return Type.audio
+ }
+ return Type.video
+ }
+
fun createDownloadItemFromResult(resultItem: ResultItem, givenType: Type) : DownloadItem {
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
val saveSubs = sharedPreferences.getBoolean("write_subtitles", false)
@@ -202,6 +215,9 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
var type = givenType
+ if (type == Type.auto){
+ type = getSuitableDownloadType(resultItem.url)
+ }
if(type == Type.command && commandTemplateDao.getTotalNumber() == 0) type = Type.video
val customFileNameTemplate = when(type) {
@@ -320,6 +336,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())!!
Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())!!
Type.command -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!!
+ else -> ""
}
list.forEach {
@@ -329,6 +346,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefaultAudioPath())
Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefaultVideoPath())
Type.command -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())
+ else -> ""
}
if (it.downloadPath == currentDownloadPath) it.downloadPath = updatedDownloadPath
@@ -359,6 +377,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.audio -> FileUtil.getDefaultAudioPath()
Type.video -> FileUtil.getDefaultVideoPath()
Type.command -> FileUtil.getDefaultCommandPath()
+ else -> ""
}
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
@@ -404,7 +423,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Type.video -> {
return cloneFormat(
try {
- val theFormats = formats.filter { !it.format_note.contains("audio", true) }.sortedBy { it.format_id }.ifEmpty { defaultVideoFormats }
+ val theFormats = formats.filter { !it.format_note.contains("audio", true) }.sortedBy { it.format_id }.ifEmpty { defaultVideoFormats }.sortedByDescending { it.filesize }
when (videoQualityPreference) {
"worst" -> {
theFormats.first()
@@ -416,7 +435,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
requirements.add { it: Format -> it.format_note.contains(videoQualityPreference.substring(0, videoQualityPreference.length - 1)) }
requirements.add { it: Format -> it.vcodec.startsWith(videoCodec!!, true) }
- theFormats.reversed().maxByOrNull { f -> requirements.count{ req -> req(f)} } ?: throw Exception()
+ theFormats.maxByOrNull { f -> requirements.count{ req -> req(f)} } ?: throw Exception()
}
}
}catch (e: Exception){
@@ -468,8 +487,9 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
fun turnResultItemsToDownloadItems(items: List) : List {
val list : MutableList = mutableListOf()
- val preferredType = sharedPreferences.getString("preferred_download_type", "video")
+ var preferredType = sharedPreferences.getString("preferred_download_type", "video")
items.forEach {
+ if (preferredType == Type.auto.toString()) preferredType = getSuitableDownloadType(it!!.url).toString()
list.add(createDownloadItemFromResult(it!!, Type.valueOf(preferredType!!)))
}
return list
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt
index 9b0b2e08..e5f234f1 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/ResultViewModel.kt
@@ -3,6 +3,7 @@ package com.deniscerri.ytdlnis.database.viewmodel
import android.app.Application
import android.content.SharedPreferences
import android.util.Log
+import android.util.Patterns
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -111,14 +112,14 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
}
private fun getQueryType(inputQuery: String) : String {
var type = "Search"
- val p = Pattern.compile("(^(https?)://(www.)?(music.)?youtu(.be)?)|(^(https?)://(www.)?piped.video)")
+ val p = Pattern.compile("(^(https?)://(www.)?youtu(.be)?)|(^(https?)://(www.)?piped.video)")
val m = p.matcher(inputQuery)
if (m.find()) {
type = "YT_Video"
- if (inputQuery.contains("playlist?list=") && !inputQuery.contains("music.youtu")) {
+ if (inputQuery.contains("playlist?list=")) {
type = "YT_Playlist"
}
- } else if (inputQuery.contains("http")) {
+ } else if (Patterns.WEB_URL.matcher(inputQuery).matches()) {
type = "Default"
}
return type
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
index a0239791..cfe0b4fa 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt
@@ -159,7 +159,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
homeAdapter!!.submitList(it)
resultsList = it
if(resultViewModel.repository.itemCount.value > 1 || resultViewModel.repository.itemCount.value == -1){
- if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist) && !loadingItems){
+ if (it.size > 1 && it[0].playlistTitle.isNotEmpty() && !loadingItems){
downloadAllFabCoordinator!!.visibility = VISIBLE
}else{
downloadAllFabCoordinator!!.visibility = GONE
@@ -187,7 +187,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
recyclerView?.setPadding(0,0,0,100)
shimmerCards!!.stopShimmer()
shimmerCards!!.visibility = GONE
- if (resultsList!!.size > 1 && resultsList!![0]!!.playlistTitle.isNotEmpty() && resultsList!![0]!!.playlistTitle != getString(R.string.trendingPlaylist)){
+ if (resultsList!!.size > 1 && resultsList!![0]!!.playlistTitle.isNotEmpty()){
downloadAllFabCoordinator!!.visibility = VISIBLE
}else{
downloadAllFabCoordinator!!.visibility = GONE
diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt
index ac4fbfd2..f13fe9b1 100644
--- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt
+++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt
@@ -11,6 +11,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
+import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
@@ -64,7 +65,6 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
super.setupDialog(dialog, style)
val view = LayoutInflater.from(context).inflate(R.layout.configure_download_bottom_sheet, null)
dialog.setContentView(view)
-
dialog.setOnShowListener {
behavior = BottomSheetBehavior.from(view.parent as View)
val displayMetrics = DisplayMetrics()
@@ -80,7 +80,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
overScrollMode = View.OVER_SCROLL_NEVER
}
- val fragments = mutableListOf(
+ val fragments = mutableListOf(
DownloadAudioFragment(resultItem, downloadItem),
DownloadVideoFragment(resultItem, downloadItem)
)
@@ -161,6 +161,9 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
viewPager2.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
tabLayout.selectTab(tabLayout.getTabAt(position))
+ runCatching {
+ updateTitleAuthorWhenSwitching()
+ }
}
})
@@ -168,22 +171,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri
val ok = view.findViewById