diff --git a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt index 12a06bdc..e89b4014 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt @@ -25,16 +25,14 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController import androidx.navigation.ui.setupWithNavController -import androidx.test.InstrumentationRegistry import com.deniscerri.ytdlnis.database.viewmodel.CookieViewModel import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel import com.deniscerri.ytdlnis.ui.HomeFragment import com.deniscerri.ytdlnis.ui.downloads.DownloadQueueActivity import com.deniscerri.ytdlnis.ui.more.settings.SettingsActivity -import com.deniscerri.ytdlnis.util.InfoUtil import com.deniscerri.ytdlnis.util.UpdateUtil -import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.navigation.NavigationBarView import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.BufferedReader @@ -51,7 +49,7 @@ class MainActivity : AppCompatActivity() { private lateinit var preferences: SharedPreferences private lateinit var resultViewModel: ResultViewModel private lateinit var cookieViewModel: CookieViewModel - private lateinit var bottomNav: BottomNavigationView + private lateinit var navigationView: NavigationBarView private lateinit var navHostFragment : NavHostFragment @@ -73,20 +71,20 @@ class MainActivity : AppCompatActivity() { navHostFragment = supportFragmentManager.findFragmentById(R.id.frame_layout) as NavHostFragment val navController = navHostFragment.findNavController() - bottomNav = findViewById(R.id.bottomNavigationView) + navigationView = findViewById(R.id.bottomNavigationView) window.decorView.setOnApplyWindowInsetsListener { view: View, windowInsets: WindowInsets? -> val windowInsetsCompat = WindowInsetsCompat.toWindowInsetsCompat( windowInsets!!, view ) val isImeVisible = windowInsetsCompat.isVisible(WindowInsetsCompat.Type.ime()) - bottomNav.visibility = + navigationView.visibility = if (isImeVisible) View.GONE else View.VISIBLE view.onApplyWindowInsets(windowInsets) } - bottomNav.setupWithNavController(navController) - bottomNav.setOnItemReselectedListener { + navigationView.setupWithNavController(navController) + navigationView.setOnItemReselectedListener { when (it.itemId) { R.id.homeFragment -> { (navHostFragment.childFragmentManager.primaryNavigationFragment!! as HomeFragment).scrollToTop() @@ -119,19 +117,19 @@ class MainActivity : AppCompatActivity() { } fun hideNav() { - bottomNav.visibility = View.GONE + navigationView.visibility = View.GONE } fun showNav() { - bottomNav.visibility = View.VISIBLE + navigationView.visibility = View.VISIBLE } fun disableBottomNavigation(){ - bottomNav.menu.forEach { it.isEnabled = false } + navigationView.menu.forEach { it.isEnabled = false } } fun enableBottomNavigation(){ - bottomNav.menu.forEach { it.isEnabled = true } + navigationView.menu.forEach { it.isEnabled = true } } override fun onResume() { 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 e2e16efe..416dd7f5 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 @@ -13,6 +13,9 @@ interface DownloadDao { @Query("SELECT * FROM downloads WHERE status='Active'") fun getActiveDownloads() : LiveData> + @Query("SELECT * FROM downloads WHERE status='Active'") + fun getActiveDownloadsList() : List + @Query("SELECT * FROM downloads WHERE status='Queued' ORDER BY downloadStartTime, id") fun getQueuedDownloads() : LiveData> @@ -46,8 +49,8 @@ interface DownloadDao { @Query("DELETE FROM downloads WHERE status='Error'") suspend fun deleteErrored() - @Query("DELETE FROM downloads WHERE status='Queued'") - suspend fun deleteQueued() + @Query("UPDATE downloads SET status='Cancelled' WHERE status='Queued'") + suspend fun cancelQueued() @Query("DELETE FROM downloads WHERE status='Processing' AND id=:id") suspend fun deleteSingleProcessing(id: Long) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt index 15e96788..6603a308 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/DownloadRepository.kt @@ -44,6 +44,10 @@ class DownloadRepository(private val downloadDao: DownloadDao) { return downloadDao.getDownloadById(id) } + fun getActiveDownloads() : List { + return downloadDao.getActiveDownloadsList() + } + suspend fun deleteCancelled(){ downloadDao.deleteCancelled() } @@ -52,8 +56,8 @@ class DownloadRepository(private val downloadDao: DownloadDao) { downloadDao.deleteErrored() } - suspend fun deleteQueued(){ - downloadDao.deleteQueued() + suspend fun cancelQueued(){ + downloadDao.cancelQueued() } fun checkIfPresentForProcessing(item: ResultItem): DownloadItem{ 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 ddde87e6..718bde8a 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 @@ -22,6 +22,7 @@ import com.deniscerri.ytdlnis.work.DownloadWorker import com.google.gson.Gson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import java.util.concurrent.TimeUnit @@ -261,29 +262,6 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel return list } - fun putDownloadsForProcessing(items: List, downloadItems: List) : LiveData> { - val result = MutableLiveData>() - viewModelScope.launch(Dispatchers.IO){ - val list : MutableList = mutableListOf() - items.forEachIndexed { i, it -> - val tmpDownloadItem = downloadItems[i] - try { - val item = repository.checkIfPresentForProcessing(it!!) - tmpDownloadItem.id = item.id - tmpDownloadItem.status = DownloadRepository.Status.Processing.toString() - repository.update(tmpDownloadItem) - list.add(tmpDownloadItem.id) - }catch (e: Exception){ - val id = repository.insert(tmpDownloadItem) - list.add(id) - } - - } - result.postValue(list) - } - return result - } - fun deleteCancelled() = viewModelScope.launch(Dispatchers.IO) { repository.deleteCancelled() } @@ -292,15 +270,19 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel repository.deleteErrored() } - fun deleteQueued() = viewModelScope.launch(Dispatchers.IO) { - repository.deleteQueued() + fun cancelQueued() = viewModelScope.launch(Dispatchers.IO) { + repository.cancelQueued() } - fun cloneFormat(item: Format) : Format { + private fun cloneFormat(item: Format) : Format { val string = Gson().toJson(item, Format::class.java) return Gson().fromJson(string, Format::class.java) } + fun getActiveDownloads() : List{ + return repository.getActiveDownloads() + } + suspend fun queueDownloads(items: List) { val context = getApplication().applicationContext val allowMeteredNetworks = sharedPreferences.getBoolean("metered_networks", true) 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 a193c54b..98b5d811 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt @@ -138,10 +138,8 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi requireActivity() ) recyclerView = view.findViewById(R.id.recyclerViewHome) - if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE || resources.getBoolean(R.bool.isTablet)){ + if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && ! resources.getBoolean(R.bool.isTablet)){ recyclerView?.layoutManager = GridLayoutManager(context, 2) - }else{ - recyclerView?.layoutManager = LinearLayoutManager(context) } recyclerView?.adapter = homeAdapter @@ -478,8 +476,10 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi if (sharedPreferences!!.getBoolean("download_card", true)) { showSingleDownloadSheet(item!!, type!!) } else { - lifecycleScope.launch(Dispatchers.IO){ - val downloadItem = downloadViewModel.createDownloadItemFromResult(item!!, type!!) + lifecycleScope.launch{ + val downloadItem = withContext(Dispatchers.IO){ + downloadViewModel.createDownloadItemFromResult(item!!, type!!) + } downloadViewModel.queueDownloads(listOf(downloadItem)) } } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt index 1a293252..91d6f219 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadMultipleBottomSheetDialog.kt @@ -134,9 +134,13 @@ class DownloadMultipleBottomSheetDialog(private var results: List, val formatListener = object : OnFormatClickListener { override fun onFormatClick(allFormats: List>, selectedFormats: List) { + val formatCollection = mutableListOf>() + allFormats.forEach {f -> + formatCollection.add(f.mapTo(mutableListOf()) {it.copy()}) + } items.forEachIndexed { index, it -> it.allFormats.clear() - it.allFormats.addAll(allFormats[index]) + it.allFormats.addAll(formatCollection[index]) it.format = selectedFormats[index] } listAdapter.submitList(items.toList()) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/FormatSelectionBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/FormatSelectionBottomSheetDialog.kt index 1a03f5b3..5f04c772 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/FormatSelectionBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/FormatSelectionBottomSheetDialog.kt @@ -70,25 +70,33 @@ class FormatSelectionBottomSheetDialog(private val items: List, p if (items.size > 1){ val hasGenericFormats = when(items.first()!!.type){ - Type.audio -> formats.flatten().size == resources.getStringArray(R.array.audio_formats).size - else -> formats.flatten().size == resources.getStringArray(R.array.video_formats).size + Type.audio -> formats.first().size == resources.getStringArray(R.array.audio_formats).size + else -> formats.first().size == resources.getStringArray(R.array.video_formats).size } if (!hasGenericFormats){ formatCollection.addAll(formats) val flattenFormats = formats.flatten() val commonFormats = flattenFormats.groupingBy { it.format_id }.eachCount().filter { it.value == items.size }.mapValues { flattenFormats.first { f -> f.format_id == it.key } }.map { it.value } - commonFormats.forEach { + chosenFormats = commonFormats.mapTo(mutableListOf()) {it.copy()} + chosenFormats = when(items.first()?.type){ + Type.audio -> chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) } + else -> chosenFormats.filter { !it.format_note.contains("audio", ignoreCase = true) } + } + chosenFormats.forEach { it.filesize = flattenFormats.filter { f -> f.format_id == it.format_id } .sumOf { itt -> itt.filesize } } - chosenFormats = commonFormats }else{ chosenFormats = formats.flatten() } addFormatsToView(linearLayout) }else{ chosenFormats = formats.flatten() + chosenFormats = when(items.first()?.type){ + Type.audio -> chosenFormats.filter { it.format_note.contains("audio", ignoreCase = true) } + else -> chosenFormats.filter { !it.format_note.contains("audio", ignoreCase = true) } + } addFormatsToView(linearLayout) } @@ -118,6 +126,7 @@ class FormatSelectionBottomSheetDialog(private val items: List, p //playlist format filtering }else{ var progress = "0/${items.size}" + formatCollection.clear() refreshBtn.text = progress withContext(Dispatchers.IO){ infoUtil.getFormatsMultiple(items.map { it!!.url }) { @@ -167,7 +176,6 @@ class FormatSelectionBottomSheetDialog(private val items: List, p } private fun addFormatsToView(linearLayout: LinearLayout){ linearLayout.removeAllViews() - Log.e("aa", chosenFormats.toString()) for (i in chosenFormats.lastIndex downTo 0){ val format = chosenFormats[i] val formatItem = LayoutInflater.from(context).inflate(R.layout.format_item, null) 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 bedd6f03..31c54bc2 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 @@ -4,6 +4,7 @@ import android.app.Activity import android.content.Intent import android.content.res.Configuration import android.os.Bundle +import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View import android.view.View.OnClickListener @@ -65,12 +66,11 @@ class ActiveDownloadsFragment() : Fragment(), ActiveDownloadAdapter.OnItemClickL activeRecyclerView = view.findViewById(R.id.download_recyclerview) activeRecyclerView.adapter = activeDownloads - val landScapeOrTablet = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE || resources.getBoolean(R.bool.isTablet) - if (landScapeOrTablet){ + val landScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && ! resources.getBoolean(R.bool.isTablet) + if (landScape){ activeRecyclerView.layoutManager = GridLayoutManager(context, 2) - }else{ - activeRecyclerView.layoutManager = LinearLayoutManager(context) } + if (resources.getBoolean(R.bool.isTablet)) activeRecyclerView.layoutManager = GridLayoutManager(context, 3) downloadViewModel.activeDownloads.observe(viewLifecycleOwner) { activeDownloads.submitList(it) 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 00b15f43..d50297e2 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 @@ -4,6 +4,7 @@ import android.app.Activity import android.content.DialogInterface import android.content.res.Configuration import android.os.Bundle +import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -69,12 +70,11 @@ class CancelledDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClic cancelledRecyclerView = view.findViewById(R.id.download_recyclerview) cancelledRecyclerView.adapter = cancelledDownloads - val landScapeOrTablet = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE || resources.getBoolean(R.bool.isTablet) - if (landScapeOrTablet){ + val landScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && ! resources.getBoolean(R.bool.isTablet) + if (landScape){ cancelledRecyclerView.layoutManager = GridLayoutManager(context, 2) - }else{ - cancelledRecyclerView.layoutManager = LinearLayoutManager(context) } + if (resources.getBoolean(R.bool.isTablet)) cancelledRecyclerView.layoutManager = GridLayoutManager(context, 3) downloadViewModel.cancelledDownloads.observe(viewLifecycleOwner) { items = it diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueActivity.kt index c456a614..6198b785 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloads/DownloadQueueActivity.kt @@ -8,14 +8,21 @@ import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import androidx.work.WorkManager +import androidx.work.await import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel +import com.deniscerri.ytdlnis.util.NotificationUtil import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.tabs.TabLayout +import com.yausername.youtubedl_android.YoutubeDL +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class DownloadQueueActivity : AppCompatActivity(){ @@ -85,7 +92,7 @@ class DownloadQueueActivity : AppCompatActivity(){ R.id.clear_queue -> { showDeleteDialog() { cancelAllDownloads() - downloadViewModel.deleteQueued() + downloadViewModel.cancelQueued() } } R.id.clear_cancelled -> { @@ -118,7 +125,20 @@ class DownloadQueueActivity : AppCompatActivity(){ } private fun cancelAllDownloads() { - workManager.cancelAllWork() + lifecycleScope.launch { + val notificationUtil = NotificationUtil(this@DownloadQueueActivity) + val activeDownloads = withContext(Dispatchers.IO){ + downloadViewModel.getActiveDownloads() + } + val workManager = WorkManager.getInstance(this@DownloadQueueActivity) + activeDownloads.forEach { + val id = it.id.toInt() + YoutubeDL.getInstance().destroyProcessById(id.toString()) + workManager.cancelUniqueWork(id.toString()) + notificationUtil.cancelDownloadNotification(id) + } + workManager.cancelAllWorkByTag("download") + } } 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 da36e7cb..603f0a5c 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 @@ -5,6 +5,7 @@ import android.content.DialogInterface import android.content.Intent import android.content.res.Configuration import android.os.Bundle +import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -71,12 +72,11 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL erroredRecyclerView = view.findViewById(R.id.download_recyclerview) erroredRecyclerView.adapter = erroredDownloads - val landScapeOrTablet = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE || resources.getBoolean(R.bool.isTablet) - if (landScapeOrTablet){ + val landScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && ! resources.getBoolean(R.bool.isTablet) + if (landScape){ erroredRecyclerView.layoutManager = GridLayoutManager(context, 2) - }else{ - erroredRecyclerView.layoutManager = LinearLayoutManager(context) } + if (resources.getBoolean(R.bool.isTablet)) erroredRecyclerView.layoutManager = GridLayoutManager(context, 3) downloadViewModel.erroredDownloads.observe(viewLifecycleOwner) { items = it 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 0fcc3bfc..8dcc831b 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 @@ -9,6 +9,7 @@ import android.os.Bundle import android.os.Handler import android.os.Looper import android.text.InputType +import android.util.DisplayMetrics import android.util.Log import android.view.* import android.view.View.GONE @@ -112,11 +113,11 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{ requireActivity() ) recyclerView = view.findViewById(R.id.recyclerviewhistorys) - if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE || resources.getBoolean(R.bool.isTablet)){ + if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && ! resources.getBoolean(R.bool.isTablet)){ recyclerView?.layoutManager = GridLayoutManager(context, 2) - }else{ - recyclerView?.layoutManager = LinearLayoutManager(context) } + if (resources.getBoolean(R.bool.isTablet)) recyclerView?.layoutManager = GridLayoutManager(context, 3) + recyclerView?.adapter = historyAdapter noResults?.visibility = GONE @@ -483,7 +484,9 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{ else redownload.visibility = GONE bottomSheet!!.show() - bottomSheet!!.behavior.peekHeight = 512 + val displayMetrics = DisplayMetrics() + requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics) + bottomSheet!!.behavior.peekHeight = displayMetrics.heightPixels bottomSheet!!.window!!.setLayout( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT 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 b721eb84..c321b1ff 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 @@ -4,6 +4,7 @@ import android.app.Activity import android.content.res.Configuration import android.os.Bundle import android.text.format.DateFormat +import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -79,12 +80,11 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi queuedRecyclerView = view.findViewById(R.id.download_recyclerview) queuedRecyclerView.adapter = queuedDownloads - val landScapeOrTablet = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE || resources.getBoolean(R.bool.isTablet) - if (landScapeOrTablet){ + val landScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && ! resources.getBoolean(R.bool.isTablet) + if (landScape){ queuedRecyclerView.layoutManager = GridLayoutManager(context, 2) - }else{ - queuedRecyclerView.layoutManager = LinearLayoutManager(context) } + if (resources.getBoolean(R.bool.isTablet)) queuedRecyclerView.layoutManager = GridLayoutManager(context, 3) downloadViewModel.queuedDownloads.observe(viewLifecycleOwner) { items = it diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/TerminalActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/TerminalActivity.kt index 0231ddc8..226b4fcb 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/TerminalActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/TerminalActivity.kt @@ -18,6 +18,7 @@ import android.widget.EditText import android.widget.LinearLayout import android.widget.ScrollView import android.widget.TextView +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.lifecycle.ViewModelProvider @@ -58,6 +59,7 @@ class TerminalActivity : AppCompatActivity() { private lateinit var observer: FileObserver private lateinit var imm : InputMethodManager private lateinit var uiUtil: UiUtil + private lateinit var fileUtil: FileUtil var context: Context? = null public override fun onCreate(savedInstanceState: Bundle?) { @@ -68,7 +70,8 @@ class TerminalActivity : AppCompatActivity() { downloadFile = File(cacheDir.absolutePath + "/$downloadID.txt") if (! downloadFile.exists()) downloadFile.createNewFile() imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - uiUtil = UiUtil(FileUtil()) + fileUtil = FileUtil() + uiUtil = UiUtil(fileUtil) context = baseContext scrollView = findViewById(R.id.custom_command_scrollview) @@ -105,7 +108,13 @@ class TerminalActivity : AppCompatActivity() { } } R.id.shortcuts -> showShortcuts() - else -> {} + R.id.folder -> { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) + commandPathResultLauncher.launch(intent) + } } true } @@ -253,6 +262,21 @@ class TerminalActivity : AppCompatActivity() { } } + private var commandPathResultLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + result.data?.data?.let { + contentResolver?.takePersistableUriPermission( + it, + Intent.FLAG_GRANT_READ_URI_PERMISSION or + Intent.FLAG_GRANT_WRITE_URI_PERMISSION + ) + } + input!!.text.insert(input!!.selectionStart, fileUtil.formatPath(result.data?.data.toString())) + } + } + private fun startDownload(command: String?) { val cmd = if (command!!.contains("yt-dlp")) command.replace("yt-dlp", "") else command 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 ec9887e2..4c7062f8 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/util/InfoUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/util/InfoUtil.kt @@ -614,17 +614,19 @@ class InfoUtil(private val context: Context) { var playlistTitle: String? = "" if (jsonObject.has("playlist_title")) playlistTitle = jsonObject.getString("playlist_title") if(playlistTitle.equals(query)) playlistTitle = "" - val formatsInJSON = if (jsonObject.has("formats") && jsonObject.get("formats") is JsonArray) jsonObject.getJSONArray("formats") else null + val formatsInJSON = if (jsonObject.has("formats") && jsonObject.get("formats") is JSONArray) jsonObject.getJSONArray("formats") else null val formats : ArrayList = ArrayList() if (formatsInJSON != null) { for (f in 0 until formatsInJSON.length()){ val format = formatsInJSON.getJSONObject(f) val formatProper = Gson().fromJson(format.toString(), Format::class.java) if (formatProper.filesize > 0){ - if ( !formatProper.format_note.contains("audio only", true)) { - formatProper.format_note = format.getString("format_note") - }else{ - formatProper.format_note = "${format.getString("format_note")} audio" + if (format.has("format_note")){ + if ( !formatProper.format_note.contains("audio only", true)) { + formatProper.format_note = format.getString("format_note") + }else{ + formatProper.format_note = "${format.getString("format_note")} audio" + } } formatProper.container = format.getString("ext") formats.add(formatProper) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/work/TerminalDownloadWorker.kt b/app/src/main/java/com/deniscerri/ytdlnis/work/TerminalDownloadWorker.kt index a243678a..7e5a4293 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/work/TerminalDownloadWorker.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/work/TerminalDownloadWorker.kt @@ -64,7 +64,7 @@ class TerminalDownloadWorker( request.addOption("--cookies", cookiesFile.absolutePath) } - request.addOption("-P", tempFileDir.absolutePath) + if (!command.contains("-P ")) request.addOption("-P", tempFileDir.absolutePath) val logDownloads = sharedPreferences.getBoolean("log_downloads", false) && !sharedPreferences.getBoolean("incognito", false) val logFolder = File(context.filesDir.absolutePath + "/logs") diff --git a/app/src/main/res/drawable/baseline_folder_24.xml b/app/src/main/res/drawable/baseline_folder_24.xml new file mode 100644 index 00000000..ba5b0f0d --- /dev/null +++ b/app/src/main/res/drawable/baseline_folder_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout-sw800dp/activity_main.xml b/app/src/main/res/layout-sw800dp/activity_main.xml new file mode 100644 index 00000000..8e74f56b --- /dev/null +++ b/app/src/main/res/layout-sw800dp/activity_main.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw800dp/fragment_home.xml b/app/src/main/res/layout-sw800dp/fragment_home.xml new file mode 100644 index 00000000..0729b4bc --- /dev/null +++ b/app/src/main/res/layout-sw800dp/fragment_home.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/active_download_card.xml b/app/src/main/res/layout/active_download_card.xml index a24d3734..1d82499b 100644 --- a/app/src/main/res/layout/active_download_card.xml +++ b/app/src/main/res/layout/active_download_card.xml @@ -50,17 +50,18 @@ @@ -68,17 +69,19 @@ + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toEndOf="@+id/download_type" + app:layout_constraintTop_toTopOf="parent"> + app:layout_constraintTop_toTopOf="parent" + app:shapeAppearance="@style/ShapeAppearanceOverlay.Chip.RoundedStart" /> + app:layout_constraintTop_toTopOf="parent" + app:shapeAppearance="@style/ShapeAppearanceOverlay.Chip.Middle" /> + app:layout_constraintTop_toTopOf="parent" + app:shapeAppearance="@style/ShapeAppearanceOverlay.Chip.RoundedEnd" /> @@ -131,13 +137,14 @@ + app:layout_constraintTop_toBottomOf="@+id/linearlayout2_horizontalscrollview"> + + - diff --git a/app/src/main/res/layout/fragment_generic_download_queue.xml b/app/src/main/res/layout/fragment_generic_download_queue.xml index fef96b31..40246d49 100644 --- a/app/src/main/res/layout/fragment_generic_download_queue.xml +++ b/app/src/main/res/layout/fragment_generic_download_queue.xml @@ -2,11 +2,13 @@ diff --git a/app/src/main/res/menu/terminal_menu.xml b/app/src/main/res/menu/terminal_menu.xml index afce27b1..a60ebcd1 100644 --- a/app/src/main/res/menu/terminal_menu.xml +++ b/app/src/main/res/menu/terminal_menu.xml @@ -11,4 +11,9 @@ android:icon="@drawable/ic_shortcut" app:showAsAction="ifRoom" android:id="@+id/shortcuts"/> + \ No newline at end of file diff --git a/app/src/main/res/values-sw720dp/attrs.xml b/app/src/main/res/values-sw800dp/attrs.xml similarity index 100% rename from app/src/main/res/values-sw720dp/attrs.xml rename to app/src/main/res/values-sw800dp/attrs.xml diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ac0b69b9..8c7cfc24 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -55,18 +55,18 @@