fixes
This commit is contained in:
parent
794f591652
commit
98c1e20d51
17 changed files with 121 additions and 54 deletions
|
|
@ -77,7 +77,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title.ifEmpty { "`${activity.getString(R.string.defaultValue)}`" }
|
||||
itemTitle.text = title.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
|
||||
|
||||
// Author ----------------------------------
|
||||
val author = card.findViewById<TextView>(R.id.author)
|
||||
|
|
@ -86,7 +86,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
if (item.author.isNotEmpty()) info += " • "
|
||||
info += item.duration
|
||||
}
|
||||
author.text = info.ifEmpty { "`${activity.getString(R.string.defaultValue)}`" }
|
||||
author.text = info.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
|
||||
|
||||
val type = card.findViewById<MaterialButton>(R.id.download_type)
|
||||
when(item.type){
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
if (title.length > 100) {
|
||||
title = title.substring(0, 40) + "..."
|
||||
}
|
||||
itemTitle.text = title.ifEmpty { "`${activity.getString(R.string.defaultValue)}`" }
|
||||
itemTitle.text = title.ifEmpty { "<${activity.getString(R.string.defaultValue)}>" }
|
||||
|
||||
val formatNote = card.findViewById<TextView>(R.id.format_note)
|
||||
if (item.format.format_note == "?" || item.format.format_note == "") formatNote!!.visibility =
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ data class DownloadItem(
|
|||
var downloadSections: String,
|
||||
val allFormats: ArrayList<Format>,
|
||||
var downloadPath: String,
|
||||
val website: String,
|
||||
var website: String,
|
||||
val downloadSize: String,
|
||||
val playlistTitle: String,
|
||||
val audioPreferences : AudioPreferences,
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
|
||||
if (arguments?.getString("url") != null){
|
||||
val url = requireArguments().getString("url")
|
||||
arguments?.remove("url")
|
||||
if (inputQueries == null) inputQueries = mutableListOf()
|
||||
searchBar?.text = url
|
||||
inputQueries!!.add(url!!)
|
||||
|
|
@ -202,6 +203,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
|||
resultViewModel.deleteAll()
|
||||
lifecycleScope.launch(Dispatchers.IO){
|
||||
resultViewModel.parseQueries(inputQueries!!)
|
||||
inputQueries = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
behavior = BottomSheetBehavior.from(view.parent as View)
|
||||
val displayMetrics = DisplayMetrics()
|
||||
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
behavior.peekHeight = displayMetrics.heightPixels - 700
|
||||
behavior.peekHeight = displayMetrics.heightPixels
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -159,9 +159,9 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
|
||||
|
||||
scheduleBtn.setOnClickListener{
|
||||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
uiUtil.showDatePicker(fragmentManager) {
|
||||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
val item: DownloadItem = getDownloadItem();
|
||||
item.downloadStartTime = it.timeInMillis
|
||||
runBlocking {
|
||||
|
|
@ -197,13 +197,13 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val
|
|||
(updateItem.parent as LinearLayout).visibility = View.VISIBLE
|
||||
updateItem.setOnClickListener {
|
||||
if (activity is ShareActivity) {
|
||||
dismiss()
|
||||
val intent = Intent(context, ShareActivity::class.java)
|
||||
intent.action = Intent.ACTION_SEND
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_TEXT, resultItem.url)
|
||||
intent.putExtra("quick_download", false)
|
||||
startActivity(intent)
|
||||
dismiss()
|
||||
}else{
|
||||
dismiss()
|
||||
val bundle = Bundle()
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
|
|||
|
||||
|
||||
scheduleBtn.setOnClickListener{
|
||||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
uiUtil.showDatePicker(parentFragmentManager) {
|
||||
scheduleBtn.isEnabled = false
|
||||
download.isEnabled = false
|
||||
items.forEach { item ->
|
||||
item.downloadStartTime = it.timeInMillis
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,13 +88,13 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
|
|||
val end = toTextInput.editText!!.text.toString()
|
||||
|
||||
if (checkRanges(start, end)) {
|
||||
if (start < end){
|
||||
if (start.toInt() < end.toInt()){
|
||||
var startNr = Integer.parseInt(start)
|
||||
startNr--
|
||||
var endNr = Integer.parseInt(end)
|
||||
endNr--
|
||||
if (startNr <= 0) startNr = 0
|
||||
if (endNr > items.size) endNr = items.size
|
||||
if (endNr > items.size) endNr = items.size - 1
|
||||
listAdapter.checkRange(startNr, endNr)
|
||||
selectedText.text = "${listAdapter.getCheckedItems().size} ${resources.getString(R.string.selected)}"
|
||||
}
|
||||
|
|
@ -108,13 +108,13 @@ class SelectPlaylistItemsBottomSheetDialog(private val items: List<ResultItem?>,
|
|||
val end = _text.toString()
|
||||
|
||||
if (checkRanges(start, end)) {
|
||||
if (start < end){
|
||||
if (start.toInt() < end.toInt()){
|
||||
var startNr = Integer.parseInt(start)
|
||||
startNr--
|
||||
var endNr = Integer.parseInt(end)
|
||||
endNr--
|
||||
if (startNr <= 0) startNr = 0
|
||||
if (endNr > items.size) endNr = items.size
|
||||
if (endNr > items.size) endNr = items.size -1
|
||||
listAdapter.checkRange(startNr, endNr)
|
||||
selectedText.text = "${listAdapter.getCheckedItems().size} ${resources.getString(R.string.selected)}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class ActiveDownloadsFragment() : Fragment(), ActiveDownloadAdapter.OnItemClickL
|
|||
val logFile = fileUtil.getLogFile(requireContext(), item)
|
||||
if (logFile.exists()) {
|
||||
val intent = Intent(requireContext(), DownloadLogActivity::class.java)
|
||||
intent.putExtra("path", logFile.absolutePath)
|
||||
intent.putExtra("logpath", logFile.absolutePath)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class ErroredDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickL
|
|||
val item = items.find { it.id == itemID } ?: return
|
||||
val file = fileUtil.getLogFile(requireContext(), item)
|
||||
val intent = Intent(requireContext(), DownloadLogActivity::class.java)
|
||||
intent.putExtra("path", file.absolutePath)
|
||||
intent.putExtra("logpath", file.absolutePath)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class DownloadLogActivity : BaseActivity() {
|
|||
clipboard.setText(content.text)
|
||||
}
|
||||
|
||||
val path = intent.getStringExtra("path")
|
||||
val path = intent.getStringExtra("logpath")
|
||||
if (path == null) {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class DownloadLogListActivity : BaseActivity(), DownloadLogsAdapter.OnItemClickL
|
|||
|
||||
override fun onItemClick(file: File) {
|
||||
val intent = Intent(this, DownloadLogActivity::class.java)
|
||||
intent.putExtra("path", file.absolutePath)
|
||||
intent.putExtra("logpath", file.absolutePath)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.os.Looper
|
|||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.deniscerri.ytdlnis.R
|
||||
import com.deniscerri.ytdlnis.database.models.DownloadItem
|
||||
import com.deniscerri.ytdlnis.database.models.Format
|
||||
import com.deniscerri.ytdlnis.database.models.ResultItem
|
||||
import com.google.gson.Gson
|
||||
|
|
@ -674,6 +675,51 @@ class InfoUtil(private val context: Context) {
|
|||
return items
|
||||
}
|
||||
|
||||
fun getMissingInfo(url: String): ResultItem? {
|
||||
try {
|
||||
val request = YoutubeDLRequest(url)
|
||||
request.addOption("--flat-playlist")
|
||||
request.addOption("-J")
|
||||
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)
|
||||
val jsonObject = JSONObject(youtubeDLResponse.out)
|
||||
val thumbs = jsonObject.getJSONArray("thumbnails")
|
||||
val thumb = thumbs.getJSONObject(thumbs.length() - 1).getString("url")
|
||||
val isPlaylist = jsonObject.has("playlist_count")
|
||||
return ResultItem(
|
||||
0,
|
||||
url,
|
||||
if (isPlaylist){
|
||||
"[${jsonObject.getInt("playlist_count")} Items] ${jsonObject.getString("title")}"
|
||||
}else{
|
||||
jsonObject.getString("title")
|
||||
},
|
||||
jsonObject.getString("uploader"),
|
||||
if (jsonObject.has("duration")) formatIntegerDuration(jsonObject.getInt("duration"), Locale.US) else "",
|
||||
thumb,
|
||||
jsonObject.getString("extractor"),
|
||||
if (isPlaylist) jsonObject.getString("title") else "",
|
||||
arrayListOf(),
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Looper.prepare().run {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
e.printStackTrace()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun getSearchSuggestions(query: String): ArrayList<String> {
|
||||
val url = "https://suggestqueries.google.com/complete/search?client=youtube&ds=yt&client=firefox&q=$query"
|
||||
// invidousURL + "search/suggestions?q=" + query
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
package com.deniscerri.ytdlnis.util
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
|
|
@ -140,16 +137,22 @@ class NotificationUtil(var context: Context) {
|
|||
intent.action = Intent.ACTION_VIEW
|
||||
intent.setDataAndType(uri, "*/*")
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
val openNotificationPendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
val openNotificationPendingIntent: PendingIntent = TaskStackBuilder.create(context).run {
|
||||
addNextIntentWithParentStack(intent)
|
||||
getPendingIntent(0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
//share intent
|
||||
val shareIntent = Intent(context, SharedDownloadNotificationReceiver::class.java)
|
||||
shareIntent.putExtra("share", "")
|
||||
shareIntent.putExtra("path", filepath)
|
||||
shareIntent.putExtra("notificationID", DOWNLOAD_FINISHED_NOTIFICATION_ID)
|
||||
shareIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val shareNotificationPendingIntent = PendingIntent.getActivity(context, 0, shareIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
|
||||
val shareNotificationPendingIntent: PendingIntent = TaskStackBuilder.create(context).run {
|
||||
addNextIntentWithParentStack(shareIntent)
|
||||
getPendingIntent(0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
notificationBuilder.addAction(0, context.getString(R.string.Open_File), openNotificationPendingIntent)
|
||||
notificationBuilder.addAction(0, context.getString(R.string.share), shareNotificationPendingIntent)
|
||||
|
|
@ -160,31 +163,34 @@ class NotificationUtil(var context: Context) {
|
|||
|
||||
fun createDownloadErrored(title: String?,
|
||||
error: String?,
|
||||
logFilePath: String?,
|
||||
logFile: File?,
|
||||
channel: String
|
||||
) {
|
||||
val notificationBuilder = getBuilder(channel)
|
||||
|
||||
val intent = Intent(context, DownloadLogActivity::class.java)
|
||||
intent.putExtra("path", logFilePath)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val errorPendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
|
||||
intent.putExtra("logpath", logFile?.absolutePath)
|
||||
|
||||
val errorPendingIntent: PendingIntent = TaskStackBuilder.create(context).run {
|
||||
addNextIntentWithParentStack(intent)
|
||||
getPendingIntent(0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
notificationBuilder
|
||||
.setContentTitle("${context.getString(R.string.failed_download)}: $title")
|
||||
.setContentText(error)
|
||||
.setContentIntent(errorPendingIntent)
|
||||
.setSmallIcon(R.drawable.ic_app_icon)
|
||||
.setSmallIcon(R.drawable.ic_launcher_foreground_large)
|
||||
.setLargeIcon(
|
||||
BitmapFactory.decodeResource(
|
||||
context.resources,
|
||||
R.drawable.ic_app_icon
|
||||
R.drawable.ic_launcher_foreground_large
|
||||
)
|
||||
)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.clearActions()
|
||||
if (logFilePath != null){
|
||||
if (logFile != null){
|
||||
notificationBuilder.setContentIntent(errorPendingIntent)
|
||||
notificationBuilder.addAction(0, context.getString(R.string.logs), errorPendingIntent)
|
||||
}
|
||||
notificationManager.notify(DOWNLOAD_FINISHED_NOTIFICATION_ID, notificationBuilder.build())
|
||||
|
|
|
|||
|
|
@ -268,6 +268,22 @@ class DownloadWorker(
|
|||
}
|
||||
}
|
||||
|
||||
//update item if its incomplete
|
||||
if (downloadItem.title.isEmpty() || downloadItem.author.isEmpty() || downloadItem.thumb.isEmpty()){
|
||||
runCatching {
|
||||
setProgressAsync(workDataOf("progress" to 0, "output" to "Updating Download Item Data", "id" to downloadItem.id, "log" to false))
|
||||
val info = infoUtil.getMissingInfo(downloadItem.url)
|
||||
if (downloadItem.title.isEmpty()) downloadItem.title = info?.title.toString()
|
||||
if (downloadItem.author.isEmpty()) downloadItem.author = info?.author.toString()
|
||||
if (downloadItem.thumb.isEmpty()) downloadItem.thumb = info?.thumb.toString()
|
||||
downloadItem.duration = info?.duration.toString()
|
||||
downloadItem.website = info?.website.toString()
|
||||
runBlocking {
|
||||
dao.update(downloadItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val logDownloads = sharedPreferences.getBoolean("log_downloads", false) && !sharedPreferences.getBoolean("incognito", false)
|
||||
val logFolder = File(context.filesDir.absolutePath + "/logs")
|
||||
val logFile = fileUtil.getLogFile(context, downloadItem)
|
||||
|
|
@ -282,21 +298,6 @@ class DownloadWorker(
|
|||
"Format: ${downloadItem.format}\n\n")
|
||||
}
|
||||
|
||||
//update item if its incomplete
|
||||
if (downloadItem.title.isEmpty() || downloadItem.author.isEmpty() || downloadItem.thumb.isEmpty()){
|
||||
runCatching {
|
||||
setProgressAsync(workDataOf("progress" to 0, "output" to "Updating Download Item Data", "id" to downloadItem.id, "log" to logDownloads))
|
||||
val info = YoutubeDL.getInfo(downloadItem.url)
|
||||
if (downloadItem.title.isEmpty()) downloadItem.title = info.title.toString()
|
||||
if (downloadItem.author.isEmpty()) downloadItem.author = info.uploader.toString()
|
||||
if (downloadItem.thumb.isEmpty()) downloadItem.thumb = info.thumbnail.toString()
|
||||
downloadItem.duration = infoUtil.formatIntegerDuration(info.duration, Locale.US)
|
||||
runBlocking {
|
||||
dao.update(downloadItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runCatching {
|
||||
YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line ->
|
||||
setProgressAsync(workDataOf("progress" to progress.toInt(), "output" to line.chunked(5000).first().toString(), "id" to downloadItem.id, "log" to logDownloads))
|
||||
|
|
@ -376,7 +377,7 @@ class DownloadWorker(
|
|||
|
||||
notificationUtil.createDownloadErrored(
|
||||
downloadItem.title, it.message,
|
||||
if (logDownloads) logFile.absolutePath else null,
|
||||
if (logDownloads) logFile else null,
|
||||
NotificationUtil.DOWNLOAD_FINISHED_CHANNEL_ID
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
android:checkable="true"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
app:cardPreventCornerOverlap="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
@ -178,12 +178,13 @@
|
|||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/action_button"
|
||||
style="?attr/materialIconButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:padding="0dp"
|
||||
android:minHeight="0dp"
|
||||
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"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.0" />
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
|
||||
def versionMajor = 1
|
||||
def versionMinor = 6
|
||||
def versionPatch = 0
|
||||
def versionPatch = 1
|
||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
||||
|
||||
ext {
|
||||
|
|
|
|||
11
fastlane/metadata/android/en-US/changelogs/10610.txt
Normal file
11
fastlane/metadata/android/en-US/changelogs/10610.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
## Introducing Quick Download Mode
|
||||
You can launch a download (or card) immediately without fetching data at first.
|
||||
|
||||
Added Theme Picker, Accents and High Contrast Mode
|
||||
Added swipe actions on history,downloads,cookies,templates cards
|
||||
Added finished download notification with actions
|
||||
Fixed Tiktok videos not creating result cards
|
||||
Added active downloads badge in the navigation bar
|
||||
Added remove audio feature for videos
|
||||
Added check for present downloads
|
||||
Added preferred Format ID
|
||||
Loading…
Reference in a new issue