From 26309541367145a801e4a7df2e7cfbd3f14bf530 Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Thu, 8 Jun 2023 18:41:53 +0200 Subject: [PATCH] added search by author --- app/build.gradle | 8 +- .../com/deniscerri/ytdlnis/MainActivity.kt | 104 +++++++++++------- .../ytdlnis/database/dao/DownloadDao.kt | 3 + .../ytdlnis/database/dao/HistoryDao.kt | 6 +- .../database/viewmodel/DownloadViewModel.kt | 12 +- .../com/deniscerri/ytdlnis/ui/HomeFragment.kt | 1 - .../ui/downloads/ActiveDownloadsFragment.kt | 2 - .../downloads/CancelledDownloadsFragment.kt | 2 - .../ui/downloads/DownloadQueueMainFragment.kt | 11 ++ .../ui/downloads/ErroredDownloadsFragment.kt | 2 - .../ytdlnis/ui/downloads/HistoryFragment.kt | 1 - .../ui/downloads/QueuedDownloadsFragment.kt | 2 - .../ui/more/CommandTemplatesFragment.kt | 1 - .../ytdlnis/ui/more/CookiesFragment.kt | 1 - .../ytdlnis/ui/more/MoreFragment.kt | 1 - .../ui/more/settings/MainSettingsFragment.kt | 16 ++- .../com/deniscerri/ytdlnis/util/FileUtil.kt | 16 ++- .../com/deniscerri/ytdlnis/util/InfoUtil.kt | 14 ++- .../deniscerri/ytdlnis/work/DownloadWorker.kt | 7 +- .../res/drawable/baseline_audio_file_24.xml | 2 +- .../baseline_insert_drive_file_24.xml | 2 +- .../res/drawable/baseline_video_file_24.xml | 2 +- .../main/res/layout-sw600dp/activity_main.xml | 1 - .../layout/download_multiple_bottom_sheet.xml | 6 - .../fragment_download_queue_main_screen.xml | 28 +---- .../fragment_generic_download_queue.xml | 20 +--- .../main/res/menu/download_multiple_menu.xml | 12 +- app/src/main/res/navigation/dqueue_nav.xml | 24 ++++ app/src/main/res/values/arrays.xml | 3 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/locales_config.xml | 1 + app/src/main/res/xml/updating_preferences.xml | 6 + build.gradle | 3 +- 33 files changed, 178 insertions(+), 144 deletions(-) create mode 100644 app/src/main/res/navigation/dqueue_nav.xml diff --git a/app/build.gradle b/app/build.gradle index 6ef7ec47..e4c0f495 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,10 +64,11 @@ android { signingConfig signingConfigs.debug } - dev { - minifyEnabled false + beta { + minifyEnabled true + versionNameSuffix "$project.betaVersionNameSuffix" proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - debuggable true + debuggable false signingConfig signingConfigs.debug } @@ -180,4 +181,5 @@ dependencies { implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4' implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1" implementation "com.github.Irineu333:Highlight-KT:1.0.4" + implementation "com.anggrayudi:storage:1.5.4" } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt index 2a31ea72..fca4fbaa 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt @@ -12,7 +12,6 @@ import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Build import android.os.Bundle -import android.os.PersistableBundle import android.provider.Settings import android.util.Log import android.view.View @@ -24,6 +23,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.app.ActivityCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.forEach +import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.fragment.app.FragmentContainerView 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.HomeFragment 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 @@ -50,7 +49,6 @@ import com.google.android.material.navigation.NavigationView import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.BufferedReader -import java.io.File import java.io.InputStreamReader import java.io.Reader import java.nio.charset.Charset @@ -108,13 +106,7 @@ class MainActivity : BaseActivity() { val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) - val startDestination = sharedPreferences.getString("start_destination", "") 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 if (navigationView is NavigationBarView){ @@ -183,48 +175,78 @@ class MainActivity : BaseActivity() { cookieViewModel.updateCookiesFile() val intent = 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) { + this.viewTreeObserver.addOnGlobalLayoutListener { + val newVis: Int = this.visibility + if (this.tag as Int? != newVis) { + this.tag = this.visibility + // visibility has changed + action(this) + } + } } fun hideBottomNavigation(){ - if(navigationView is NavigationBarView){ - if (navigationView is BottomNavigationView){ - findViewById(R.id.frame_layout).updateLayoutParams { - bottomToTop = ConstraintLayout.LayoutParams.UNSET - bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID - } - navigationView.animate()?.translationY(navigationView.height.toFloat())?.setDuration(300)?.withEndAction { - navigationView.visibility = View.GONE - }?.start() - }else{ - findViewById(R.id.frame_layout).updateLayoutParams { - this.width = LayoutParams.MATCH_PARENT - } - navigationView.animate()?.translationX(-navigationView.width.toFloat())?.setDuration(300)?.withEndAction { - navigationView.visibility = View.GONE - }?.start() + if (navigationView is BottomNavigationView){ + findViewById(R.id.frame_layout).updateLayoutParams { + bottomToTop = ConstraintLayout.LayoutParams.UNSET + bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID + } + navigationView.animate()?.translationY(navigationView.height.toFloat())?.setDuration(300)?.withEndAction { + navigationView.visibility = View.GONE + }?.start() + }else{ + findViewById(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){ - if (navigationView is BottomNavigationView){ - findViewById(R.id.frame_layout).updateLayoutParams { - bottomToTop = R.id.bottomNavigationView - bottomToBottom = ConstraintLayout.LayoutParams.UNSET - } - navigationView.animate()?.translationY(0F)?.setDuration(300)?.withEndAction { - navigationView.visibility = View.VISIBLE - }?.start() - }else{ - findViewById(R.id.frame_layout).updateLayoutParams { - this.width = 0 - } - navigationView.animate()?.translationX(0F)?.setDuration(300)?.withEndAction { - navigationView.visibility = View.VISIBLE - }?.start() + if (navigationView is BottomNavigationView){ + findViewById(R.id.frame_layout).updateLayoutParams { + bottomToTop = R.id.bottomNavigationView + bottomToBottom = ConstraintLayout.LayoutParams.UNSET + } + navigationView.animate()?.translationY(0F)?.setDuration(300)?.withEndAction { + navigationView.visibility = View.VISIBLE + }?.start() + }else{ + findViewById(R.id.frame_layout).updateLayoutParams { + this.width = 0 } + navigationView.animate()?.translationX(0F)?.setDuration(300)?.withEndAction { + navigationView.visibility = View.VISIBLE + }?.start() } } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/DownloadDao.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/DownloadDao.kt index ae049e66..fb00f6ca 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/DownloadDao.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/DownloadDao.kt @@ -49,6 +49,9 @@ interface DownloadDao { @Query("SELECT id FROM downloads ORDER BY id DESC LIMIT 1") fun getLastDownloadId(): Long + @Query("SELECT status FROM downloads WHERE id=:id") + fun checkStatus(id: Long) : String + @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(item: DownloadItem) : Long diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt index 3eff7b22..1d12d37d 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/dao/HistoryDao.kt @@ -7,19 +7,19 @@ import com.deniscerri.ytdlnis.database.models.HistoryItem @Dao 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 = 'DESC' THEN id END DESC," + "CASE WHEN :sort = '' THEN id END DESC ") fun getHistorySortedByID(query : String, format : String, site : String, sort : String) : List - @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 = 'DESC' THEN title END DESC," + "CASE WHEN :sort = '' THEN title END DESC ") fun getHistorySortedByTitle(query : String, format : String, site : String, sort : String) : List - @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 = 'DESC' THEN author END DESC," + "CASE WHEN :sort = '' THEN author END DESC ") 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 4d22d4e3..743de87e 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 @@ -6,10 +6,8 @@ import android.content.SharedPreferences import android.content.res.Configuration import android.content.res.Resources import android.net.ConnectivityManager -import android.os.Environment import android.os.Looper import android.util.DisplayMetrics -import android.util.Log import android.widget.Toast import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData @@ -43,7 +41,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.io.File import java.util.Locale import java.util.concurrent.TimeUnit @@ -141,12 +138,16 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application 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 saveSubs = sharedPreferences.getBoolean("write_subtitles", false) val addChapters = sharedPreferences.getBoolean("add_chapters", false) val saveThumb = sharedPreferences.getBoolean("write_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) { Type.audio -> sharedPreferences.getString("file_name_template_audio", "%(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()) } + val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet()) 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 videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs) - return DownloadItem(historyItem.downloadId, + return DownloadItem(0, historyItem.url, historyItem.title, historyItem.author, 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 c9a8ca9d..2a989faf 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt @@ -102,7 +102,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene fragmentView = inflater.inflate(R.layout.fragment_home, container, false) activity = getActivity() mainActivity = activity as MainActivity? - mainActivity?.showBottomNavigation() quickLaunchSheet = false return fragmentView } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ActiveDownloadsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ActiveDownloadsFragment.kt index 3b4666c6..0b547e11 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ActiveDownloadsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ActiveDownloadsFragment.kt @@ -26,7 +26,6 @@ import com.yausername.youtubedl_android.YoutubeDL class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickListener, OnClickListener { - private var _binding : FragmentHomeBinding? = null private var fragmentView: View? = null private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel @@ -42,7 +41,6 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentHomeBinding.inflate(inflater, container, false) fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false) activity = getActivity() notificationUtil = NotificationUtil(requireContext()) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/CancelledDownloadsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/CancelledDownloadsFragment.kt index c13849d5..9a577f87 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/CancelledDownloadsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/CancelledDownloadsFragment.kt @@ -43,7 +43,6 @@ import kotlinx.coroutines.runBlocking class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener { - private var _binding : FragmentHomeBinding? = null private var fragmentView: View? = null private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel @@ -58,7 +57,6 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentHomeBinding.inflate(inflater, container, false) fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false) activity = getActivity() selectedObjects = arrayListOf() diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueMainFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueMainFragment.kt index b9b1a104..d761dc39 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueMainFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueMainFragment.kt @@ -18,9 +18,11 @@ import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.database.repository.DownloadRepository import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel import com.deniscerri.ytdlnis.util.NotificationUtil +import com.deniscerri.ytdlnis.work.DownloadWorker import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator import com.yausername.youtubedl_android.YoutubeDL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -72,6 +74,15 @@ class DownloadQueueMainFragment : Fragment(){ viewPager2.adapter = fragmentAdapter 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 { override fun onTabSelected(tab: TabLayout.Tab?) { viewPager2.setCurrentItem(tab!!.position, true) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ErroredDownloadsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ErroredDownloadsFragment.kt index 51f0b306..398bdc27 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ErroredDownloadsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/ErroredDownloadsFragment.kt @@ -46,7 +46,6 @@ import java.io.File class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener, OnItemClickListener { - private var _binding : FragmentHomeBinding? = null private var fragmentView: View? = null private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel @@ -60,7 +59,6 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentHomeBinding.inflate(inflater, container, false) fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false) activity = getActivity() downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/HistoryFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/HistoryFragment.kt index f9116b62..93b9c249 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/HistoryFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/HistoryFragment.kt @@ -98,7 +98,6 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{ fragmentView = inflater.inflate(R.layout.fragment_history, container, false) activity = getActivity() mainActivity = activity as MainActivity? - mainActivity?.showBottomNavigation() return fragmentView } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/QueuedDownloadsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/QueuedDownloadsFragment.kt index e766e095..5e8bafc0 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/QueuedDownloadsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/QueuedDownloadsFragment.kt @@ -53,7 +53,6 @@ import java.util.Locale class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickListener { - private var _binding : FragmentHomeBinding? = null private var fragmentView: View? = null private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel @@ -69,7 +68,6 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentHomeBinding.inflate(inflater, container, false) fragmentView = inflater.inflate(R.layout.fragment_generic_download_queue, container, false) activity = getActivity() notificationUtil = NotificationUtil(requireContext()) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CommandTemplatesFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CommandTemplatesFragment.kt index 66b1b9ff..7bd57827 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CommandTemplatesFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CommandTemplatesFragment.kt @@ -48,7 +48,6 @@ class CommandTemplatesFragment : Fragment(), TemplatesAdapter.OnItemClickListene savedInstanceState: Bundle? ): View? { mainActivity = activity as MainActivity - mainActivity.hideBottomNavigation() return inflater.inflate(R.layout.fragment_command_templates, container, false) } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CookiesFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CookiesFragment.kt index 545e05f7..e375ac4a 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CookiesFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/CookiesFragment.kt @@ -54,7 +54,6 @@ class CookiesFragment : Fragment(), CookieAdapter.OnItemClickListener { savedInstanceState: Bundle? ): View? { mainActivity = activity as MainActivity - mainActivity.hideBottomNavigation() return inflater.inflate(R.layout.fragment_cookies, container, false) } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/MoreFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/MoreFragment.kt index 4ab288a7..ce97cd32 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/MoreFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/MoreFragment.kt @@ -35,7 +35,6 @@ class MoreFragment : Fragment() { savedInstanceState: Bundle? ): View? { mainActivity = activity as MainActivity - mainActivity.showBottomNavigation() return inflater.inflate(R.layout.fragment_more, container, false) } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/MainSettingsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/MainSettingsFragment.kt index f7a28ed6..d5440197 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/MainSettingsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/MainSettingsFragment.kt @@ -7,10 +7,12 @@ import android.content.SharedPreferences import android.os.Build import android.os.Bundle import android.os.Environment +import android.util.LayoutDirection import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.edit import androidx.core.os.LocaleListCompat +import androidx.core.text.layoutDirection import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController @@ -47,6 +49,7 @@ import java.io.BufferedReader import java.io.File import java.io.InputStreamReader import java.util.Calendar +import java.util.Locale class MainSettingsFragment : PreferenceFragmentCompat() { @@ -67,36 +70,38 @@ class MainSettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.root_preferences, rootKey) val navController = findNavController() + val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) val appearance = findPreference("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 { navController.navigate(R.id.action_mainSettingsFragment_to_appearanceSettingsFragment) true } val folders = findPreference("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 { navController.navigate(R.id.action_mainSettingsFragment_to_folderSettingsFragment) true } val downloading = findPreference("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 { navController.navigate(R.id.action_mainSettingsFragment_to_downloadSettingsFragment) true } val processing = findPreference("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 { navController.navigate(R.id.action_mainSettingsFragment_to_processingSettingsFragment) true } val updating = findPreference("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 { navController.navigate(R.id.action_mainSettingsFragment_to_updateSettingsFragment) true @@ -118,7 +123,6 @@ class MainSettingsFragment : PreferenceFragmentCompat() { cookieViewModel = ViewModelProvider(this)[CookieViewModel::class.java] commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java] - val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) backup = findPreference("backup") restore = findPreference("restore") diff --git a/app/src/main/java/com/deniscerri/ytdlnis/util/FileUtil.kt b/app/src/main/java/com/deniscerri/ytdlnis/util/FileUtil.kt index a2e6247b..2f94c292 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/util/FileUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/util/FileUtil.kt @@ -8,12 +8,12 @@ import android.os.Environment import android.provider.DocumentsContract import android.util.Log 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.database.models.DownloadItem import okhttp3.internal.closeQuietly import java.io.File -import java.io.FileOutputStream import java.net.URLDecoder import java.nio.charset.StandardCharsets import java.nio.file.Files @@ -91,7 +91,7 @@ object FileUtil { if(it.name.contains(".part-Frag")) return@forEach //sending to main or SD CARD - if (currentDirectory.exists()){ + if (currentDirectory.exists() && Build.VERSION.SDK_INT >= 26){ if (Build.VERSION.SDK_INT >= 26 ){ Files.move(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) }else{ @@ -134,7 +134,7 @@ object FileUtil { if (Build.VERSION.SDK_INT >= 26 ){ Files.move(it.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) }else{ - it.renameTo(destFile) + it.moveTo(context, destFile.parent!!, destFile.name, FileCallback.ConflictResolution.REPLACE) } fileList.add(destFile) } @@ -170,8 +170,12 @@ object FileUtil { } fun checkLogFileExists(context: Context, item: DownloadItem) : File? { - val dir = File(context.filesDir.absolutePath + "/logs/") - return dir.listFiles()?.toList()?.first { it.name.startsWith(item.id.toString()) } + return try { + 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 { diff --git a/app/src/main/java/com/deniscerri/ytdlnis/util/InfoUtil.kt b/app/src/main/java/com/deniscerri/ytdlnis/util/InfoUtil.kt index 2e9f5fcb..af4c7b50 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/util/InfoUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/util/InfoUtil.kt @@ -122,7 +122,7 @@ class InfoUtil(private val context: Context) { @Throws(JSONException::class) fun searchFromPiped(query: String): ArrayList { - val data = genericRequest(pipedURL + "search?q=" + query + "?filter=videos") + val data = genericRequest(pipedURL + "/search?q=" + query + "?filter=videos") val dataArray = data.getJSONArray("items") if (dataArray.length() == 0) return getFromYTDL(query) for (i in 0 until dataArray.length()) { @@ -233,7 +233,7 @@ class InfoUtil(private val context: Context) { try { init() 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( res, id ) @@ -544,7 +544,7 @@ class InfoUtil(private val context: Context) { } private fun getTrendingFromPiped(): ArrayList { - val url = pipedURL + "trending?region=" + countryCODE + val url = pipedURL + "/trending?region=" + countryCODE val res = genericArrayRequest(url) try { 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") return if(m.find() && formatSource == "piped"){ val id = getIDFromYoutubeURL(url) - val res = genericRequest(pipedURL + "streams/" + id) + val res = genericRequest(pipedURL + "/streams/" + id) if (res.length() == 0) getFromYTDL(url)[0]!! val item = createVideoFromPipedJSON(res, id) item!!.formats @@ -719,7 +719,7 @@ class InfoUtil(private val context: Context) { }else{ urls.forEach { val id = getIDFromYoutubeURL(it) - val res = genericRequest(pipedURL + "streams/" + id) + val res = genericRequest(pipedURL + "/streams/" + id) val vid = createVideoFromPipedJSON(res, id) 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( var nextPageToken: String, var videos: ArrayList @@ -1036,7 +1038,7 @@ class InfoUtil(private val context: Context) { companion object { private const val TAG = "API MANAGER" 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 = "" } } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt b/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt index 1bd303a9..32606fa7 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt @@ -1,8 +1,6 @@ package com.deniscerri.ytdlnis.work -import android.app.PendingIntent import android.content.Context -import android.content.Intent import android.os.Handler import android.os.Looper import android.util.Log @@ -14,7 +12,6 @@ import androidx.work.ForegroundInfo import androidx.work.Worker import androidx.work.WorkerParameters import androidx.work.workDataOf -import com.deniscerri.ytdlnis.MainActivity import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.database.DBManager import com.deniscerri.ytdlnis.database.dao.DownloadDao @@ -61,6 +58,8 @@ class DownloadWorker( return Result.failure() } + if (downloadItem.status != DownloadRepository.Status.Queued.toString()) return Result.failure() + Log.e(TAG, downloadItem.toString()) runBlocking{ @@ -208,6 +207,8 @@ class DownloadWorker( 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()){ request.addOption("--split-chapters") request.addOption("-P", tempFileDir.absolutePath) diff --git a/app/src/main/res/drawable/baseline_audio_file_24.xml b/app/src/main/res/drawable/baseline_audio_file_24.xml index 076e65b7..0fba753b 100644 --- a/app/src/main/res/drawable/baseline_audio_file_24.xml +++ b/app/src/main/res/drawable/baseline_audio_file_24.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/baseline_insert_drive_file_24.xml b/app/src/main/res/drawable/baseline_insert_drive_file_24.xml index 7b6a50fc..cfb8c494 100644 --- a/app/src/main/res/drawable/baseline_insert_drive_file_24.xml +++ b/app/src/main/res/drawable/baseline_insert_drive_file_24.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/baseline_video_file_24.xml b/app/src/main/res/drawable/baseline_video_file_24.xml index 2904fb5a..5e48425f 100644 --- a/app/src/main/res/drawable/baseline_video_file_24.xml +++ b/app/src/main/res/drawable/baseline_video_file_24.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/layout-sw600dp/activity_main.xml b/app/src/main/res/layout-sw600dp/activity_main.xml index db405e44..7e5aabb6 100644 --- a/app/src/main/res/layout-sw600dp/activity_main.xml +++ b/app/src/main/res/layout-sw600dp/activity_main.xml @@ -47,7 +47,6 @@ android:id="@+id/bottomNavigationView" android:layout_width="wrap_content" android:layout_height="match_parent" - app:labelVisibilityMode="unlabeled" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" diff --git a/app/src/main/res/layout/download_multiple_bottom_sheet.xml b/app/src/main/res/layout/download_multiple_bottom_sheet.xml index 396aeeee..782a6280 100644 --- a/app/src/main/res/layout/download_multiple_bottom_sheet.xml +++ b/app/src/main/res/layout/download_multiple_bottom_sheet.xml @@ -22,12 +22,6 @@ android:layout_gravity="bottom" app:menu="@menu/download_multiple_menu" /> - - diff --git a/app/src/main/res/layout/fragment_download_queue_main_screen.xml b/app/src/main/res/layout/fragment_download_queue_main_screen.xml index 85349e0f..60e27deb 100644 --- a/app/src/main/res/layout/fragment_download_queue_main_screen.xml +++ b/app/src/main/res/layout/fragment_download_queue_main_screen.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context="com.deniscerri.ytdlnis.ui.more.TerminalActivity"> + android:layout_height="match_parent"> - - - - - - - - - - - + app:tabMode="scrollable" /> - + xmlns:android="http://schemas.android.com/apk/res/android"> - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/menu/download_multiple_menu.xml b/app/src/main/res/menu/download_multiple_menu.xml index c059200d..ed04ade4 100644 --- a/app/src/main/res/menu/download_multiple_menu.xml +++ b/app/src/main/res/menu/download_multiple_menu.xml @@ -8,25 +8,25 @@ android:id="@+id/preferred_download_type" android:title="@string/preferred_download_type" android:icon="@drawable/baseline_insert_drive_file_24" - app:showAsAction="ifRoom"/> + app:showAsAction="always"/> + android:icon="@drawable/ic_format" + app:showAsAction="always"/> + app:showAsAction="always"/> + android:icon="@drawable/baseline_folder_24" + app:showAsAction="always"/> diff --git a/app/src/main/res/navigation/dqueue_nav.xml b/app/src/main/res/navigation/dqueue_nav.xml new file mode 100644 index 00000000..f6920a28 --- /dev/null +++ b/app/src/main/res/navigation/dqueue_nav.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 50419980..65622c5d 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -93,6 +93,7 @@ ar az bn + bs de es fa @@ -173,12 +174,14 @@ @string/home @string/downloads + @string/download_queue @string/more Home History + Queue More diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dca54a8a..720602bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -276,4 +276,6 @@ Move Temporary Files Transfer cached files to the downloads folder All items must either be audio or video to use this option + Piped Instance + Write a PIPED API Server, the app can use for youtube queries and formats \ No newline at end of file diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml index 5f528366..84e8ccd5 100644 --- a/app/src/main/res/xml/locales_config.xml +++ b/app/src/main/res/xml/locales_config.xml @@ -4,6 +4,7 @@ + diff --git a/app/src/main/res/xml/updating_preferences.xml b/app/src/main/res/xml/updating_preferences.xml index 7f7633fa..60c475ff 100644 --- a/app/src/main/res/xml/updating_preferences.xml +++ b/app/src/main/res/xml/updating_preferences.xml @@ -38,6 +38,12 @@ app:useSimpleSummaryProvider="true" app:title="@string/format_source" /> + +