This commit is contained in:
Denis Çerri 2023-03-05 22:59:19 +01:00
parent 2c026f039e
commit 220935dd57
No known key found for this signature in database
GPG key ID: 95C43D517D830350
8 changed files with 93 additions and 77 deletions

View file

@ -106,9 +106,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener
}
val fileSize = card.findViewById<TextView>(R.id.file_size)
Log.e("aa", item.format.filesize.toString())
val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize)
Log.e("aa", fileSizeReadable)
if (fileSizeReadable == "?") fileSize.visibility = View.GONE
else {
fileSize.text = fileSizeReadable

View file

@ -25,7 +25,7 @@ import java.util.*
class PlaylistAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter<ResultItem?, PlaylistAdapter.ViewHolder>(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) {
private val checkedItems: ArrayList<Long>
private val checkedItems: ArrayList<String>
private val onItemClickListener: OnItemClickListener
private val activity: Activity
@ -73,9 +73,9 @@ class PlaylistAdapter(onItemClickListener: OnItemClickListener, activity: Activi
// CHECKBOX ----------------------------------
val check = card.findViewById<CheckBox>(R.id.checkBox)
check.isChecked = checkedItems.contains(item.id)
check.isChecked = checkedItems.contains(item.url)
check.setOnCheckedChangeListener { buttonView, isChecked ->
checkCard(isChecked, item.id)
checkCard(isChecked, item.url)
}
card.setOnClickListener {
@ -83,25 +83,25 @@ class PlaylistAdapter(onItemClickListener: OnItemClickListener, activity: Activi
}
}
private fun checkCard(isChecked: Boolean, itemID: Long) {
private fun checkCard(isChecked: Boolean, itemURL: String) {
if (isChecked) {
checkedItems.add(itemID)
checkedItems.add(itemURL)
} else {
checkedItems.remove(itemID)
checkedItems.remove(itemURL)
}
onItemClickListener.onCardSelect(itemID, isChecked, checkedItems)
onItemClickListener.onCardSelect(itemURL, isChecked, checkedItems)
}
interface OnItemClickListener {
fun onCardSelect(itemID: Long, isChecked: Boolean, checkedItems: List<Long>)
fun onCardSelect(itemURL: String, isChecked: Boolean, checkedItems: List<String>)
}
@SuppressLint("NotifyDataSetChanged")
fun clearCheckeditems() {
for (i in 0 until itemCount){
val item = getItem(i)
if (checkedItems.find { it == item?.id } != null){
checkedItems.remove(item?.id)
if (checkedItems.find { it == item?.url } != null){
checkedItems.remove(item?.url)
notifyItemChanged(i)
}
}
@ -112,12 +112,12 @@ class PlaylistAdapter(onItemClickListener: OnItemClickListener, activity: Activi
checkedItems.clear()
for (i in 0 until itemCount){
val item = getItem(i)
checkedItems.add(item!!.id)
checkedItems.add(item!!.url)
notifyItemChanged(i)
}
}
fun getCheckedItems() : List<Long>{
fun getCheckedItems() : List<String>{
return checkedItems
}

View file

@ -12,6 +12,7 @@ import com.deniscerri.ytdlnis.database.repository.ResultRepository
import com.deniscerri.ytdlnis.database.repository.SearchHistoryRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.regex.Pattern
class ResultViewModel(application: Application) : AndroidViewModel(application) {
@ -51,39 +52,47 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
loadingItems.postValue(false)
}
fun parseQuery(inputQuery: String, resetResults: Boolean) = viewModelScope.launch(Dispatchers.IO){
suspend fun parseQuery(inputQuery: String, resetResults: Boolean) : ArrayList<ResultItem?> {
if (resetResults) loadingItems.postValue(true)
val type = getQueryType(inputQuery)
var res = arrayListOf<ResultItem?>()
return withContext(Dispatchers.IO){
try {
when (type) {
"Search" -> {
res = repository.search(inputQuery, resetResults)
}
"Video" -> {
res = repository.getOne(inputQuery, resetResults)
}
"Playlist" -> {
res = repository.getPlaylist(inputQuery, resetResults)
}
"Default" -> {
res = repository.getDefault(inputQuery, resetResults)
}
}
} catch (e: Exception) {
Log.e(tag, e.toString())
}
loadingItems.postValue(false)
res
}
}
fun getQueryType(inputQuery: String) : String {
var type = "Search"
val p = Pattern.compile("^(https?)://(www.)?youtu(.be)?")
val m = p.matcher(inputQuery!!)
val m = p.matcher(inputQuery)
if (m.find()) {
type = "Video"
if (inputQuery!!.contains("playlist?list=")) {
if (inputQuery.contains("playlist?list=")) {
type = "Playlist"
}
} else if (inputQuery!!.contains("http")) {
} else if (inputQuery.contains("http")) {
type = "Default"
}
try {
when (type) {
"Search" -> {
repository.search(inputQuery, resetResults)
}
"Video" -> {
repository.getOne(inputQuery, resetResults)
}
"Playlist" -> {
repository.getPlaylist(inputQuery, resetResults)
}
"Default" -> {
repository.getDefault(inputQuery, resetResults)
}
}
} catch (e: Exception) {
Log.e(tag, e.toString())
}
loadingItems.postValue(false)
return type
}
fun insert(items: ArrayList<ResultItem?>) = viewModelScope.launch(Dispatchers.IO){

View file

@ -20,6 +20,7 @@ import android.view.Window
import android.view.WindowManager
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.view.ViewCompat
@ -42,6 +43,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import kotlin.system.exitProcess
@ -110,19 +112,20 @@ class ShareActivity : AppCompatActivity() {
showDownloadSheet(result)
}catch (e: Exception){
resultViewModel.deleteAll()
CoroutineScope(Dispatchers.IO).launch {
resultViewModel.parseQuery(inputQuery!!, true)
}
resultViewModel.items.observe(this) {
if (it.isNotEmpty() && supportFragmentManager.findFragmentByTag("downloadSingleSheet") == null){
if(resultViewModel.itemCount.value!! == it.size){
loadingBottomSheet.cancel()
if (it.size == 1){
showDownloadSheet(it[0])
}else{
showSelectPlaylistItems(it)
}
lifecycleScope.launch {
var res: ArrayList<ResultItem?>
withContext(Dispatchers.IO){
res = resultViewModel.parseQuery(inputQuery!!, true)
}
if (res.isEmpty()) {
Toast.makeText(this@ShareActivity, "No Results Found!", Toast.LENGTH_SHORT).show()
exit()
}else{
loadingBottomSheet.cancel()
if (res.size == 1){
showDownloadSheet(res[0]!!)
}else{
showSelectPlaylistItems(res.toList())
}
}
}
@ -141,7 +144,7 @@ class ShareActivity : AppCompatActivity() {
}
}
private fun showSelectPlaylistItems(it: List<ResultItem>){
private fun showSelectPlaylistItems(it: List<ResultItem?>){
if (sharedPreferences.getBoolean("download_card", true)){
val bottomSheet = SelectPlaylistItemsBottomSheetDialog(it, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
bottomSheet.show(supportFragmentManager, "downloadPlaylistSheet")
@ -149,7 +152,7 @@ class ShareActivity : AppCompatActivity() {
lifecycleScope.launch(Dispatchers.IO){
val downloadItems = mutableListOf<DownloadItem>()
it.forEach { res ->
val i = downloadViewModel.createDownloadItemFromResult(res, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
val i = downloadViewModel.createDownloadItemFromResult(res!!, DownloadViewModel.Type.valueOf(sharedPreferences.getString("preferred_download_type", "video")!!))
i.format = downloadViewModel.getLatestCommandTemplateAsFormat()
downloadItems.add(i)
}

View file

@ -21,6 +21,7 @@ import androidx.appcompat.widget.SearchView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -43,6 +44,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*
@ -134,8 +138,8 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
resultViewModel.items.observe(viewLifecycleOwner) {
homeAdapter!!.submitList(it)
resultsList = it
if(resultViewModel.itemCount.value!! > 1 || resultViewModel.itemCount.value!! == -1){
if (it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist)){
if(resultViewModel.itemCount.value!! > 1 || resultViewModel.itemCount.value!! == -1){
if (it[0].playlistTitle.isNotEmpty() && it[0].playlistTitle != getString(R.string.trendingPlaylist) && it.size > 1){
downloadAllFabCoordinator!!.visibility = VISIBLE
}else{
downloadAllFabCoordinator!!.visibility = GONE
@ -181,23 +185,24 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
resultViewModel.deleteAll()
inputQueriesLength = inputQueries!!.size
Handler(Looper.getMainLooper()).post { scrollToTop() }
val thread = Thread {
resultViewModel.parseQuery(inputQueries!!.pop()!!, true)
lifecycleScope.launch(){
withContext(Dispatchers.IO){
resultViewModel.parseQuery(inputQueries!!.pop()!!, true)
}
while (!inputQueries!!.isEmpty()) {
inputQuery = inputQueries!!.pop()
resultViewModel.parseQuery(inputQuery!!, false)
withContext(Dispatchers.IO){
resultViewModel.parseQuery(inputQuery!!, false)
}
}
try {
Handler(Looper.getMainLooper()).post {
// DOWNLOAD ALL BUTTON
if (resultsList!!.size > 1 || inputQueriesLength > 1) {
downloadAllFabCoordinator!!.visibility = VISIBLE
}
if (resultsList!!.size > 1 || inputQueriesLength > 1) {
downloadAllFabCoordinator!!.visibility = VISIBLE
}
} catch (ignored: Exception) {
}
}
thread.start()
} else {
resultViewModel.checkTrending()
}
@ -255,10 +260,9 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
resultViewModel.addSearchQueryToHistory(inputQuery!!)
}
resultViewModel.deleteAll()
val thread = Thread {
lifecycleScope.launch(Dispatchers.IO){
resultViewModel.parseQuery(inputQuery!!, true)
}
thread.start()
return true
}

View file

@ -200,6 +200,7 @@ class DownloadMultipleBottomSheetDialog(private val items: MutableList<DownloadI
val resultItem = withContext(Dispatchers.IO){
resultViewModel.getItemByURL(downloadItem!!.url)
}
Log.e("aa", resultItem.toString())
val bottomSheet = ConfigureDownloadBottomSheetDialog(resultItem, downloadItem!!, this@DownloadMultipleBottomSheetDialog)
bottomSheet.show(parentFragmentManager, "configureDownloadSingleSheet")
}

View file

@ -35,7 +35,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*
class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem>, private val type: DownloadViewModel.Type) : BottomSheetDialogFragment(), PlaylistAdapter.OnItemClickListener {
class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>, private val type: DownloadViewModel.Type) : BottomSheetDialogFragment(), PlaylistAdapter.OnItemClickListener {
private lateinit var downloadViewModel: DownloadViewModel
private lateinit var resultViewModel: ResultViewModel
private lateinit var listAdapter : PlaylistAdapter
@ -85,10 +85,9 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem>,
val checkAll = view.findViewById<Button>(R.id.check_all)
checkAll!!.setOnClickListener {
if (listAdapter.getCheckedItems().isEmpty()){
if (listAdapter.getCheckedItems().size != items.size){
listAdapter.checkAll()
selectedText.text = resources.getString(R.string.all_items_selected)
}else{
listAdapter.clearCheckeditems()
selectedText.text = "0 ${resources.getString(R.string.selected)}"
@ -100,17 +99,19 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem>,
ok!!.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO){
val checkedItems = listAdapter.getCheckedItems()
val checkedResultItems = items.filter { checkedItems.contains(it.id) }
val checkedResultItems = items.filter { item -> checkedItems.contains(item!!.url) }
val downloadItems = mutableListOf<DownloadItem>()
checkedResultItems.forEach {c ->
checkedResultItems.forEach { c ->
c!!.id = 0
val i = downloadViewModel.createDownloadItemFromResult(c,type)
if (type == DownloadViewModel.Type.command){
i.format = downloadViewModel.getLatestCommandTemplateAsFormat()
}
downloadItems.add(i)
}
if (downloadItems.size == 1){
val resultItem = resultViewModel.getItemByURL(items[0].url)
val resultItem = resultViewModel.getItemByURL(items[0]!!.url)
val bottomSheet = DownloadBottomSheetDialog(resultItem, type)
bottomSheet.show(parentFragmentManager, "downloadSingleSheet")
}else{
@ -118,8 +119,7 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem>,
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
}
dismiss()
resultViewModel.deleteAll()
resultViewModel.insert(ArrayList(checkedResultItems))
}
}
}
@ -142,7 +142,7 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem>,
}
override fun onCardSelect(itemID: Long, isChecked: Boolean, checkedItems: List<Long>) {
override fun onCardSelect(itemURL: String, isChecked: Boolean, checkedItems: List<String>) {
if (checkedItems.size == items.size){
selectedText.text = resources.getString(R.string.all_items_selected)
}else{

View file

@ -537,10 +537,11 @@ class InfoUtil(context: Context) {
if (formatsInJSON != null) {
for (f in 0 until formatsInJSON.length()){
val format = formatsInJSON.getJSONObject(f).toString()
formats.add(Gson().fromJson(format, Format::class.java))
val formatProper = Gson().fromJson(format, Format::class.java)
if (formatProper.filesize > 0) formats.add(formatProper)
}
}
Log.e(TAG, formats.toString())
Log.e("aa", formats.toString())
items.add(ResultItem(0,
url,
title,