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