added search by author
This commit is contained in:
parent
6686868de0
commit
2630954136
33 changed files with 181 additions and 147 deletions
|
|
@ -64,10 +64,11 @@ android {
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
|
|
||||||
dev {
|
beta {
|
||||||
minifyEnabled false
|
minifyEnabled true
|
||||||
|
versionNameSuffix "$project.betaVersionNameSuffix"
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
debuggable true
|
debuggable false
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,4 +181,5 @@ dependencies {
|
||||||
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4'
|
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4'
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
|
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
|
||||||
implementation "com.github.Irineu333:Highlight-KT:1.0.4"
|
implementation "com.github.Irineu333:Highlight-KT:1.0.4"
|
||||||
|
implementation "com.anggrayudi:storage:1.5.4"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import android.graphics.drawable.ColorDrawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.PersistableBundle
|
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
|
@ -24,6 +23,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.forEach
|
import androidx.core.view.forEach
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.fragment.app.FragmentContainerView
|
import androidx.fragment.app.FragmentContainerView
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
|
@ -39,7 +39,6 @@ import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
|
||||||
import com.deniscerri.ytdlnis.ui.BaseActivity
|
import com.deniscerri.ytdlnis.ui.BaseActivity
|
||||||
import com.deniscerri.ytdlnis.ui.HomeFragment
|
import com.deniscerri.ytdlnis.ui.HomeFragment
|
||||||
import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity
|
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.ThemeUtil
|
||||||
import com.deniscerri.ytdlnis.util.UpdateUtil
|
import com.deniscerri.ytdlnis.util.UpdateUtil
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
|
|
@ -50,7 +49,6 @@ import com.google.android.material.navigation.NavigationView
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.File
|
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
|
@ -108,13 +106,7 @@ class MainActivity : BaseActivity() {
|
||||||
|
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
val startDestination = sharedPreferences.getString("start_destination", "")
|
|
||||||
val graph = navController.navInflater.inflate(R.navigation.nav_graph)
|
val graph = navController.navInflater.inflate(R.navigation.nav_graph)
|
||||||
when(startDestination) {
|
|
||||||
"History" -> graph.setStartDestination(R.id.historyFragment)
|
|
||||||
"More" -> if (navigationView is NavigationBarView) graph.setStartDestination(R.id.moreFragment) else graph.setStartDestination(R.id.homeFragment)
|
|
||||||
else -> graph.setStartDestination(R.id.homeFragment)
|
|
||||||
}
|
|
||||||
navController.graph = graph
|
navController.graph = graph
|
||||||
|
|
||||||
if (navigationView is NavigationBarView){
|
if (navigationView is NavigationBarView){
|
||||||
|
|
@ -183,48 +175,78 @@ class MainActivity : BaseActivity() {
|
||||||
cookieViewModel.updateCookiesFile()
|
cookieViewModel.updateCookiesFile()
|
||||||
val intent = intent
|
val intent = intent
|
||||||
handleIntents(intent)
|
handleIntents(intent)
|
||||||
|
|
||||||
|
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||||
|
if (navigationView is NavigationBarView){
|
||||||
|
when(destination.id){
|
||||||
|
R.id.homeFragment, R.id.historyFragment, R.id.moreFragment -> showBottomNavigation()
|
||||||
|
else -> hideBottomNavigation()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationView.visibilityChanged {
|
||||||
|
if (it.isVisible){
|
||||||
|
val curr = navController.currentDestination?.id
|
||||||
|
if (curr != R.id.homeFragment && curr != R.id.historyFragment && curr != R.id.moreFragment) hideBottomNavigation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when(sharedPreferences.getString("start_destination", "")) {
|
||||||
|
"History" -> navController.navigate(R.id.historyFragment)
|
||||||
|
"Queue" -> navController.navigate(R.id.downloadQueueMainFragment)
|
||||||
|
"More" -> if (navigationView is NavigationBarView) graph.setStartDestination(R.id.moreFragment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun View.visibilityChanged(action: (View) -> Unit) {
|
||||||
fun hideBottomNavigation(){
|
this.viewTreeObserver.addOnGlobalLayoutListener {
|
||||||
if(navigationView is NavigationBarView){
|
val newVis: Int = this.visibility
|
||||||
if (navigationView is BottomNavigationView){
|
if (this.tag as Int? != newVis) {
|
||||||
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams<ConstraintLayout.LayoutParams> {
|
this.tag = this.visibility
|
||||||
bottomToTop = ConstraintLayout.LayoutParams.UNSET
|
// visibility has changed
|
||||||
bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
|
action(this)
|
||||||
}
|
|
||||||
navigationView.animate()?.translationY(navigationView.height.toFloat())?.setDuration(300)?.withEndAction {
|
|
||||||
navigationView.visibility = View.GONE
|
|
||||||
}?.start()
|
|
||||||
}else{
|
|
||||||
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams {
|
|
||||||
this.width = LayoutParams.MATCH_PARENT
|
|
||||||
}
|
|
||||||
navigationView.animate()?.translationX(-navigationView.width.toFloat())?.setDuration(300)?.withEndAction {
|
|
||||||
navigationView.visibility = View.GONE
|
|
||||||
}?.start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showBottomNavigation(){
|
|
||||||
if(navigationView is NavigationBarView){
|
fun hideBottomNavigation(){
|
||||||
if (navigationView is BottomNavigationView){
|
if (navigationView is BottomNavigationView){
|
||||||
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams<ConstraintLayout.LayoutParams> {
|
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
bottomToTop = R.id.bottomNavigationView
|
bottomToTop = ConstraintLayout.LayoutParams.UNSET
|
||||||
bottomToBottom = ConstraintLayout.LayoutParams.UNSET
|
bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
|
||||||
}
|
|
||||||
navigationView.animate()?.translationY(0F)?.setDuration(300)?.withEndAction {
|
|
||||||
navigationView.visibility = View.VISIBLE
|
|
||||||
}?.start()
|
|
||||||
}else{
|
|
||||||
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams {
|
|
||||||
this.width = 0
|
|
||||||
}
|
|
||||||
navigationView.animate()?.translationX(0F)?.setDuration(300)?.withEndAction {
|
|
||||||
navigationView.visibility = View.VISIBLE
|
|
||||||
}?.start()
|
|
||||||
}
|
}
|
||||||
|
navigationView.animate()?.translationY(navigationView.height.toFloat())?.setDuration(300)?.withEndAction {
|
||||||
|
navigationView.visibility = View.GONE
|
||||||
|
}?.start()
|
||||||
|
}else{
|
||||||
|
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams {
|
||||||
|
this.width = LayoutParams.MATCH_PARENT
|
||||||
|
}
|
||||||
|
navigationView.animate()?.translationX(-navigationView.width.toFloat())?.setDuration(300)?.withEndAction {
|
||||||
|
navigationView.visibility = View.GONE
|
||||||
|
}?.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showBottomNavigation(){
|
||||||
|
if (navigationView is BottomNavigationView){
|
||||||
|
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
bottomToTop = R.id.bottomNavigationView
|
||||||
|
bottomToBottom = ConstraintLayout.LayoutParams.UNSET
|
||||||
|
}
|
||||||
|
navigationView.animate()?.translationY(0F)?.setDuration(300)?.withEndAction {
|
||||||
|
navigationView.visibility = View.VISIBLE
|
||||||
|
}?.start()
|
||||||
|
}else{
|
||||||
|
findViewById<FragmentContainerView>(R.id.frame_layout).updateLayoutParams {
|
||||||
|
this.width = 0
|
||||||
|
}
|
||||||
|
navigationView.animate()?.translationX(0F)?.setDuration(300)?.withEndAction {
|
||||||
|
navigationView.visibility = View.VISIBLE
|
||||||
|
}?.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ interface DownloadDao {
|
||||||
@Query("SELECT id FROM downloads ORDER BY id DESC LIMIT 1")
|
@Query("SELECT id FROM downloads ORDER BY id DESC LIMIT 1")
|
||||||
fun getLastDownloadId(): Long
|
fun getLastDownloadId(): Long
|
||||||
|
|
||||||
|
@Query("SELECT status FROM downloads WHERE id=:id")
|
||||||
|
fun checkStatus(id: Long) : String
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
suspend fun insert(item: DownloadItem) : Long
|
suspend fun insert(item: DownloadItem) : Long
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,19 @@ import com.deniscerri.ytdlnis.database.models.HistoryItem
|
||||||
@Dao
|
@Dao
|
||||||
interface HistoryDao {
|
interface HistoryDao {
|
||||||
|
|
||||||
@Query("SELECT * FROM history WHERE title LIKE '%'||:query||'%' AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " +
|
@Query("SELECT * FROM history WHERE (title LIKE '%'||:query||'%' OR author LIKE '%'||:query||'%') AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " +
|
||||||
"CASE WHEN :sort = 'ASC' THEN id END ASC," +
|
"CASE WHEN :sort = 'ASC' THEN id END ASC," +
|
||||||
"CASE WHEN :sort = 'DESC' THEN id END DESC," +
|
"CASE WHEN :sort = 'DESC' THEN id END DESC," +
|
||||||
"CASE WHEN :sort = '' THEN id END DESC ")
|
"CASE WHEN :sort = '' THEN id END DESC ")
|
||||||
fun getHistorySortedByID(query : String, format : String, site : String, sort : String) : List<HistoryItem>
|
fun getHistorySortedByID(query : String, format : String, site : String, sort : String) : List<HistoryItem>
|
||||||
|
|
||||||
@Query("SELECT * FROM history WHERE title LIKE '%'||:query||'%' AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " +
|
@Query("SELECT * FROM history WHERE (title LIKE '%'||:query||'%' OR author LIKE '%'||:query||'%') AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " +
|
||||||
"CASE WHEN :sort = 'ASC' THEN title END ASC," +
|
"CASE WHEN :sort = 'ASC' THEN title END ASC," +
|
||||||
"CASE WHEN :sort = 'DESC' THEN title END DESC," +
|
"CASE WHEN :sort = 'DESC' THEN title END DESC," +
|
||||||
"CASE WHEN :sort = '' THEN title END DESC ")
|
"CASE WHEN :sort = '' THEN title END DESC ")
|
||||||
fun getHistorySortedByTitle(query : String, format : String, site : String, sort : String) : List<HistoryItem>
|
fun getHistorySortedByTitle(query : String, format : String, site : String, sort : String) : List<HistoryItem>
|
||||||
|
|
||||||
@Query("SELECT * FROM history WHERE title LIKE '%'||:query||'%' AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " +
|
@Query("SELECT * FROM history WHERE (title LIKE '%'||:query||'%' OR author LIKE '%'||:query||'%') AND type LIKE '%'||:format||'%' AND website LIKE '%'||:site||'%' ORDER BY " +
|
||||||
"CASE WHEN :sort = 'ASC' THEN author END ASC," +
|
"CASE WHEN :sort = 'ASC' THEN author END ASC," +
|
||||||
"CASE WHEN :sort = 'DESC' THEN author END DESC," +
|
"CASE WHEN :sort = 'DESC' THEN author END DESC," +
|
||||||
"CASE WHEN :sort = '' THEN author END DESC ")
|
"CASE WHEN :sort = '' THEN author END DESC ")
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,8 @@ import android.content.SharedPreferences
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.os.Environment
|
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
|
@ -43,7 +41,6 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
@ -141,12 +138,16 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
||||||
return repository.getItemByID(id)
|
return repository.getItemByID(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createDownloadItemFromResult(resultItem: ResultItem, type: Type) : DownloadItem {
|
fun createDownloadItemFromResult(resultItem: ResultItem, givenType: Type) : DownloadItem {
|
||||||
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false)
|
||||||
val saveSubs = sharedPreferences.getBoolean("write_subtitles", false)
|
val saveSubs = sharedPreferences.getBoolean("write_subtitles", false)
|
||||||
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
val addChapters = sharedPreferences.getBoolean("add_chapters", false)
|
||||||
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
|
val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false)
|
||||||
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false)
|
||||||
|
|
||||||
|
var type = givenType
|
||||||
|
if(type == Type.command && commandTemplateDao.getTotalNumber() == 0) type = Type.video
|
||||||
|
|
||||||
val customFileNameTemplate = when(type) {
|
val customFileNameTemplate = when(type) {
|
||||||
Type.audio -> sharedPreferences.getString("file_name_template_audio", "%(uploader)s - %(title)s")
|
Type.audio -> sharedPreferences.getString("file_name_template_audio", "%(uploader)s - %(title)s")
|
||||||
Type.video -> sharedPreferences.getString("file_name_template", "%(uploader)s - %(title)s")
|
Type.video -> sharedPreferences.getString("file_name_template", "%(uploader)s - %(title)s")
|
||||||
|
|
@ -159,6 +160,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
||||||
else -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())
|
else -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||||
|
|
||||||
val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!))
|
val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!))
|
||||||
|
|
@ -272,7 +274,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
|
||||||
val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!))
|
val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!))
|
||||||
val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs)
|
val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs)
|
||||||
|
|
||||||
return DownloadItem(historyItem.downloadId,
|
return DownloadItem(0,
|
||||||
historyItem.url,
|
historyItem.url,
|
||||||
historyItem.title,
|
historyItem.title,
|
||||||
historyItem.author,
|
historyItem.author,
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_home, container, false)
|
fragmentView = inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
activity = getActivity()
|
activity = getActivity()
|
||||||
mainActivity = activity as MainActivity?
|
mainActivity = activity as MainActivity?
|
||||||
mainActivity?.showBottomNavigation()
|
|
||||||
quickLaunchSheet = false
|
quickLaunchSheet = false
|
||||||
return fragmentView
|
return fragmentView
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import com.yausername.youtubedl_android.YoutubeDL
|
||||||
|
|
||||||
|
|
||||||
class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickListener, OnClickListener {
|
class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickListener, OnClickListener {
|
||||||
private var _binding : FragmentHomeBinding? = null
|
|
||||||
private var fragmentView: View? = null
|
private var fragmentView: View? = null
|
||||||
private var activity: Activity? = null
|
private var activity: Activity? = null
|
||||||
private lateinit var downloadViewModel : DownloadViewModel
|
private lateinit var downloadViewModel : DownloadViewModel
|
||||||
|
|
@ -42,7 +41,6 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||||
activity = getActivity()
|
activity = getActivity()
|
||||||
notificationUtil = NotificationUtil(requireContext())
|
notificationUtil = NotificationUtil(requireContext())
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
|
|
||||||
class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
||||||
private var _binding : FragmentHomeBinding? = null
|
|
||||||
private var fragmentView: View? = null
|
private var fragmentView: View? = null
|
||||||
private var activity: Activity? = null
|
private var activity: Activity? = null
|
||||||
private lateinit var downloadViewModel : DownloadViewModel
|
private lateinit var downloadViewModel : DownloadViewModel
|
||||||
|
|
@ -58,7 +57,6 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||||
activity = getActivity()
|
activity = getActivity()
|
||||||
selectedObjects = arrayListOf()
|
selectedObjects = arrayListOf()
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,11 @@ import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
import com.deniscerri.ytdlnis.database.repository.DownloadRepository
|
||||||
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
|
||||||
import com.deniscerri.ytdlnis.util.NotificationUtil
|
import com.deniscerri.ytdlnis.util.NotificationUtil
|
||||||
|
import com.deniscerri.ytdlnis.work.DownloadWorker
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import com.yausername.youtubedl_android.YoutubeDL
|
import com.yausername.youtubedl_android.YoutubeDL
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -72,6 +74,15 @@ class DownloadQueueMainFragment : Fragment(){
|
||||||
viewPager2.adapter = fragmentAdapter
|
viewPager2.adapter = fragmentAdapter
|
||||||
viewPager2.isSaveFromParentEnabled = false
|
viewPager2.isSaveFromParentEnabled = false
|
||||||
|
|
||||||
|
TabLayoutMediator(tabLayout, viewPager2) { tab, position ->
|
||||||
|
when (position) {
|
||||||
|
0 -> tab.text = getString(R.string.running)
|
||||||
|
1 -> tab.text = getString(R.string.in_queue)
|
||||||
|
2 -> tab.text = getString(R.string.cancelled)
|
||||||
|
3 -> tab.text = getString(R.string.errored)
|
||||||
|
}
|
||||||
|
}.attach()
|
||||||
|
|
||||||
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||||
override fun onTabSelected(tab: TabLayout.Tab?) {
|
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||||
viewPager2.setCurrentItem(tab!!.position, true)
|
viewPager2.setCurrentItem(tab!!.position, true)
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ import java.io.File
|
||||||
|
|
||||||
|
|
||||||
class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener, OnItemClickListener {
|
class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener, OnItemClickListener {
|
||||||
private var _binding : FragmentHomeBinding? = null
|
|
||||||
private var fragmentView: View? = null
|
private var fragmentView: View? = null
|
||||||
private var activity: Activity? = null
|
private var activity: Activity? = null
|
||||||
private lateinit var downloadViewModel : DownloadViewModel
|
private lateinit var downloadViewModel : DownloadViewModel
|
||||||
|
|
@ -60,7 +59,6 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||||
activity = getActivity()
|
activity = getActivity()
|
||||||
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_history, container, false)
|
fragmentView = inflater.inflate(R.layout.fragment_history, container, false)
|
||||||
activity = getActivity()
|
activity = getActivity()
|
||||||
mainActivity = activity as MainActivity?
|
mainActivity = activity as MainActivity?
|
||||||
mainActivity?.showBottomNavigation()
|
|
||||||
return fragmentView
|
return fragmentView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,6 @@ import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener {
|
||||||
private var _binding : FragmentHomeBinding? = null
|
|
||||||
private var fragmentView: View? = null
|
private var fragmentView: View? = null
|
||||||
private var activity: Activity? = null
|
private var activity: Activity? = null
|
||||||
private lateinit var downloadViewModel : DownloadViewModel
|
private lateinit var downloadViewModel : DownloadViewModel
|
||||||
|
|
@ -69,7 +68,6 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false)
|
||||||
activity = getActivity()
|
activity = getActivity()
|
||||||
notificationUtil = NotificationUtil(requireContext())
|
notificationUtil = NotificationUtil(requireContext())
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ class CommandTemplatesFragment : Fragment(), TemplatesAdapter.OnItemClickListene
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
mainActivity = activity as MainActivity
|
mainActivity = activity as MainActivity
|
||||||
mainActivity.hideBottomNavigation()
|
|
||||||
return inflater.inflate(R.layout.fragment_command_templates, container, false)
|
return inflater.inflate(R.layout.fragment_command_templates, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ class CookiesFragment : Fragment(), CookieAdapter.OnItemClickListener {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
mainActivity = activity as MainActivity
|
mainActivity = activity as MainActivity
|
||||||
mainActivity.hideBottomNavigation()
|
|
||||||
return inflater.inflate(R.layout.fragment_cookies, container, false)
|
return inflater.inflate(R.layout.fragment_cookies, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ class MoreFragment : Fragment() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
mainActivity = activity as MainActivity
|
mainActivity = activity as MainActivity
|
||||||
mainActivity.showBottomNavigation()
|
|
||||||
return inflater.inflate(R.layout.fragment_more, container, false)
|
return inflater.inflate(R.layout.fragment_more, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,12 @@ import android.content.SharedPreferences
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import android.util.LayoutDirection
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
|
import androidx.core.text.layoutDirection
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
|
@ -47,6 +49,7 @@ import java.io.BufferedReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
class MainSettingsFragment : PreferenceFragmentCompat() {
|
class MainSettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
@ -67,36 +70,38 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
||||||
val navController = findNavController()
|
val navController = findNavController()
|
||||||
|
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
val appearance = findPreference<Preference>("appearance")
|
val appearance = findPreference<Preference>("appearance")
|
||||||
appearance?.summary = "${if (Build.VERSION.SDK_INT < 33) getString(R.string.language) + ", " else ""}${getString(R.string.Theme)}, ${getString(R.string.accents)}, ${getString(R.string.preferred_search_engine)}"
|
val separator = if (Locale(preferences.getString("app_language", "en")!!).layoutDirection == LayoutDirection.RTL) "،" else ","
|
||||||
|
appearance?.summary = "${if (Build.VERSION.SDK_INT < 33) getString(R.string.language) + "$separator " else ""}${getString(R.string.Theme)}$separator ${getString(R.string.accents)}$separator ${getString(R.string.preferred_search_engine)}"
|
||||||
appearance?.setOnPreferenceClickListener {
|
appearance?.setOnPreferenceClickListener {
|
||||||
navController.navigate(R.id.action_mainSettingsFragment_to_appearanceSettingsFragment)
|
navController.navigate(R.id.action_mainSettingsFragment_to_appearanceSettingsFragment)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
val folders = findPreference<Preference>("folders")
|
val folders = findPreference<Preference>("folders")
|
||||||
folders?.summary = "${getString(R.string.music_directory)}, ${getString(R.string.video_directory)}, ${getString(R.string.command_directory)}"
|
folders?.summary = "${getString(R.string.music_directory)}$separator ${getString(R.string.video_directory)}$separator ${getString(R.string.command_directory)}"
|
||||||
folders?.setOnPreferenceClickListener {
|
folders?.setOnPreferenceClickListener {
|
||||||
navController.navigate(R.id.action_mainSettingsFragment_to_folderSettingsFragment)
|
navController.navigate(R.id.action_mainSettingsFragment_to_folderSettingsFragment)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
val downloading = findPreference<Preference>("downloading")
|
val downloading = findPreference<Preference>("downloading")
|
||||||
downloading?.summary = "${getString(R.string.quick_download)}, ${getString(R.string.concurrent_downloads)}, ${getString(R.string.limit_rate)}"
|
downloading?.summary = "${getString(R.string.quick_download)}$separator ${getString(R.string.concurrent_downloads)}$separator ${getString(R.string.limit_rate)}"
|
||||||
downloading?.setOnPreferenceClickListener {
|
downloading?.setOnPreferenceClickListener {
|
||||||
navController.navigate(R.id.action_mainSettingsFragment_to_downloadSettingsFragment)
|
navController.navigate(R.id.action_mainSettingsFragment_to_downloadSettingsFragment)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
val processing = findPreference<Preference>("processing")
|
val processing = findPreference<Preference>("processing")
|
||||||
processing?.summary = "${getString(R.string.sponsorblock)}, ${getString(R.string.embed_subtitles)}, ${getString(R.string.add_chapters)}"
|
processing?.summary = "${getString(R.string.sponsorblock)}$separator ${getString(R.string.embed_subtitles)}$separator ${getString(R.string.add_chapters)}"
|
||||||
processing?.setOnPreferenceClickListener {
|
processing?.setOnPreferenceClickListener {
|
||||||
navController.navigate(R.id.action_mainSettingsFragment_to_processingSettingsFragment)
|
navController.navigate(R.id.action_mainSettingsFragment_to_processingSettingsFragment)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
val updating = findPreference<Preference>("updating")
|
val updating = findPreference<Preference>("updating")
|
||||||
updating?.summary = "${getString(R.string.update_ytdl)}, ${getString(R.string.format_source)}, ${getString(R.string.update_app)}"
|
updating?.summary = "${getString(R.string.update_ytdl)}$separator ${getString(R.string.format_source)}$separator ${getString(R.string.update_app)}"
|
||||||
updating?.setOnPreferenceClickListener {
|
updating?.setOnPreferenceClickListener {
|
||||||
navController.navigate(R.id.action_mainSettingsFragment_to_updateSettingsFragment)
|
navController.navigate(R.id.action_mainSettingsFragment_to_updateSettingsFragment)
|
||||||
true
|
true
|
||||||
|
|
@ -118,7 +123,6 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
|
||||||
cookieViewModel = ViewModelProvider(this)[CookieViewModel::class.java]
|
cookieViewModel = ViewModelProvider(this)[CookieViewModel::class.java]
|
||||||
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
|
commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java]
|
||||||
|
|
||||||
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
|
||||||
backup = findPreference("backup")
|
backup = findPreference("backup")
|
||||||
restore = findPreference("restore")
|
restore = findPreference("restore")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ import android.os.Environment
|
||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import androidx.core.net.toUri
|
import com.anggrayudi.storage.callback.FileCallback
|
||||||
|
import com.anggrayudi.storage.file.moveTo
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||||
import okhttp3.internal.closeQuietly
|
import okhttp3.internal.closeQuietly
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
@ -91,7 +91,7 @@ object FileUtil {
|
||||||
if(it.name.contains(".part-Frag")) return@forEach
|
if(it.name.contains(".part-Frag")) return@forEach
|
||||||
|
|
||||||
//sending to main or SD CARD
|
//sending to main or SD CARD
|
||||||
if (currentDirectory.exists()){
|
if (currentDirectory.exists() && Build.VERSION.SDK_INT >= 26){
|
||||||
if (Build.VERSION.SDK_INT >= 26 ){
|
if (Build.VERSION.SDK_INT >= 26 ){
|
||||||
Files.move(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
Files.move(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -134,7 +134,7 @@ object FileUtil {
|
||||||
if (Build.VERSION.SDK_INT >= 26 ){
|
if (Build.VERSION.SDK_INT >= 26 ){
|
||||||
Files.move(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
Files.move(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||||
}else{
|
}else{
|
||||||
it.renameTo(destFile)
|
it.moveTo(context, destFile.parent!!, destFile.name, FileCallback.ConflictResolution.REPLACE)
|
||||||
}
|
}
|
||||||
fileList.add(destFile)
|
fileList.add(destFile)
|
||||||
}
|
}
|
||||||
|
|
@ -170,8 +170,12 @@ object FileUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkLogFileExists(context: Context, item: DownloadItem) : File? {
|
fun checkLogFileExists(context: Context, item: DownloadItem) : File? {
|
||||||
val dir = File(context.filesDir.absolutePath + "/logs/")
|
return try {
|
||||||
return dir.listFiles()?.toList()?.first { it.name.startsWith(item.id.toString()) }
|
val dir = File(context.filesDir.absolutePath + "/logs/")
|
||||||
|
dir.listFiles()?.toList()?.first { it.name.startsWith(item.id.toString()) }
|
||||||
|
}catch (e: Exception){
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLogFileForTerminal(context: Context, command: String) : File {
|
fun getLogFileForTerminal(context: Context, command: String) : File {
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ class InfoUtil(private val context: Context) {
|
||||||
|
|
||||||
@Throws(JSONException::class)
|
@Throws(JSONException::class)
|
||||||
fun searchFromPiped(query: String): ArrayList<ResultItem?> {
|
fun searchFromPiped(query: String): ArrayList<ResultItem?> {
|
||||||
val data = genericRequest(pipedURL + "search?q=" + query + "?filter=videos")
|
val data = genericRequest(pipedURL + "/search?q=" + query + "?filter=videos")
|
||||||
val dataArray = data.getJSONArray("items")
|
val dataArray = data.getJSONArray("items")
|
||||||
if (dataArray.length() == 0) return getFromYTDL(query)
|
if (dataArray.length() == 0) return getFromYTDL(query)
|
||||||
for (i in 0 until dataArray.length()) {
|
for (i in 0 until dataArray.length()) {
|
||||||
|
|
@ -233,7 +233,7 @@ class InfoUtil(private val context: Context) {
|
||||||
try {
|
try {
|
||||||
init()
|
init()
|
||||||
if (key!!.isEmpty()) {
|
if (key!!.isEmpty()) {
|
||||||
val res = genericRequest(pipedURL + "streams/" + id)
|
val res = genericRequest(pipedURL + "/streams/" + id)
|
||||||
return if (res.length() == 0) getFromYTDL("https://www.youtube.com/watch?v=$id")[0] else createVideoFromPipedJSON(
|
return if (res.length() == 0) getFromYTDL("https://www.youtube.com/watch?v=$id")[0] else createVideoFromPipedJSON(
|
||||||
res, id
|
res, id
|
||||||
)
|
)
|
||||||
|
|
@ -544,7 +544,7 @@ class InfoUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTrendingFromPiped(): ArrayList<ResultItem?> {
|
private fun getTrendingFromPiped(): ArrayList<ResultItem?> {
|
||||||
val url = pipedURL + "trending?region=" + countryCODE
|
val url = pipedURL + "/trending?region=" + countryCODE
|
||||||
val res = genericArrayRequest(url)
|
val res = genericArrayRequest(url)
|
||||||
try {
|
try {
|
||||||
for (i in 0 until res.length()) {
|
for (i in 0 until res.length()) {
|
||||||
|
|
@ -586,7 +586,7 @@ class InfoUtil(private val context: Context) {
|
||||||
val formatSource = sharedPreferences.getString("formats_source", "yt-dlp")
|
val formatSource = sharedPreferences.getString("formats_source", "yt-dlp")
|
||||||
return if(m.find() && formatSource == "piped"){
|
return if(m.find() && formatSource == "piped"){
|
||||||
val id = getIDFromYoutubeURL(url)
|
val id = getIDFromYoutubeURL(url)
|
||||||
val res = genericRequest(pipedURL + "streams/" + id)
|
val res = genericRequest(pipedURL + "/streams/" + id)
|
||||||
if (res.length() == 0) getFromYTDL(url)[0]!!
|
if (res.length() == 0) getFromYTDL(url)[0]!!
|
||||||
val item = createVideoFromPipedJSON(res, id)
|
val item = createVideoFromPipedJSON(res, id)
|
||||||
item!!.formats
|
item!!.formats
|
||||||
|
|
@ -719,7 +719,7 @@ class InfoUtil(private val context: Context) {
|
||||||
}else{
|
}else{
|
||||||
urls.forEach {
|
urls.forEach {
|
||||||
val id = getIDFromYoutubeURL(it)
|
val id = getIDFromYoutubeURL(it)
|
||||||
val res = genericRequest(pipedURL + "streams/" + id)
|
val res = genericRequest(pipedURL + "/streams/" + id)
|
||||||
val vid = createVideoFromPipedJSON(res, id)
|
val vid = createVideoFromPipedJSON(res, id)
|
||||||
progress(vid!!.formats)
|
progress(vid!!.formats)
|
||||||
}
|
}
|
||||||
|
|
@ -1028,6 +1028,8 @@ class InfoUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val pipedURL = sharedPreferences.getString("piped_instance", defaultPipedURL)?.ifEmpty { defaultPipedURL }?.removeSuffix("/")
|
||||||
|
|
||||||
class PlaylistTuple internal constructor(
|
class PlaylistTuple internal constructor(
|
||||||
var nextPageToken: String,
|
var nextPageToken: String,
|
||||||
var videos: ArrayList<ResultItem?>
|
var videos: ArrayList<ResultItem?>
|
||||||
|
|
@ -1036,7 +1038,7 @@ class InfoUtil(private val context: Context) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "API MANAGER"
|
private const val TAG = "API MANAGER"
|
||||||
private const val invidousURL = "https://invidious.baczek.me/api/v1/"
|
private const val invidousURL = "https://invidious.baczek.me/api/v1/"
|
||||||
private const val pipedURL = "https://pipedapi.kavin.rocks/"
|
private const val defaultPipedURL = "https://pipedapi.kavin.rocks/"
|
||||||
private var countryCODE: String = ""
|
private var countryCODE: String = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package com.deniscerri.ytdlnis.work
|
package com.deniscerri.ytdlnis.work
|
||||||
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
|
@ -14,7 +12,6 @@ import androidx.work.ForegroundInfo
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import androidx.work.workDataOf
|
import androidx.work.workDataOf
|
||||||
import com.deniscerri.ytdlnis.MainActivity
|
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.database.DBManager
|
import com.deniscerri.ytdlnis.database.DBManager
|
||||||
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
import com.deniscerri.ytdlnis.database.dao.DownloadDao
|
||||||
|
|
@ -61,6 +58,8 @@ class DownloadWorker(
|
||||||
return Result.failure()
|
return Result.failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downloadItem.status != DownloadRepository.Status.Queued.toString()) return Result.failure()
|
||||||
|
|
||||||
Log.e(TAG, downloadItem.toString())
|
Log.e(TAG, downloadItem.toString())
|
||||||
|
|
||||||
runBlocking{
|
runBlocking{
|
||||||
|
|
@ -208,6 +207,8 @@ class DownloadWorker(
|
||||||
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
request.addOption("--parse-metadata", "%(album,title)s:%(meta_album)s")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request.addOption("--audio-quality", sharedPreferences.getInt("audio_quality", 5))
|
||||||
|
|
||||||
if (downloadItem.audioPreferences.splitByChapters && downloadItem.downloadSections.isBlank()){
|
if (downloadItem.audioPreferences.splitByChapters && downloadItem.downloadSections.isBlank()){
|
||||||
request.addOption("--split-chapters")
|
request.addOption("--split-chapters")
|
||||||
request.addOption("-P", tempFileDir.absolutePath)
|
request.addOption("-P", tempFileDir.absolutePath)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:height="24dp"
|
<vector android:height="24dp"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM16,13h-3v3.75c0,1.24 -1.01,2.25 -2.25,2.25S8.5,17.99 8.5,16.75c0,-1.24 1.01,-2.25 2.25,-2.25c0.46,0 0.89,0.14 1.25,0.38V11h4V13zM13,9V3.5L18.5,9H13z"/>
|
<path android:fillColor="?android:colorAccent" android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM16,13h-3v3.75c0,1.24 -1.01,2.25 -2.25,2.25S8.5,17.99 8.5,16.75c0,-1.24 1.01,-2.25 2.25,-2.25c0.46,0 0.89,0.14 1.25,0.38V11h4V13zM13,9V3.5L18.5,9H13z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
android:viewportHeight="24"
|
android:viewportHeight="24"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
|
<path android:fillColor="?android:colorAccent" android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:height="24dp"
|
<vector android:height="24dp"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M14,2H6.01c-1.1,0 -2,0.89 -2,2L4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V8L14,2zM13,9V3.5L18.5,9H13zM14,14l2,-1.06v4.12L14,16v1c0,0.55 -0.45,1 -1,1H9c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h4c0.55,0 1,0.45 1,1V14z"/>
|
<path android:fillColor="?android:colorAccent" android:pathData="M14,2H6.01c-1.1,0 -2,0.89 -2,2L4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V8L14,2zM13,9V3.5L18.5,9H13zM14,14l2,-1.06v4.12L14,16v1c0,0.55 -0.45,1 -1,1H9c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h4c0.55,0 1,0.45 1,1V14z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@
|
||||||
android:id="@+id/bottomNavigationView"
|
android:id="@+id/bottomNavigationView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:labelVisibilityMode="unlabeled"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,6 @@
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
app:menu="@menu/download_multiple_menu" />
|
app:menu="@menu/download_multiple_menu" />
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:srcCompat="@drawable/ic_edit" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
tools:context="com.deniscerri.ytdlnis.ui.more.TerminalActivity">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -38,30 +37,7 @@
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:backgroundTint="@android:color/transparent"
|
android:backgroundTint="@android:color/transparent"
|
||||||
app:tabGravity="fill"
|
app:tabGravity="fill"
|
||||||
app:tabMode="scrollable">
|
app:tabMode="scrollable" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:text="@string/running" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:text="@string/in_queue" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:text="@string/cancelled" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:text="@string/errored" />
|
|
||||||
|
|
||||||
|
|
||||||
</com.google.android.material.tabs.TabLayout>
|
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/download_viewpager"
|
android:id="@+id/download_viewpager"
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.recyclerview.widget.RecyclerView android:id="@+id/download_recyclerview"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:fillViewport="true"
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
android:scrollbars="none">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
android:id="@+id/download_recyclerview"
|
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
@ -8,25 +8,25 @@
|
||||||
android:id="@+id/preferred_download_type"
|
android:id="@+id/preferred_download_type"
|
||||||
android:title="@string/preferred_download_type"
|
android:title="@string/preferred_download_type"
|
||||||
android:icon="@drawable/baseline_insert_drive_file_24"
|
android:icon="@drawable/baseline_insert_drive_file_24"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/format"
|
android:id="@+id/format"
|
||||||
android:title="@string/format"
|
android:title="@string/format"
|
||||||
android:icon="@drawable/baseline_high_quality_24"
|
android:icon="@drawable/ic_format"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/filename_template"
|
android:id="@+id/filename_template"
|
||||||
android:title="@string/file_name_template"
|
android:title="@string/file_name_template"
|
||||||
android:icon="@drawable/if_file_rename"
|
android:icon="@drawable/if_file_rename"
|
||||||
app:showAsAction="collapseActionView|ifRoom"/>
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/folder"
|
android:id="@+id/folder"
|
||||||
android:title="@string/directories"
|
android:title="@string/directories"
|
||||||
android:icon="@drawable/ic_folders"
|
android:icon="@drawable/baseline_folder_24"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
24
app/src/main/res/navigation/dqueue_nav.xml
Normal file
24
app/src/main/res/navigation/dqueue_nav.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:label="@string/more"
|
||||||
|
app:startDestination="@id/activeDownloadsFragment">
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/activeDownloadsFragment"
|
||||||
|
android:name="com.deniscerri.ytdlnis.ui.downloads.ActiveDownloadsFragment"
|
||||||
|
android:label="ActiveDownloadsFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/queuedDownloadsFragment"
|
||||||
|
android:name="com.deniscerri.ytdlnis.ui.downloads.QueuedDownloadsFragment"
|
||||||
|
android:label="QueuedDownloadsFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/cancelledDownloadsFragment"
|
||||||
|
android:name="com.deniscerri.ytdlnis.ui.downloads.CancelledDownloadsFragment"
|
||||||
|
android:label="CancelledDownloadsFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/erroredDownloadsFragment"
|
||||||
|
android:name="com.deniscerri.ytdlnis.ui.downloads.ErroredDownloadsFragment"
|
||||||
|
android:label="ErroredDownloadsFragment" />
|
||||||
|
</navigation>
|
||||||
|
|
@ -93,6 +93,7 @@
|
||||||
<item>ar</item>
|
<item>ar</item>
|
||||||
<item>az</item>
|
<item>az</item>
|
||||||
<item>bn</item>
|
<item>bn</item>
|
||||||
|
<item>bs</item>
|
||||||
<item>de</item>
|
<item>de</item>
|
||||||
<item>es</item>
|
<item>es</item>
|
||||||
<item>fa</item>
|
<item>fa</item>
|
||||||
|
|
@ -173,12 +174,14 @@
|
||||||
<array name="start_destination">
|
<array name="start_destination">
|
||||||
<item>@string/home</item>
|
<item>@string/home</item>
|
||||||
<item>@string/downloads</item>
|
<item>@string/downloads</item>
|
||||||
|
<item>@string/download_queue</item>
|
||||||
<item>@string/more</item>
|
<item>@string/more</item>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
<array name="start_destination_values">
|
<array name="start_destination_values">
|
||||||
<item>Home</item>
|
<item>Home</item>
|
||||||
<item>History</item>
|
<item>History</item>
|
||||||
|
<item>Queue</item>
|
||||||
<item>More</item>
|
<item>More</item>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -276,4 +276,6 @@
|
||||||
<string name="move_temporary_files">Move Temporary Files</string>
|
<string name="move_temporary_files">Move Temporary Files</string>
|
||||||
<string name="move_temporary_files_summary">Transfer cached files to the downloads folder</string>
|
<string name="move_temporary_files_summary">Transfer cached files to the downloads folder</string>
|
||||||
<string name="format_filtering_hint_2">All items must either be audio or video to use this option</string>
|
<string name="format_filtering_hint_2">All items must either be audio or video to use this option</string>
|
||||||
|
<string name="piped_instance">Piped Instance</string>
|
||||||
|
<string name="piped_instance_summary">Write a PIPED API Server, the app can use for youtube queries and formats</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
<locale android:name="ar"/>
|
<locale android:name="ar"/>
|
||||||
<locale android:name="az"/>
|
<locale android:name="az"/>
|
||||||
<locale android:name="bn"/>
|
<locale android:name="bn"/>
|
||||||
|
<locale android:name="bs"/>
|
||||||
<locale android:name="de"/>
|
<locale android:name="de"/>
|
||||||
<locale android:name="es"/>
|
<locale android:name="es"/>
|
||||||
<locale android:name="fa-IR"/>
|
<locale android:name="fa-IR"/>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,12 @@
|
||||||
app:useSimpleSummaryProvider="true"
|
app:useSimpleSummaryProvider="true"
|
||||||
app:title="@string/format_source" />
|
app:title="@string/format_source" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
app:key="piped_instance"
|
||||||
|
app:defaultValue="https://pipedapi.kavin.rocks"
|
||||||
|
android:summary="@string/piped_instance_summary"
|
||||||
|
app:title="@string/piped_instance" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:widgetLayout="@layout/preferece_material_switch"
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
app:defaultValue="true"
|
app:defaultValue="true"
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,12 @@ buildscript {
|
||||||
def versionMajor = 1
|
def versionMajor = 1
|
||||||
def versionMinor = 6
|
def versionMinor = 6
|
||||||
def versionPatch = 2
|
def versionPatch = 2
|
||||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
def versionBuild = 1 // bump for dogfood builds, public betas, etc.
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
versionCode = versionMajor * 100000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
|
versionCode = versionMajor * 100000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
|
||||||
versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
|
versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||||
|
betaVersionNameSuffix = ".${versionBuild}-beta"
|
||||||
// dependency versions
|
// dependency versions
|
||||||
appCompatVer = '1.6.1'
|
appCompatVer = '1.6.1'
|
||||||
junitVer = '4.13.2'
|
junitVer = '4.13.2'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue