added select all to history & made chips in download card and active download card have same colors

This commit is contained in:
deniscerri 2023-04-17 13:31:00 +02:00
parent 0ae5d2c11f
commit 5b91db5834
No known key found for this signature in database
GPG key ID: 95C43D517D830350
13 changed files with 175 additions and 74 deletions

View file

@ -137,7 +137,6 @@ dependencies {
implementation "androidx.navigation:navigation-ui-ktx:$navVer"
implementation "androidx.navigation:navigation-dynamic-features-fragment:$navVer"
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.test.ext:junit-ktx:1.1.5'
implementation 'androidx.benchmark:benchmark-macro:1.1.1'
testImplementation "junit:junit:$junitVer"

View file

@ -115,7 +115,7 @@
</activity>
<activity
android:name=".ui.more.TerminalActivity"
android:configChanges="layoutDirection|locale"
android:configChanges="layoutDirection|locale|orientation|screenSize"
android:exported="true"
android:label="@string/terminal"
android:parentActivityName=".MainActivity"

View file

@ -25,11 +25,13 @@ 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
@ -101,6 +103,17 @@ class MainActivity : AppCompatActivity() {
}
}
cookieViewModel.updateCookiesFile()
//TODO PLAYLIST FORMAT UPDATING
// val infoUtil = InfoUtil(context)
// val list = arrayOf(
// "https://www.youtube.com/watch?v=tYcqn48SMT8",
// "https://www.youtube.com/watch?v=QNrNKPKe5oc"
// )
// infoUtil.getFormatsTest(list.toList()){
// Log.e("gff", it.toString())
// }
val intent = intent
handleIntents(intent)
}

View file

