add no free space warning
This commit is contained in:
parent
98930837af
commit
84f13b1c86
6 changed files with 94 additions and 15 deletions
|
|
@ -22,6 +22,7 @@ import com.deniscerri.ytdl.ui.downloadcard.FormatSelectionBottomSheetDialog.Form
|
|||
import com.deniscerri.ytdl.ui.downloadcard.FormatTuple
|
||||
import com.deniscerri.ytdl.ui.downloadcard.MultipleItemFormatTuple
|
||||
import com.deniscerri.ytdl.util.Extensions.isYoutubeURL
|
||||
import com.deniscerri.ytdl.util.FileUtil
|
||||
import com.deniscerri.ytdl.util.FormatUtil
|
||||
import com.deniscerri.ytdl.util.UiUtil
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
|
@ -30,11 +31,14 @@ import kotlinx.coroutines.Job
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.text.Normalizer.Form
|
||||
import kotlin.text.compareTo
|
||||
|
||||
class FormatViewModel(private val application: Application) : AndroidViewModel(application) {
|
||||
private val downloadRepository: DownloadRepository
|
||||
|
|
@ -56,6 +60,9 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
|
|||
var sortBy = FormatSorting.valueOf(sharedPreferences.getString("format_order", "filesize")!!)
|
||||
var filterBy = MutableStateFlow(FormatCategory.valueOf(sharedPreferences.getString("format_filter", "ALL")!!))
|
||||
|
||||
private val _noFreeSpace = MutableSharedFlow<String?>()
|
||||
val noFreeSpace = _noFreeSpace.asSharedFlow()
|
||||
|
||||
init {
|
||||
downloadRepository = DownloadRepository(DBManager.getInstance(application).downloadDao)
|
||||
formats = combine(listOf(selectedItemsSharedFlow, filterBy)) { f ->
|
||||
|
|
@ -245,4 +252,19 @@ class FormatViewModel(private val application: Application) : AndroidViewModel(a
|
|||
|
||||
return formatsToReturn
|
||||
}
|
||||
|
||||
fun checkFreeSpace(size: Long, path: String) = viewModelScope.launch {
|
||||
_noFreeSpace.emit(null)
|
||||
if (size > 10L) {
|
||||
File(FileUtil.formatPath(path)).apply {
|
||||
if (size > this.freeSpace) {
|
||||
val warningTxt = application.getString(R.string.no_free_space_warning) +
|
||||
"\n" + "${application.getString(R.string.file_size)}:\t${FileUtil.convertFileSize(size)}" +
|
||||
"\n" + "${application.getString(R.string.freespace)}:\t${FileUtil.convertFileSize(this.freeSpace)}"
|
||||
|
||||
_noFreeSpace.emit(warningTxt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,8 @@ import com.google.gson.Gson
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
|
@ -227,12 +229,14 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
|||
|
||||
val formatCard = view.findViewById<MaterialCardView>(R.id.format_card_constraintLayout)
|
||||
val chosenFormat = downloadItem.format
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, chosenFormat, null, showSize = downloadItem.downloadSections.isEmpty())
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, chosenFormat, null, showSize = downloadItem.downloadSections.isEmpty())
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
val listener = object : OnFormatClickListener {
|
||||
override fun onFormatClick(formatTuple: FormatTuple) {
|
||||
formatTuple.format?.apply {
|
||||
downloadItem.format = this
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, this, null, showSize = downloadItem.downloadSections.isEmpty())
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, this, null, showSize = downloadItem.downloadSections.isEmpty())
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +257,8 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
|||
val preferredFormat = downloadViewModel.getFormat(formats, Type.audio)
|
||||
downloadItem.format = preferredFormat
|
||||
downloadItem.allFormats = formats
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, null, showSize = downloadItem.downloadSections.isEmpty())
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat, null, showSize = downloadItem.downloadSections.isEmpty())
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
}
|
||||
}
|
||||
formatCard.setOnClickListener{
|
||||
|
|
@ -359,7 +364,8 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
|||
},
|
||||
cutValueChanged = {
|
||||
downloadItem.downloadSections = it
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, showSize = downloadItem.downloadSections.isEmpty())
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, showSize = downloadItem.downloadSections.isEmpty())
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
|
||||
if (it.isNotBlank()){
|
||||
downloadItem.customFileNameTemplate = downloadItem.customFileNameTemplate.applyFilenameTemplateForCuts()
|
||||
|
|
@ -392,6 +398,16 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
formatViewModel.noFreeSpace.collectLatest {
|
||||
if (it != null) {
|
||||
val snack = Snackbar.make(view, it, Snackbar.LENGTH_INDEFINITE)
|
||||
snack.setTextMaxLines(10)
|
||||
snack.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
|
|
@ -400,7 +416,8 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
|||
formats.find { it.format_id == formatID }?.apply {
|
||||
downloadItem.format = this
|
||||
val formatCard = requireView().findViewById<MaterialCardView>(R.id.format_card_constraintLayout)
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, listOf(), showSize = downloadItem.downloadSections.isEmpty())
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, listOf(), showSize = downloadItem.downloadSections.isEmpty())
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import android.graphics.Canvas
|
|||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
|
|
@ -71,6 +72,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.math.abs
|
||||
|
|
@ -196,6 +198,16 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
|||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
formatViewModel.noFreeSpace.collectLatest {
|
||||
if (it != null) {
|
||||
val snack = Snackbar.make(view, it, Snackbar.LENGTH_INDEFINITE)
|
||||
snack.setTextMaxLines(10)
|
||||
snack.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
downloadViewModel.processingDownloads.collectLatest { items ->
|
||||
processingItemsCount = items.size
|
||||
|
|
@ -1013,10 +1025,12 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
|||
}
|
||||
|
||||
if (fileSizes.all { it > 5L }){
|
||||
val size = FileUtil.convertFileSize(fileSizes.sum())
|
||||
val filesizeRaw = fileSizes.sum()
|
||||
val size = FileUtil.convertFileSize(filesizeRaw)
|
||||
itemsFileSize = fileSizes.sum()
|
||||
filesize.isVisible = size != "?" && !listAdapter.isCheckingItems()
|
||||
filesize.text = "${getString(R.string.file_size)}: >~ $size"
|
||||
formatViewModel.checkFreeSpace(filesizeRaw, Environment.getExternalStorageDirectory().path)
|
||||
}else{
|
||||
filesize.visibility = View.GONE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ import com.google.gson.Gson
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
|
@ -244,14 +246,15 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
val formatCard = view.findViewById<MaterialCardView>(R.id.format_card_constraintLayout)
|
||||
|
||||
val chosenFormat = downloadItem.format
|
||||
|
||||
UiUtil.populateFormatCard(
|
||||
val chosenAudioFormats = downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) }
|
||||
val filesize = UiUtil.populateFormatCard(
|
||||
requireContext(),
|
||||
formatCard,
|
||||
chosenFormat,
|
||||
downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) },
|
||||
chosenAudioFormats,
|
||||
showSize = downloadItem.downloadSections.isEmpty()
|
||||
)
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
|
||||
val listener = object : OnFormatClickListener {
|
||||
override fun onFormatClick(formatTuple: FormatTuple) {
|
||||
|
|
@ -262,10 +265,11 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
formatTuple.audioFormats?.map { it.format_id }?.let {
|
||||
downloadItem.videoPreferences.audioFormatIDs.addAll(it)
|
||||
}
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format,
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format,
|
||||
if(downloadItem.videoPreferences.removeAudio) listOf() else formatTuple.audioFormats,
|
||||
showSize = downloadItem.downloadSections.isEmpty()
|
||||
)
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
}
|
||||
|
||||
override fun onFormatsUpdated(allFormats: List<Format>) {
|
||||
|
|
@ -287,10 +291,11 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
val preferredAudioFormats = downloadViewModel.getPreferredAudioFormats(formats)
|
||||
downloadItem.format = preferredFormat
|
||||
downloadItem.allFormats = formats
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat,
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, preferredFormat,
|
||||
if(downloadItem.videoPreferences.removeAudio) listOf() else formats.filter { preferredAudioFormats.contains(it.format_id) },
|
||||
showSize = downloadItem.downloadSections.isEmpty()
|
||||
)
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -399,7 +404,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
},
|
||||
cutValueChanged = {
|
||||
downloadItem.downloadSections = it
|
||||
UiUtil.populateFormatCard(
|
||||
val filesize = UiUtil.populateFormatCard(
|
||||
requireContext(),
|
||||
formatCard,
|
||||
downloadItem.format,
|
||||
|
|
@ -407,6 +412,7 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
else downloadItem.allFormats.filter { f -> downloadItem.videoPreferences.audioFormatIDs.contains(f.format_id) },
|
||||
showSize = downloadItem.downloadSections.isEmpty()
|
||||
)
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
|
||||
if (it.isNotBlank()){
|
||||
downloadItem.customFileNameTemplate = downloadItem.customFileNameTemplate.applyFilenameTemplateForCuts()
|
||||
|
|
@ -428,13 +434,14 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
},
|
||||
removeAudioClicked = {
|
||||
downloadItem.videoPreferences.removeAudio = it
|
||||
UiUtil.populateFormatCard(
|
||||
val filesize = UiUtil.populateFormatCard(
|
||||
requireContext(),
|
||||
formatCard,
|
||||
downloadItem.format,
|
||||
if (it) listOf() else downloadItem.allFormats.filter { downloadItem.videoPreferences.audioFormatIDs.contains(it.format_id) },
|
||||
showSize = downloadItem.downloadSections.isEmpty()
|
||||
)
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
},
|
||||
recodeVideoClicked = {
|
||||
downloadItem.videoPreferences.recodeVideo = it
|
||||
|
|
@ -479,6 +486,16 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
formatViewModel.noFreeSpace.collectLatest {
|
||||
if (it != null) {
|
||||
val snack = Snackbar.make(view, it, Snackbar.LENGTH_INDEFINITE)
|
||||
snack.setTextMaxLines(10)
|
||||
snack.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateTitleAuthor(t: String, a: String){
|
||||
|
|
@ -510,10 +527,11 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
downloadItem.videoPreferences.audioFormatIDs.clear()
|
||||
downloadItem.videoPreferences.audioFormatIDs.addAll(arrayListOf(format.format_id))
|
||||
val formatCard = requireView().findViewById<MaterialCardView>(R.id.format_card_constraintLayout)
|
||||
UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format,
|
||||
val filesize = UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format,
|
||||
if(downloadItem.videoPreferences.removeAudio) listOf() else listOf(format),
|
||||
showSize = downloadItem.downloadSections.isEmpty()
|
||||
)
|
||||
formatViewModel.checkFreeSpace(filesize, downloadItem.downloadPath)
|
||||
}
|
||||
|
||||
private var pathResultLauncher = registerForActivityResult(
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ import java.util.Locale
|
|||
|
||||
object UiUtil {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun populateFormatCard(context: Context, formatCard : MaterialCardView, chosenFormat: Format, audioFormats: List<Format>? = null, showSize: Boolean = true){
|
||||
//return filesize
|
||||
fun populateFormatCard(context: Context, formatCard : MaterialCardView, chosenFormat: Format, audioFormats: List<Format>? = null, showSize: Boolean = true) : Long {
|
||||
var formatNote = chosenFormat.format_note
|
||||
if (formatNote.isEmpty()) formatNote = context.getString(R.string.defaultValue)
|
||||
else if (formatNote == "best") formatNote = context.getString(R.string.best_quality)
|
||||
|
|
@ -185,6 +186,12 @@ object UiUtil {
|
|||
}
|
||||
}
|
||||
|
||||
if (showSize) {
|
||||
return filesize
|
||||
}else {
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun populateCommandCard(card: MaterialCardView, item: CommandTemplate){
|
||||
|
|
|
|||
|
|
@ -485,4 +485,5 @@
|
|||
<string name="no_keep_subs_summary">When using both Embed Subtitles and Write Subtitles, don\'t keep the subtitle files after embedding</string>
|
||||
<string name="video_compatible">Compatible Video</string>
|
||||
<string name="video_compatible_summary">Recodes the video making it compatible with other apps</string>
|
||||
<string name="no_free_space_warning">There is no free space for this configuration.</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in a new issue