From 0f6d1fa765d2904c31a3e9e58f323c3192b4225f Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Sun, 28 May 2023 13:19:35 +0200 Subject: [PATCH] more more fixes lol fixed Snackbar overlapping with buttons on settings fixed locale not translating right in download card fixed format updating the container when re-selecting it made the video tab disabled when the item only has audio formats made the app fetch streaming url and chapters from the start so it loads faster when trying to cut a video added url in format item --- .../6.json | 448 +++++++++++++++++ .../com/deniscerri/ytdlnis/MainActivity.kt | 8 +- .../ytdlnis/adapter/ActiveDownloadAdapter.kt | 4 +- .../ConfigureMultipleDownloadsAdapter.kt | 4 +- .../ytdlnis/adapter/GenericDownloadAdapter.kt | 6 +- .../deniscerri/ytdlnis/database/Converters.kt | 13 + .../deniscerri/ytdlnis/database/DBManager.kt | 5 +- .../ytdlnis/database/models/DownloadItem.kt | 2 + .../ytdlnis/database/models/Format.kt | 5 +- .../ytdlnis/database/models/ResultItem.kt | 4 + .../repository/CommandTemplateRepository.kt | 4 +- .../database/repository/HistoryRepository.kt | 3 +- .../database/viewmodel/DownloadViewModel.kt | 47 +- .../database/viewmodel/HistoryViewModel.kt | 3 +- .../receiver/SharedNotificationReceiver.kt | 2 +- .../com/deniscerri/ytdlnis/ui/BaseActivity.kt | 5 - .../com/deniscerri/ytdlnis/ui/HomeFragment.kt | 3 - .../ConfigureDownloadBottomSheetDialog.kt | 22 +- .../downloadcard/CutVideoBottomSheetDialog.kt | 39 +- .../ui/downloadcard/DownloadAudioFragment.kt | 27 +- .../downloadcard/DownloadBottomSheetDialog.kt | 25 +- .../downloadcard/DownloadCommandFragment.kt | 16 +- .../DownloadMultipleBottomSheetDialog.kt | 6 +- .../ui/downloadcard/DownloadVideoFragment.kt | 40 +- .../FormatSelectionBottomSheetDialog.kt | 13 +- .../ui/downloads/ActiveDownloadsFragment.kt | 6 +- .../downloads/CancelledDownloadsFragment.kt | 6 +- .../ui/downloads/ErroredDownloadsFragment.kt | 9 +- .../ytdlnis/ui/downloads/HistoryFragment.kt | 6 +- .../ui/downloads/QueuedDownloadsFragment.kt | 6 +- .../ui/more/CommandTemplatesFragment.kt | 2 +- .../ytdlnis/ui/more/CookiesFragment.kt | 2 +- .../ytdlnis/ui/more/TerminalActivity.kt | 6 +- .../more/settings/FolderSettingsFragment.kt | 20 +- .../more/settings/GeneralSettingsFragment.kt | 2 - .../ui/more/settings/MainSettingsFragment.kt | 2 - .../com/deniscerri/ytdlnis/util/FileUtil.kt | 18 +- .../com/deniscerri/ytdlnis/util/InfoUtil.kt | 162 +++++-- .../com/deniscerri/ytdlnis/util/UiUtil.kt | 21 +- .../deniscerri/ytdlnis/work/DownloadWorker.kt | 31 +- .../ytdlnis/work/TerminalDownloadWorker.kt | 5 +- app/src/main/res/layout/activity_settings.xml | 1 - .../main/res/layout/format_details_sheet.xml | 449 ++++++++++-------- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/folders_preference.xml | 3 - app/src/main/res/xml/general_preferences.xml | 2 +- 46 files changed, 1056 insertions(+), 459 deletions(-) create mode 100644 app/schemas/com.deniscerri.ytdlnis.database.DBManager/6.json diff --git a/app/schemas/com.deniscerri.ytdlnis.database.DBManager/6.json b/app/schemas/com.deniscerri.ytdlnis.database.DBManager/6.json new file mode 100644 index 00000000..4bde6f31 --- /dev/null +++ b/app/schemas/com.deniscerri.ytdlnis.database.DBManager/6.json @@ -0,0 +1,448 @@ +{ + "formatVersion": 1, + "database": { + "version": 6, + "identityHash": "d34711f8239a4a966885543cd5454eab", + "entities": [ + { + "tableName": "results", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `website` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `formats` TEXT NOT NULL, `urls` TEXT NOT NULL DEFAULT '', `chapters` TEXT, `creationTime` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "thumb", + "columnName": "thumb", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "website", + "columnName": "website", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "playlistTitle", + "columnName": "playlistTitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "formats", + "columnName": "formats", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "urls", + "columnName": "urls", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "chapters", + "columnName": "chapters", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "creationTime", + "columnName": "creationTime", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `duration` TEXT NOT NULL, `thumb` TEXT NOT NULL, `type` TEXT NOT NULL, `time` INTEGER NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `format` TEXT NOT NULL, `downloadId` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "thumb", + "columnName": "thumb", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadPath", + "columnName": "downloadPath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "website", + "columnName": "website", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "format", + "columnName": "format", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "downloadId", + "columnName": "downloadId", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "downloads", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `thumb` TEXT NOT NULL, `duration` TEXT NOT NULL, `type` TEXT NOT NULL, `format` TEXT NOT NULL, `container` TEXT NOT NULL DEFAULT 'Default', `downloadSections` TEXT NOT NULL DEFAULT '', `allFormats` TEXT NOT NULL, `downloadPath` TEXT NOT NULL, `website` TEXT NOT NULL, `downloadSize` TEXT NOT NULL, `playlistTitle` TEXT NOT NULL, `audioPreferences` TEXT NOT NULL, `videoPreferences` TEXT NOT NULL, `customFileNameTemplate` TEXT NOT NULL, `SaveThumb` INTEGER NOT NULL, `status` TEXT NOT NULL DEFAULT 'Queued', `downloadStartTime` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "thumb", + "columnName": "thumb", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "format", + "columnName": "format", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "container", + "columnName": "container", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'Default'" + }, + { + "fieldPath": "downloadSections", + "columnName": "downloadSections", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "allFormats", + "columnName": "allFormats", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "downloadPath", + "columnName": "downloadPath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "website", + "columnName": "website", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "downloadSize", + "columnName": "downloadSize", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "playlistTitle", + "columnName": "playlistTitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "audioPreferences", + "columnName": "audioPreferences", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "videoPreferences", + "columnName": "videoPreferences", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "customFileNameTemplate", + "columnName": "customFileNameTemplate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "SaveThumb", + "columnName": "SaveThumb", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'Queued'" + }, + { + "fieldPath": "downloadStartTime", + "columnName": "downloadStartTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "commandTemplates", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "searchHistory", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `query` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "query", + "columnName": "query", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "templateShortcuts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "cookies", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd34711f8239a4a966885543cd5454eab')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt index 9db3abd1..b659169b 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/MainActivity.kt @@ -38,6 +38,7 @@ 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 @@ -67,7 +68,6 @@ class MainActivity : BaseActivity() { private lateinit var navHostFragment : NavHostFragment private lateinit var navController : NavController - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ThemeUtil.updateTheme(this) @@ -338,9 +338,9 @@ class MainActivity : BaseActivity() { private fun createDefaultFolders(){ - val audio = File(getString(R.string.music_path)) - val video = File(getString(R.string.video_path)) - val command = File(getString(R.string.command_path)) + val audio = File(FileUtil.getDefautAudioPath()) + val video = File(FileUtil.getDefautVideoPath()) + val command = File(FileUtil.getDefaultCommandPath()) audio.mkdirs() video.mkdirs() diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt index e6de79d6..0304fe65 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ActiveDownloadAdapter.kt @@ -28,12 +28,10 @@ import com.squareup.picasso.Picasso class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) { private val onItemClickListener: OnItemClickListener private val activity: Activity - private val fileUtil: FileUtil init { this.onItemClickListener = onItemClickListener this.activity = activity - fileUtil = FileUtil() } class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) { @@ -113,7 +111,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity: } val fileSize = card.findViewById(R.id.file_size) - fileSize.text = fileUtil.convertFileSize(item.format.filesize) + fileSize.text = FileUtil.convertFileSize(item.format.filesize) if (fileSize.text == "?") fileSize.visibility = View.GONE if (fileSize.visibility == View.VISIBLE && codec.visibility == View.GONE){ diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ConfigureMultipleDownloadsAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ConfigureMultipleDownloadsAdapter.kt index 9631c147..7e929217 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/ConfigureMultipleDownloadsAdapter.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/ConfigureMultipleDownloadsAdapter.kt @@ -24,12 +24,10 @@ import java.util.Locale class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) { private val onItemClickListener: OnItemClickListener private val activity: Activity - private var fileUtil: FileUtil init { this.onItemClickListener = onItemClickListener this.activity = activity - fileUtil = FileUtil() } class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) { @@ -96,7 +94,7 @@ class ConfigureMultipleDownloadsAdapter(onItemClickListener: OnItemClickListener } val fileSize = card.findViewById(R.id.file_size) - val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize) + val fileSizeReadable = FileUtil.convertFileSize(item.format.filesize) if (fileSizeReadable == "?") fileSize.visibility = View.GONE else { fileSize.text = fileSizeReadable diff --git a/app/src/main/java/com/deniscerri/ytdlnis/adapter/GenericDownloadAdapter.kt b/app/src/main/java/com/deniscerri/ytdlnis/adapter/GenericDownloadAdapter.kt index 3504d1a0..4c7d19ad 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/adapter/GenericDownloadAdapter.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/adapter/GenericDownloadAdapter.kt @@ -24,14 +24,12 @@ import com.squareup.picasso.Picasso class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity: Activity) : ListAdapter(AsyncDifferConfig.Builder(DIFF_CALLBACK).build()) { private val onItemClickListener: OnItemClickListener private val activity: Activity - private var fileUtil: FileUtil private val checkedItems: ArrayList init { checkedItems = ArrayList() this.onItemClickListener = onItemClickListener this.activity = activity - fileUtil = FileUtil() } class ViewHolder(itemView: View, onItemClickListener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView) { @@ -94,7 +92,7 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity: } val fileSize = card.findViewById(R.id.file_size) - val fileSizeReadable = fileUtil.convertFileSize(item.format.filesize) + val fileSizeReadable = FileUtil.convertFileSize(item.format.filesize) if (fileSizeReadable == "?") fileSize.visibility = View.GONE else fileSize.text = fileSizeReadable @@ -107,7 +105,7 @@ class GenericDownloadAdapter(onItemClickListener: OnItemClickListener, activity: DownloadRepository.Status.Queued.toString() -> actionButton.setIconResource(R.drawable.ic_baseline_delete_outline_24) else -> { actionButton.setIconResource(R.drawable.ic_baseline_file_open_24) - val logFile = fileUtil.getLogFile(activity, item) + val logFile = FileUtil.getLogFile(activity, item) if (!logFile.exists()){ actionButton.visibility = View.GONE } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/Converters.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/Converters.kt index 4bfb77c4..f4850317 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/Converters.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/Converters.kt @@ -2,6 +2,7 @@ package com.deniscerri.ytdlnis.database import androidx.room.TypeConverter import com.deniscerri.ytdlnis.database.models.AudioPreferences +import com.deniscerri.ytdlnis.database.models.ChapterItem import com.deniscerri.ytdlnis.database.models.Format import com.deniscerri.ytdlnis.database.models.VideoPreferences import com.deniscerri.ytdlnis.database.viewmodel.DownloadViewModel @@ -50,4 +51,16 @@ class Converters { fun videoPreferencesToString(videoPreferences: VideoPreferences): String = Gson().toJson(videoPreferences) @TypeConverter fun stringToVideoPreferences(string: String): VideoPreferences = Gson().fromJson(string, VideoPreferences::class.java) + + @TypeConverter + fun stringToListOfChapters(value: String?): ArrayList? { + val listType: Type = object : TypeToken?>() {}.type + return Gson().fromJson(value, listType) + } + + @TypeConverter + fun listOfChaptersToString(list: ArrayList?): String { + val gson = Gson() + return gson.toJson(list) + } } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/DBManager.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/DBManager.kt index 294e4c4d..89e597d5 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/DBManager.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/DBManager.kt @@ -8,12 +8,13 @@ import com.deniscerri.ytdlnis.database.models.* @TypeConverters(Converters::class) @Database( entities = [ResultItem::class, HistoryItem::class, DownloadItem::class, CommandTemplate::class, SearchHistoryItem::class, TemplateShortcut::class, CookieItem::class], - version = 5, + version = 6, autoMigrations = [ AutoMigration (from = 1, to = 2), AutoMigration (from = 2, to = 3), AutoMigration (from = 3, to = 4), - AutoMigration (from = 4, to = 5) + AutoMigration (from = 4, to = 5), + AutoMigration (from = 5, to = 6) ] ) abstract class DBManager : RoomDatabase(){ diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt index ccb5f99c..aed75696 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/DownloadItem.kt @@ -16,6 +16,8 @@ data class DownloadItem( var duration: String, var type: DownloadViewModel.Type, var format: Format, + @ColumnInfo(defaultValue = "Default") + var container: String, @ColumnInfo(defaultValue = "") var downloadSections: String, val allFormats: ArrayList, diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/Format.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/Format.kt index eaef477b..12bec0ad 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/Format.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/Format.kt @@ -13,7 +13,7 @@ data class Format( var acodec: String = "", @SerializedName(value = "encoding") var encoding: String = "", - @SerializedName(value = "filesize", alternate = ["clen", "filesize_approx"]) + @SerializedName(value = "filesize", alternate = ["clen", "filesize_approx", "contentLength"]) var filesize: Long = 0, @SerializedName(value = "format_note", alternate = ["resolution", "audioQuality", "quality"]) var format_note: String = "", @@ -21,5 +21,6 @@ data class Format( var fps: String? = "", @SerializedName(value = "asr", alternate = ["audioSampleRate"]) var asr: String? = "", - + @SerializedName(value = "url") + var url: String? = "" ) \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt index 5a57b69a..c40242ab 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/ResultItem.kt @@ -1,5 +1,6 @@ package com.deniscerri.ytdlnis.database.models +import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey @@ -15,5 +16,8 @@ data class ResultItem( val website: String, var playlistTitle: String, var formats: ArrayList, + @ColumnInfo(defaultValue = "") + var urls: String, + var chapters: ArrayList?, var creationTime: Long = System.currentTimeMillis() / 1000, ) \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/CommandTemplateRepository.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/CommandTemplateRepository.kt index 1ff727be..31721162 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/CommandTemplateRepository.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/CommandTemplateRepository.kt @@ -10,7 +10,7 @@ class CommandTemplateRepository(private val commandDao: CommandTemplateDao) { val shortcuts : LiveData> = commandDao.getAllShortcutsLiveData() fun getAll() : List { - return commandDao.getAllTemplates(); + return commandDao.getAllTemplates() } fun getTotalNumber() : Int { @@ -34,7 +34,7 @@ class CommandTemplateRepository(private val commandDao: CommandTemplateDao) { } fun getAllShortCuts() : List { - return commandDao.getAllShortcuts(); + return commandDao.getAllShortcuts() } suspend fun insertShortcut(item: TemplateShortcut){ diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt index b4370ffa..ba31c176 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/repository/HistoryRepository.kt @@ -59,9 +59,8 @@ class HistoryRepository(private val historyDao: HistoryDao) { } suspend fun clearDeletedHistory(){ - val fileUtil = FileUtil() items.value?.forEach { item -> - if (!fileUtil.exists(item.downloadPath)){ + if (!FileUtil.exists(item.downloadPath)){ historyDao.delete(item.id) } } 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 a141b471..dfebe321 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 @@ -33,6 +33,7 @@ import com.deniscerri.ytdlnis.database.models.HistoryItem import com.deniscerri.ytdlnis.database.models.ResultItem import com.deniscerri.ytdlnis.database.models.VideoPreferences import com.deniscerri.ytdlnis.database.repository.DownloadRepository +import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.InfoUtil import com.deniscerri.ytdlnis.work.DownloadWorker import com.google.gson.Gson @@ -46,7 +47,7 @@ import java.util.Locale import java.util.concurrent.TimeUnit -class DownloadViewModel(private val application: Application) : AndroidViewModel(application) { +class DownloadViewModel(application: Application) : AndroidViewModel(application) { private val repository : DownloadRepository private val sharedPreferences: SharedPreferences private val commandTemplateDao: CommandTemplateDao @@ -152,9 +153,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel } val downloadPath = when(type){ - Type.audio -> sharedPreferences.getString("music_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Audio").absolutePath) - Type.video -> sharedPreferences.getString("video_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Video").absolutePath) - else -> sharedPreferences.getString("command_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Command").absolutePath) + Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefautAudioPath()) + Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefautVideoPath()) + else -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath()) } val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet()) @@ -170,6 +171,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel resultItem.duration, type, getFormat(resultItem.formats, type), + sharedPreferences.getString("video_format", "Default")!!, "", resultItem.formats, downloadPath!!, resultItem.website, "", resultItem.playlistTitle, audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0 @@ -188,6 +190,8 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel downloadItem.website, downloadItem.playlistTitle, downloadItem.allFormats, + "", + arrayListOf(), System.currentTimeMillis() ) @@ -204,6 +208,8 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel downloadItem.website, "", arrayListOf(), + "", + arrayListOf(), System.currentTimeMillis() ) @@ -220,6 +226,8 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel "", "", arrayListOf(), + "", + arrayListOf(), System.currentTimeMillis() ) @@ -247,9 +255,15 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel } val downloadPath = when(historyItem.type){ - Type.audio -> sharedPreferences.getString("music_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Audio").absolutePath) - Type.video -> sharedPreferences.getString("video_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Video").absolutePath) - else -> sharedPreferences.getString("command_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Command").absolutePath) + Type.audio -> sharedPreferences.getString("music_path", FileUtil.getDefautAudioPath()) + Type.video -> sharedPreferences.getString("video_path", FileUtil.getDefautVideoPath()) + else -> sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath()) + } + + val container = when(historyItem.type){ + Type.audio -> sharedPreferences.getString("audio_format", "Default")!! + Type.video -> sharedPreferences.getString("video_format", "Default")!! + else -> "" } val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet()) @@ -265,6 +279,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel historyItem.duration, historyItem.type, historyItem.format, + container, "", ArrayList(), downloadPath!!, historyItem.website, "", "", audioPreferences, videoPreferences,customFileNameTemplate!!, saveThumb, DownloadRepository.Status.Processing.toString(), 0 @@ -438,24 +453,6 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel } } - //if the download was quick downloaded and are incomplete - if (queuedItems.count() == 1){ - val item = queuedItems.first() - if (item.title.isEmpty() || item.author.isEmpty() || item.thumb.isEmpty()){ - runCatching { - val info = infoUtil.getMissingInfo(item.url) - if (item.title.isEmpty()) item.title = info?.title.toString() - if (item.author.isEmpty()) item.author = info?.author.toString() - item.duration = info?.duration.toString() - item.website = info?.website.toString() - if (item.thumb.isEmpty()) item.thumb = info?.thumb.toString() - repository.update(item) - }.onFailure { err -> - Log.e("error", err.message.toString()) - } - } - } - queuedItems.forEach { val currentTime = System.currentTimeMillis() var delay = if (it.downloadStartTime != 0L){ diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt index 81ac3e25..405bb0a3 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/HistoryViewModel.kt @@ -90,8 +90,7 @@ class HistoryViewModel(application: Application) : AndroidViewModel(application) fun delete(item: HistoryItem, deleteFile: Boolean) = viewModelScope.launch(Dispatchers.IO){ repository.delete(item) if (deleteFile){ - val fileUtil = FileUtil() - fileUtil.deleteFile(item.downloadPath) + FileUtil.deleteFile(item.downloadPath) } } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/receiver/SharedNotificationReceiver.kt b/app/src/main/java/com/deniscerri/ytdlnis/receiver/SharedNotificationReceiver.kt index 488e42b6..e45e56d5 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/receiver/SharedNotificationReceiver.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/receiver/SharedNotificationReceiver.kt @@ -17,7 +17,7 @@ class SharedDownloadNotificationReceiver : AppCompatActivity() { val notificationId = intent.getIntExtra("notificationID", 0) if (message != null && path != null) { if (notificationId != 0) NotificationUtil(this).cancelDownloadNotification(notificationId) - val uiUtil = UiUtil(FileUtil()) + val uiUtil = UiUtil() uiUtil.shareFileIntent(this, listOf(path)) this.finishAffinity() } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/BaseActivity.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/BaseActivity.kt index 5eb3a09d..7ad2793a 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/BaseActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/BaseActivity.kt @@ -11,10 +11,5 @@ open class BaseActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ThemeUtil.updateTheme(this) super.onCreate(savedInstanceState) - WindowCompat.setDecorFitsSystemWindows(window, false) - ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { v, insets -> - v.setPadding(0, 0, 0, 0) - insets - } } } \ No newline at end of file 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 d6c05404..b03489c3 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/HomeFragment.kt @@ -37,7 +37,6 @@ import com.deniscerri.ytdlnis.database.viewmodel.ResultViewModel import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding import com.deniscerri.ytdlnis.ui.downloadcard.DownloadBottomSheetDialog import com.deniscerri.ytdlnis.ui.downloadcard.DownloadMultipleBottomSheetDialog -import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.InfoUtil import com.facebook.shimmer.ShimmerFrameLayout import com.google.android.material.appbar.AppBarLayout @@ -88,7 +87,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene private var uiHandler: Handler? = null private var resultsList: List? = null private var selectedObjects: ArrayList? = null - private var fileUtil: FileUtil? = null private var quickLaunchSheet = false private var sharedPreferences: SharedPreferences? = null private var _binding : FragmentHomeBinding? = null @@ -114,7 +112,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, OnClickListene fragmentContext = context layoutinflater = LayoutInflater.from(context) - fileUtil = FileUtil() uiHandler = Handler(Looper.getMainLooper()) selectedObjects = ArrayList() diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt index 71594ac2..8d6ba286 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/ConfigureDownloadBottomSheetDialog.kt @@ -50,7 +50,7 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java] commandTemplateDao = DBManager.getInstance(requireContext()).commandTemplateDao onDownloadItemUpdateListener = listener - uiUtil = UiUtil(FileUtil()) + uiUtil = UiUtil() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -94,6 +94,13 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri } } + //check if the item has formats and its audio-only + val isAudioOnly = resultItem.formats.isNotEmpty() && resultItem.formats.none { !it.format_note.contains("audio") } + if (isAudioOnly){ + (tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(1)?.isClickable = true + (tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(1)?.alpha = 0.3f + } + val fragmentManager = parentFragmentManager fragmentAdapter = DownloadFragmentAdapter( @@ -111,8 +118,14 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri viewPager2.setCurrentItem(0, false) } Type.video -> { - tabLayout.selectTab(tabLayout.getTabAt(1)) - viewPager2.setCurrentItem(1, false) + if (isAudioOnly){ + tabLayout.getTabAt(0)!!.select() + viewPager2.setCurrentItem(0, false) + Toast.makeText(context, getString(R.string.audio_only_item), Toast.LENGTH_SHORT).show() + }else{ + tabLayout.getTabAt(1)!!.select() + viewPager2.setCurrentItem(1, false) + } } else -> { tabLayout.selectTab(tabLayout.getTabAt(2)) @@ -127,6 +140,9 @@ class ConfigureDownloadBottomSheetDialog(private val resultItem: ResultItem, pri if (tab!!.position == 2 && commandTemplateNr == 0){ tabLayout.selectTab(tabLayout.getTabAt(1)) Toast.makeText(context, getString(R.string.add_template_first), Toast.LENGTH_SHORT).show() + }else if (tab.position == 1 && isAudioOnly){ + tabLayout.selectTab(tabLayout.getTabAt(0)) + Toast.makeText(context, getString(R.string.audio_only_item), Toast.LENGTH_SHORT).show() }else{ viewPager2.setCurrentItem(tab.position, false) } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/CutVideoBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/CutVideoBottomSheetDialog.kt index 2fc8527d..ac2c2a53 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/CutVideoBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/CutVideoBottomSheetDialog.kt @@ -60,9 +60,8 @@ import java.util.* import kotlin.properties.Delegates -class CutVideoBottomSheetDialog(private val item: DownloadItem, private val listener: VideoCutListener) : BottomSheetDialogFragment() { +class CutVideoBottomSheetDialog(private val item: DownloadItem, private val urls : String?, private var chapters: List?, private val listener: VideoCutListener) : BottomSheetDialogFragment() { private lateinit var behavior: BottomSheetBehavior - private lateinit var fileUtil: FileUtil private lateinit var infoUtil: InfoUtil private lateinit var uiUtil: UiUtil private lateinit var player: Player @@ -86,14 +85,12 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list private lateinit var chipGroup : ChipGroup private var timeSeconds by Delegates.notNull() - private lateinit var chapters: List private lateinit var selectedCuts: MutableList override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - fileUtil = FileUtil() - uiUtil = UiUtil(fileUtil) + uiUtil = UiUtil() infoUtil = InfoUtil(requireActivity().applicationContext) } @@ -150,7 +147,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list val videoView = view.findViewById(R.id.video_view) videoView.player = player timeSeconds = convertStringToTimestamp(item.duration) - chapters = emptyList() + if (chapters == null) chapters = emptyList() //cut section cutSection = view.findViewById(R.id.cut_section) @@ -166,7 +163,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list okBtn = view.findViewById(R.id.okButton) suggestedChips = view.findViewById(R.id.chapters) suggestedChapters = view.findViewById(R.id.suggested_cuts) - initCutSection() + //cut list section cutListSection = view.findViewById(R.id.list_section) @@ -174,6 +171,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list resetBtn = view.findViewById(R.id.reset_all) chipGroup = view.findViewById(R.id.cut_list_chip_group) + selectedCuts = if (chipGroup.childCount == 0){ mutableListOf() }else { @@ -183,6 +181,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list chipGroup.children.map { (it as Chip).text.toString() }.toMutableList() } + initCutSection() initCutListSection() if (item.downloadSections.isBlank()) cutSection.visibility = View.VISIBLE @@ -190,16 +189,22 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list lifecycleScope.launch { try { - val data = withContext(Dispatchers.IO){ - infoUtil.getStreamingUrlAndChapters(item.url) + val data : MutableList = withContext(Dispatchers.IO){ + if (urls.isNullOrEmpty() || chapters.isNullOrEmpty()) { + infoUtil.getStreamingUrlAndChapters(item.url) + }else { + urls.split("\n").toMutableList() + } } - if (data.isEmpty()) throw Exception("No Data found!") - try{ - val listType: Type = object : TypeToken>() {}.type - chapters = Gson().fromJson(data.first().toString(), listType) - }catch (ignored: Exception) {} - data.removeFirst() + if (data.isEmpty()) throw Exception("No Data found!") + if (chapters!!.isEmpty()){ + try{ + val listType: Type = object : TypeToken>() {}.type + chapters = Gson().fromJson(data.first().toString(), listType) + }catch (ignored: Exception) {} + data.removeFirst() + } if (data.isEmpty()) throw Exception("No Streaming URL found!") if (data.size == 2){ @@ -375,11 +380,11 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list } private fun populateSuggestedChapters(){ - if (chapters.isEmpty()) suggestedChapters.visibility = View.GONE + if (chapters!!.isEmpty()) suggestedChapters.visibility = View.GONE else { suggestedChapters.visibility = View.VISIBLE suggestedChips.removeAllViews() - chapters.forEach { + chapters!!.forEach { val chip = layoutInflater.inflate(R.layout.suggestion_chip, chipGroup, false) as Chip chip.text = it.title chip.chipBackgroundColor = ColorStateList.valueOf(MaterialColors.getColor(requireContext(), R.attr.colorSecondaryContainer, Color.BLACK)) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadAudioFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadAudioFragment.kt index c252c864..8dfd31e2 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadAudioFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadAudioFragment.kt @@ -51,7 +51,6 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel private lateinit var resultViewModel : ResultViewModel - private lateinit var fileUtil : FileUtil private lateinit var uiUtil : UiUtil private lateinit var title : TextInputLayout @@ -71,8 +70,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java] - fileUtil = FileUtil() - uiUtil = UiUtil(fileUtil) + uiUtil = UiUtil() return fragmentView } @@ -112,7 +110,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr }) saveDir = view.findViewById(R.id.outputPath) saveDir.editText!!.setText( - fileUtil.formatPath(downloadItem.downloadPath) + FileUtil.formatPath(downloadItem.downloadPath) ) saveDir.editText!!.isFocusable = false saveDir.editText!!.isClickable = true @@ -124,8 +122,8 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr audioPathResultLauncher.launch(intent) } freeSpace = view.findViewById(R.id.freespace) - val free = fileUtil.convertFileSize( - File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace) + val free = FileUtil.convertFileSize( + File(FileUtil.formatPath(downloadItem.downloadPath)).freeSpace) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free) if (free == "?") freeSpace.visibility = View.GONE @@ -157,7 +155,6 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr } } formats = allFormats.first().toMutableList() - downloadItem.format.container = container.editText?.text.toString() } } formatCard.setOnClickListener{ @@ -181,13 +178,13 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr ) ) - downloadItem.format.container = if (containerPreference == getString(R.string.defaultValue)) "" else containerPreference!! - containerAutoCompleteTextView.setText(downloadItem.format.container.ifEmpty { getString(R.string.defaultValue) }, false) + downloadItem.container = if (containerPreference == getString(R.string.defaultValue)) "" else containerPreference!! + containerAutoCompleteTextView.setText(downloadItem.container.ifEmpty { getString(R.string.defaultValue) }, false) (container!!.editText as AutoCompleteTextView?)!!.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long -> - downloadItem.format.container = containers[index] - if (containers[index] == getString(R.string.defaultValue)) downloadItem.format.container = "" + downloadItem.container = containers[index] + if (containers[index] == getString(R.string.defaultValue)) downloadItem.container = "" } val embedThumb = view.findViewById(R.id.embed_thumb) @@ -313,7 +310,7 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr } cut.setOnClickListener { if (parentFragmentManager.findFragmentByTag("cutVideoSheet") == null){ - val bottomSheet = CutVideoBottomSheetDialog(downloadItem, cutVideoListener) + val bottomSheet = CutVideoBottomSheetDialog(downloadItem, resultItem.urls, resultItem.chapters, cutVideoListener) bottomSheet.show(parentFragmentManager, "cutVideoSheet") } } @@ -340,10 +337,10 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr } downloadItem.downloadPath = result.data?.data.toString() //downloadViewModel.updateDownload(downloadItem) - saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) + saveDir.editText?.setText(FileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) - val free = fileUtil.convertFileSize( - File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace) + val free = FileUtil.convertFileSize( + File(FileUtil.formatPath(downloadItem.downloadPath)).freeSpace) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free) if (free == "?") freeSpace.visibility = View.GONE } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadBottomSheetDialog.kt index 022ae073..f3504351 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadBottomSheetDialog.kt @@ -59,7 +59,7 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java] commandTemplateDao = DBManager.getInstance(requireContext()).commandTemplateDao - uiUtil = UiUtil(FileUtil()) + uiUtil = UiUtil() infoUtil = InfoUtil(requireContext()) } @@ -103,6 +103,13 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val } } + //check if the item has formats and its audio-only + val isAudioOnly = resultItem.formats.isNotEmpty() && resultItem.formats.none { !it.format_note.contains("audio") } + if (isAudioOnly){ + (tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(1)?.isClickable = true + (tabLayout.getChildAt(0) as? ViewGroup)?.getChildAt(1)?.alpha = 0.3f + } + val fragmentManager = parentFragmentManager fragmentAdapter = DownloadFragmentAdapter( @@ -121,8 +128,14 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val viewPager2.setCurrentItem(0, false) } Type.video -> { - tabLayout.getTabAt(1)!!.select() - viewPager2.setCurrentItem(1, false) + if (isAudioOnly){ + tabLayout.getTabAt(0)!!.select() + viewPager2.setCurrentItem(0, false) + Toast.makeText(context, getString(R.string.audio_only_item), Toast.LENGTH_SHORT).show() + }else{ + tabLayout.getTabAt(1)!!.select() + viewPager2.setCurrentItem(1, false) + } } else -> { tabLayout.getTabAt(2)!!.select() @@ -138,7 +151,11 @@ class DownloadBottomSheetDialog(private val resultItem: ResultItem, private val if (tab!!.position == 2 && commandTemplateNr == 0){ tabLayout.selectTab(tabLayout.getTabAt(1)) Toast.makeText(context, getString(R.string.add_template_first), Toast.LENGTH_SHORT).show() - }else{ + }else if (tab.position == 1 && isAudioOnly){ + tabLayout.selectTab(tabLayout.getTabAt(0)) + Toast.makeText(context, getString(R.string.audio_only_item), Toast.LENGTH_SHORT).show() + } + else{ viewPager2.setCurrentItem(tab.position, false) } } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadCommandFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadCommandFragment.kt index 8dde869f..8fb3a5aa 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadCommandFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadCommandFragment.kt @@ -42,7 +42,6 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel private lateinit var commandTemplateViewModel : CommandTemplateViewModel - private lateinit var fileUtil : FileUtil private lateinit var uiUtil : UiUtil private lateinit var saveDir : TextInputLayout private lateinit var freeSpace : TextView @@ -59,8 +58,7 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu activity = getActivity() downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java] - fileUtil = FileUtil() - uiUtil = UiUtil(fileUtil) + uiUtil = UiUtil() return fragmentView } @@ -138,7 +136,7 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu saveDir = view.findViewById(R.id.outputPath) saveDir.editText!!.setText( - fileUtil.formatPath(downloadItem.downloadPath) + FileUtil.formatPath(downloadItem.downloadPath) ) saveDir.editText!!.isFocusable = false saveDir.editText!!.isClickable = true @@ -151,8 +149,8 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu } freeSpace = view.findViewById(R.id.freespace) - freeSpace.text = String.format(getString(R.string.freespace) + ": " + fileUtil.convertFileSize( - File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace + freeSpace.text = String.format(getString(R.string.freespace) + ": " + FileUtil.convertFileSize( + File(FileUtil.formatPath(downloadItem.downloadPath)).freeSpace )) val newTemplate : Chip = view.findViewById(R.id.newTemplate) @@ -226,10 +224,10 @@ class DownloadCommandFragment(private val resultItem: ResultItem, private var cu ) } downloadItem.downloadPath = result.data?.data.toString() - saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) + saveDir.editText?.setText(FileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) - freeSpace.text = String.format(getString(R.string.freespace) + ": " + fileUtil.convertFileSize( - File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace + freeSpace.text = String.format(getString(R.string.freespace) + ": " + FileUtil.convertFileSize( + File(FileUtil.formatPath(downloadItem.downloadPath)).freeSpace )) } } 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 f5006aff..9c2fd92d 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 @@ -59,7 +59,6 @@ class DownloadMultipleBottomSheetDialog(private var results: List, private lateinit var listAdapter : ConfigureMultipleDownloadsAdapter private lateinit var recyclerView: RecyclerView private lateinit var behavior: BottomSheetBehavior - private lateinit var fileUtil: FileUtil private lateinit var uiUtil: UiUtil private lateinit var bottomAppBar: BottomAppBar @@ -69,8 +68,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List, downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] resultViewModel = ViewModelProvider(this)[ResultViewModel::class.java] commandTemplateViewModel = ViewModelProvider(this)[CommandTemplateViewModel::class.java] - fileUtil = FileUtil() - uiUtil = UiUtil(fileUtil) + uiUtil = UiUtil() } @SuppressLint("RestrictedApi", "NotifyDataSetChanged") @@ -291,7 +289,7 @@ class DownloadMultipleBottomSheetDialog(private var results: List, items.forEach { it.downloadPath = result.data?.data.toString() } - Toast.makeText(requireContext(), "Changed every item's download path to: ${fileUtil.formatPath(result.data!!.data.toString())}", Toast.LENGTH_LONG).show() + Toast.makeText(requireContext(), "Changed every item's download path to: ${FileUtil.formatPath(result.data!!.data.toString())}", Toast.LENGTH_LONG).show() } } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt index 2b0bb8fc..07bfcb61 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt @@ -51,7 +51,6 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr private var activity: Activity? = null private lateinit var downloadViewModel : DownloadViewModel private lateinit var resultViewModel: ResultViewModel - private lateinit var fileUtil : FileUtil private lateinit var uiUtil : UiUtil private lateinit var title : TextInputLayout @@ -72,8 +71,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java] resultViewModel = ViewModelProvider(this@DownloadVideoFragment)[ResultViewModel::class.java] - fileUtil = FileUtil() - uiUtil = UiUtil(fileUtil) + uiUtil = UiUtil() return fragmentView } @@ -114,7 +112,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr saveDir = view.findViewById(R.id.outputPath) saveDir.editText!!.setText( - fileUtil.formatPath(downloadItem.downloadPath) + FileUtil.formatPath(downloadItem.downloadPath) ) saveDir.editText!!.isFocusable = false saveDir.editText!!.isClickable = true @@ -127,8 +125,8 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr } freeSpace = view.findViewById(R.id.freespace) - val free = fileUtil.convertFileSize( - File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace) + val free = FileUtil.convertFileSize( + File(FileUtil.formatPath(downloadItem.downloadPath)).freeSpace) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free) if (free == "?") freeSpace.visibility = View.GONE @@ -148,7 +146,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr val formatCard = view.findViewById(R.id.format_card_constraintLayout) val chosenFormat = downloadItem.format - uiUtil.populateFormatCard(formatCard, chosenFormat, null) + uiUtil.populateFormatCard(formatCard, chosenFormat, downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) }) val listener = object : OnFormatClickListener { override fun onFormatClick(allFormats: List>, item: List) { downloadItem.format = item.first() @@ -162,7 +160,6 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr } formats = allFormats.first().toMutableList() uiUtil.populateFormatCard(formatCard, item.first(), item.drop(1)) - downloadItem.format.container = container.editText?.text.toString() } } formatCard.setOnClickListener{ @@ -185,15 +182,15 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr containers ) ) - downloadItem.format.container = if (containerPreference == getString(R.string.defaultValue)) "" else containerPreference!! + downloadItem.container = if (containerPreference == getString(R.string.defaultValue)) "" else containerPreference!! containerAutoCompleteTextView!!.setText( - downloadItem.format.container.ifEmpty { getString(R.string.defaultValue) }, + downloadItem.container.ifEmpty { getString(R.string.defaultValue) }, false) (container!!.editText as AutoCompleteTextView?)!!.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long -> - downloadItem.format.container = containers[index] - if (containers[index] == getString(R.string.defaultValue)) downloadItem.format.container = "" + downloadItem.container = containers[index] + if (containers[index] == getString(R.string.defaultValue)) downloadItem.container = "" } @@ -312,7 +309,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr } cut.setOnClickListener { if (parentFragmentManager.findFragmentByTag("cutVideoSheet") == null){ - val bottomSheet = CutVideoBottomSheetDialog(downloadItem, cutVideoListener) + val bottomSheet = CutVideoBottomSheetDialog(downloadItem, resultItem.urls, resultItem.chapters, cutVideoListener) bottomSheet.show(parentFragmentManager, "cutVideoSheet") } } @@ -332,17 +329,17 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr builder.setView(inputLayout) builder.setPositiveButton( getString(R.string.ok) - ) { dialog: DialogInterface?, which: Int -> + ) { _: DialogInterface?, _: Int -> downloadItem.customFileNameTemplate = editText.text.toString() } // handle the negative button of the alert dialog builder.setNegativeButton( getString(R.string.cancel) - ) { dialog: DialogInterface?, which: Int -> } + ) { _: DialogInterface?, _: Int -> } val dialog = builder.create() - editText.doOnTextChanged { text, start, before, count -> + editText.doOnTextChanged { _, _, _, _ -> dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty() } dialog.show() @@ -363,7 +360,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr subtitleLanguages.visibility = View.VISIBLE } - saveSubtitles.setOnCheckedChangeListener { compoundButton, b -> + saveSubtitles.setOnCheckedChangeListener { _, _ -> if (saveSubtitles.isChecked) subtitleLanguages.visibility = View.VISIBLE else subtitleLanguages.visibility = View.GONE downloadItem.videoPreferences.writeSubs = saveSubtitles.isChecked @@ -376,7 +373,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr } val removeAudio = view.findViewById(R.id.remove_audio) - removeAudio.setOnCheckedChangeListener { compoundButton, b -> + removeAudio.setOnCheckedChangeListener { _, _ -> downloadItem.videoPreferences.removeAudio = removeAudio.isChecked } @@ -398,11 +395,10 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr ) } downloadItem.downloadPath = result.data?.data.toString() - //downloadviewmodel.updateDownload(downloadItem) - saveDir.editText?.setText(fileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) + saveDir.editText?.setText(FileUtil.formatPath(result.data?.data.toString()), TextView.BufferType.EDITABLE) - val free = fileUtil.convertFileSize( - File(fileUtil.formatPath(downloadItem.downloadPath)).freeSpace) + val free = FileUtil.convertFileSize( + File(FileUtil.formatPath(downloadItem.downloadPath)).freeSpace) freeSpace.text = String.format( getString(R.string.freespace) + ": " + free) if (free == "?") freeSpace.visibility = View.GONE } 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 21569a56..488608b4 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 @@ -31,7 +31,6 @@ import java.util.* class FormatSelectionBottomSheetDialog(private val items: List, private var formats: List>, private val listener: OnFormatClickListener) : BottomSheetDialogFragment() { private lateinit var behavior: BottomSheetBehavior - private lateinit var fileUtil: FileUtil private lateinit var infoUtil: InfoUtil private lateinit var uiUtil: UiUtil private lateinit var sharedPreferences: SharedPreferences @@ -48,8 +47,7 @@ class FormatSelectionBottomSheetDialog(private val items: List, p override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - fileUtil = FileUtil() - uiUtil = UiUtil(fileUtil) + uiUtil = UiUtil() infoUtil = InfoUtil(requireActivity().applicationContext) formatCollection = mutableListOf() chosenFormats = listOf() @@ -116,11 +114,12 @@ class FormatSelectionBottomSheetDialog(private val items: List, p } val refreshBtn = view.findViewById