@ -19,6 +19,7 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.HistoryItem
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
@ -170,6 +171,12 @@ class HistoryAdapter(onItemClickListener: OnItemClickListener, activity: Activit
checkedItems.clear()
}
fun checkAll(items: List<HistoryItem?>?){
checkedItems.clear()
checkedItems.addAll(items!!.map { it!!.id })
notifyDataSetChanged()
}
fun invertSelected(items: List<HistoryItem?>?){
val invertedList = mutableListOf<Long>()
items?.forEach {

View file

@ -527,7 +527,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
downloadViewModel.turnResultItemsToDownloadItems(resultsList!!)
}
if (sharedPreferences!!.getBoolean("download_card", true)) {
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList.toMutableList())
val bottomSheet = DownloadMultipleBottomSheetDialog(resultsList!!, downloadList.toMutableList())
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
} else {
downloadViewModel.queueDownloads(downloadList)
@ -584,7 +584,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
actionMode?.finish()
if (sharedPreferences!!.getBoolean("download_card", true)) {
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadList.toMutableList())
val bottomSheet = DownloadMultipleBottomSheetDialog(selectedObjects!!, downloadList.toMutableList())
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
} else {
downloadViewModel.queueDownloads(downloadList)

View file

@ -21,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.adapter.ConfigureMultipleDownloadsAdapter
import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.deniscerri.ytdlnis.database.viewmodel.CommandTemplateViewModel
import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel
import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel
@ -40,7 +41,7 @@ import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.*
class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener,
class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>, private var items: MutableList<DownloadItem>) : BottomSheetDialogFragment(), ConfigureMultipleDownloadsAdapter.OnItemClickListener, View.OnClickListener,
ConfigureDownloadBottomSheetDialog.OnDownloadItemUpdateListener {
private lateinit var downloadViewModel: DownloadViewModel
private lateinit var commandTemplateViewModel: CommandTemplateViewModel
@ -131,82 +132,88 @@ class DownloadMultipleBottomSheetDialog(private var items: MutableList<DownloadI
}
bottomAppBar!!.setOnMenuItemClickListener { m: MenuItem ->
val itemId = m.itemId
if (itemId == 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)
pathResultLauncher.launch(intent)
} else if (itemId == R.id.preferred_download_type){
lifecycleScope.launch{
val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.download_type_sheet)
when (m.itemId) {
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)
pathResultLauncher.launch(intent)
}
R.id.preferred_download_type -> {
lifecycleScope.launch{
val bottomSheet = BottomSheetDialog(requireContext())
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
bottomSheet.setContentView(R.layout.download_type_sheet)
// BUTTON ----------------------------------
val audio = bottomSheet.findViewById<TextView>(R.id.audio)
val video = bottomSheet.findViewById<TextView>(R.id.video)
val command = bottomSheet.findViewById<TextView>(R.id.command)
// BUTTON ----------------------------------
val audio = bottomSheet.findViewById<TextView>(R.id.audio)
val video = bottomSheet.findViewById<TextView>(R.id.video)
val command = bottomSheet.findViewById<TextView>(R.id.command)
withContext(Dispatchers.IO){
val nr = commandTemplateViewModel.getTotalNumber()
if(nr == 0){
command!!.visibility = View.GONE
}else{
command!!.visibility = View.VISIBLE
}
}
audio!!.setOnClickListener {
items = downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.audio).toMutableList()
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24)
bottomSheet.cancel()
}
video!!.setOnClickListener {
items = downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.video).toMutableList()
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_video_file_24)
bottomSheet.cancel()
}
command!!.setOnClickListener {
lifecycleScope.launch {
items = withContext(Dispatchers.IO){
downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.command).toMutableList()
withContext(Dispatchers.IO){
val nr = commandTemplateViewModel.getTotalNumber()
if(nr == 0){
command!!.visibility = View.GONE
}else{
command!!.visibility = View.VISIBLE
}
}
audio!!.setOnClickListener {
items = downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.audio).toMutableList()
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24)
preferredDownloadType.setIcon(R.drawable.baseline_audio_file_24)
bottomSheet.cancel()
}
video!!.setOnClickListener {
items = downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.video).toMutableList()
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_video_file_24)
bottomSheet.cancel()
}
command!!.setOnClickListener {
lifecycleScope.launch {
items = withContext(Dispatchers.IO){
downloadViewModel.switchDownloadType(items, DownloadViewModel.Type.command).toMutableList()
}
listAdapter.submitList(items.toList())
listAdapter.notifyDataSetChanged()
preferredDownloadType.setIcon(R.drawable.baseline_insert_drive_file_24)
bottomSheet.cancel()
}
}
bottomSheet.show()
bottomSheet.window!!.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
bottomSheet.show()
bottomSheet.window!!.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
R.id.format -> {
if (results.first()!!.formats.isEmpty()){
} else if (itemId == R.id.format){
// val formatListCollection = items.map { it.format }
// val commonFormats = getCommonFormats(formatListCollection)
//
// val listener = object : OnFormatClickListener {
// override fun onFormatClick(allFormats: List<Format>, item: Format) {
//
// }
// }
// if (parentFragmentManager.findFragmentByTag("formatSheet") == null){
// val bottomSheet = FormatSelectionBottomSheetDialog(null, commonFormats.toList(), listener)
// bottomSheet.show(parentFragmentManager, "formatSheet")
// }
}
// val formatListCollection = items.map { it.format }
// val commonFormats = getCommonFormats(formatListCollection)
//
// val listener = object : OnFormatClickListener {
// override fun onFormatClick(allFormats: List<Format>, item: Format) {
//
// }
// }
// if (parentFragmentManager.findFragmentByTag("formatSheet") == null){
// val bottomSheet = FormatSelectionBottomSheetDialog(null, commonFormats.toList(), listener)
// bottomSheet.show(parentFragmentManager, "formatSheet")
// }
}
}
true
}

View file

@ -158,7 +158,7 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
downloadItems.add(i)
}
val bottomSheet = DownloadMultipleBottomSheetDialog(downloadItems)
val bottomSheet = DownloadMultipleBottomSheetDialog(items, downloadItems)
bottomSheet.show(parentFragmentManager, "downloadMultipleSheet")
}

View file

@ -559,6 +559,13 @@ class HistoryFragment : Fragment(), HistoryAdapter.OnItemClickListener{
actionMode?.finish()
true
}
R.id.select_all -> {
historyAdapter?.checkAll(historyList)
selectedObjects?.clear()
historyList?.forEach { selectedObjects?.add(it!!) }
mode?.title = getString(R.string.all_items_selected)
true
}
R.id.invert_selected -> {
historyAdapter?.invertSelected(historyList)
val invertedList = arrayListOf<HistoryItem>()

View file

@ -10,8 +10,11 @@ import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLRequest
import kotlinx.serialization.json.Json
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
@ -22,6 +25,7 @@ import java.net.HttpURLConnection
import java.net.URL
import java.util.*
import java.util.regex.Pattern
import kotlin.collections.ArrayList
class InfoUtil(private val context: Context) {
private var items: ArrayList<ResultItem?>
@ -498,6 +502,56 @@ class InfoUtil(private val context: Context) {
}
}
fun getFormatsTest(urls: List<String>, progress: (progress: List<Format>) -> Unit){
init()
val urlsFile = File(context.cacheDir, "urls.txt")
urlsFile.delete()
urlsFile.createNewFile()
urls.forEach {
urlsFile.appendText(it+"\n")
}
try {
val request = YoutubeDLRequest(emptyList())
request.addOption("--print", "%(formats)s")
request.addOption("-a", urlsFile.absolutePath)
request.addOption("--skip-download")
request.addOption("-R", "1")
request.addOption("--socket-timeout", "5")
val cookiesFile = File(context.cacheDir, "cookies.txt")
if (cookiesFile.exists()){
request.addOption("--cookies", cookiesFile.absolutePath)
}
val youtubeDLResponse = YoutubeDL.getInstance().execute(request){ progress, _, line ->
val formats = mutableListOf<Format>()
val listOfStrings = JSONArray(line)
for (f in 0 until listOfStrings.length()){
val format = listOfStrings.get(f) as JSONObject
try{
if (format.getString("filesize") == "None") continue
}catch (e: Exception) { continue }
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"
}
formatProper.container = format.getString("ext")
formats.add(formatProper)
}
}
progress(formats)
}
} catch (e: Exception) {
Looper.prepare().run {
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
}
e.printStackTrace()
}
urlsFile.delete()
}
fun getFromYTDL(query: String): ArrayList<ResultItem?> {
init()
items = ArrayList()

View file

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?android:colorAccent" android:pathData="M12,2a10,10 0,1 0,10 10A10,10 0,0 0,12 2zM18,11.8a0.9,0.9 0,0 1,-0.1 0.5l-2.1,4.9a1.34,1.34 0,0 1,-1.3 0.8L9,18a2,2 0,0 1,-2 -2v-5a1.28,1.28 0,0 1,0.4 -1L12,5l0.69,0.69a1.08,1.08 0,0 1,0.3 0.7v0.2L12.41,10L17,10a1,1 0,0 1,1 1z"/>
</vector>

View file

@ -199,12 +199,14 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/active_download_cancel"
style="?attr/materialIconButtonFilledTonalStyle"
style="?attr/materialIconButtonFilledStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_marginTop="5dp"
app:cornerRadius="10dp"
app:backgroundTint="?attr/colorSurface"
app:iconTint="?android:textColorPrimary"
app:icon="@drawable/ic_cancel"
app:iconSize="30dp"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -135,7 +135,7 @@
<TextView
android:id="@+id/codec"
style="@style/Widget.Material3.FloatingActionButton.Large.Tertiary"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
@ -153,10 +153,11 @@
<TextView
android:id="@+id/file_size"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="?attr/colorPrimaryInverse"
android:background="?attr/colorSecondary"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
@ -180,6 +181,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cornerRadius="10dp"
app:iconTint="?attr/colorAccent"
app:icon="@drawable/ic_video"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -15,6 +15,11 @@
app:showAsAction="ifRoom"
android:title="@string/share" />
<item
android:id="@+id/select_all"
android:title="@string/select_all"
app:showAsAction="never" />
<item
android:id="@+id/invert_selected"
android:title="@string/invert_selected"