more features

pull/640/head
deniscerri 2 years ago
parent e1c99e2647
commit 0df5a9e194
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -3,8 +3,9 @@ plugins {
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1'
id 'org.jetbrains.kotlin.android'
id 'com.google.devtools.ksp'
id "org.jetbrains.kotlin.plugin.serialization" version "1.8.10"
id "org.jetbrains.kotlin.plugin.parcelize" version "1.8.10"
id "org.jetbrains.kotlin.plugin.serialization" version "2.0.21"
id "org.jetbrains.kotlin.plugin.parcelize" version "2.0.21"
id "org.jetbrains.kotlin.plugin.compose" version "2.0.21"
}
def properties = new Properties()
@ -101,6 +102,7 @@ android {
buildFeatures {
viewBinding true
buildConfig true
compose true
}
@ -195,7 +197,7 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0'
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.6"
implementation "com.github.Irineu333:Highlight-KT:1.0.4"
implementation "com.neoutils.highlight:highlight-view:2.2.0"
// For media playback using ExoPlayer
implementation("androidx.media3:media3-exoplayer:$media3_version")

@ -228,6 +228,9 @@ interface DownloadDao {
@Query("UPDATE downloads set status=:status where id=:id")
suspend fun setStatus(id: Long, status: String)
@Query("UPDATE downloads set status=:status where id IN (:ids)")
suspend fun setStatusMultiple(ids: List<Long>, status: String)
@Update
suspend fun updateWithoutUpsert(item: DownloadItem)

@ -123,6 +123,10 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
downloadDao.setStatus(id, status.toString())
}
suspend fun setDownloadStatusMultiple(ids: List<Long>, status: Status) {
downloadDao.setStatusMultiple(ids, status.toString())
}
fun getItemByID(id: Long) : DownloadItem {
return downloadDao.getDownloadById(id)
}

@ -1268,9 +1268,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
}
delay(1000)
isPausingResuming = false
activeDownloadsList.forEach {
repository.setDownloadStatus(it.id, DownloadRepository.Status.Paused)
}
repository.setDownloadStatusMultiple(activeDownloadsList.map { it.id }, DownloadRepository.Status.Paused)
pausedAllDownloads.value = PausedAllDownloadsState.RESUME
}

@ -71,6 +71,10 @@ class TemplatesAdapter(onItemClickListener: OnItemClickListener, activity: Activ
text = finalText
}
card.findViewById<TextView>(R.id.dataFetchingExtraCommands).apply {
isVisible = item.useAsExtraCommandDataFetching
}
card.findViewById<TextView>(R.id.preferredTemplate).apply {
val preferred = sharedPreferences.getString("preferred_command_template", "")
isVisible = preferred == item.content
@ -165,7 +169,8 @@ class TemplatesAdapter(onItemClickListener: OnItemClickListener, activity: Activ
oldItem.content == newItem.content &&
oldItem.useAsExtraCommand == newItem.useAsExtraCommand &&
oldItem.useAsExtraCommandAudio == newItem.useAsExtraCommandAudio &&
oldItem.useAsExtraCommandVideo == newItem.useAsExtraCommandVideo
oldItem.useAsExtraCommandVideo == newItem.useAsExtraCommandVideo &&
oldItem.useAsExtraCommandDataFetching == newItem.useAsExtraCommandDataFetching
}
}
}

@ -46,11 +46,12 @@ import com.deniscerri.ytdl.database.repository.ObserveSourcesRepository.EveryCat
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.tabs.TabLayout
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.neo.highlight.core.Highlight
import com.neo.highlight.util.listener.HighlightTextWatcher
import com.neo.highlight.util.scheme.ColorScheme
import com.neoutils.highlight.core.Highlight
import com.neoutils.highlight.core.scheme.TextColorScheme
import com.neoutils.highlight.core.util.Match
import com.neoutils.highlight.core.util.UiColor
import com.neoutils.highlight.view.extension.toSpannedString
import com.neoutils.highlight.view.text.HighlightTextWatcher
import com.squareup.picasso.Picasso
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@ -72,28 +73,27 @@ object Extensions {
return (metrics.density * px).toInt()
}
private var textHighLightSchemes = listOf(
ColorScheme(Pattern.compile("([\"'])(?:\\\\1|.)*?\\1"), Color.parseColor("#FC8500")),
ColorScheme(Pattern.compile("yt-dlp"), Color.parseColor("#77eb09")),
ColorScheme(Pattern.compile("(https?://(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?://(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})"), Color.parseColor("#b5942f")),
ColorScheme(Pattern.compile("\\d+(\\.\\d)?%"), Color.parseColor("#43a564"))
private var textHighlightSchemes = listOf(
TextColorScheme(regex = "([\"'])(?:\\\\1|.)*?\\1".toRegex(), match = Match.fully(UiColor.Hex("#FC8500"))),
TextColorScheme(regex = "yt-dlp".toRegex(), match = Match.fully(UiColor.Hex("#77eb09"))),
TextColorScheme(regex = "(https?://(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?://(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})".toRegex(), match = Match.fully(UiColor.Hex("#b5942f"))),
TextColorScheme(regex = "\\d+(\\.\\d)?%".toRegex(), match = Match.fully(UiColor.Hex("#43a564"))),
)
fun View.enableTextHighlight(){
if (this is EditText || this is TextView){
//init syntax highlighter
val highlight = Highlight()
val highlightWatcher = HighlightTextWatcher()
highlight.addScheme(
*textHighLightSchemes.map { it }.toTypedArray()
)
highlightWatcher.addScheme(
*textHighLightSchemes.map { it }.toTypedArray()
)
highlight.setSpan(this as TextView)
this.addTextChangedListener(highlightWatcher)
val highlight = Highlight(textHighlightSchemes)
val highlightWatcher = HighlightTextWatcher(highlight)
if (this is EditText) {
this.addTextChangedListener(highlightWatcher)
this.setText(highlight.toSpannedString(this.text.toString()))
}else if (this is TextView) {
this.addTextChangedListener(highlightWatcher)
this.text = highlight.toSpannedString(this.text.toString())
}
}
}

@ -108,7 +108,7 @@ object FileUtil {
if (it.isDirectory && it.absolutePath == originDir.absolutePath) return@forEach
var destFile: DocumentFile
try {
if (it.name.matches("(^config.*.\\.txt\$)|(rList)|(.*.part-Frag.*)|(.*.live_chat)|(.*.ytdl)".toRegex())){
if (it.name.matches("(^config.*.\\.txt\$)|(rList)|(.*.part-Frag.*)|(.*.live_chat)|(.*.ytdl)|(.*.info.json)".toRegex())){
return@forEach
}

@ -725,6 +725,18 @@ class YTDLPUtil(private val context: Context) {
request.addOption("--download-archive", FileUtil.getDownloadArchivePath(context))
}
if (!sharedPreferences.getBoolean("disable_write_info_json", false)) {
val infoJsonFile = downDir.walkTopDown().firstOrNull { it.name == "${downloadItem.id}.info.json" }
//ignore info file if its older than 5 hours. puny measure to prevent expired formats in some cases
if (infoJsonFile == null || System.currentTimeMillis() - infoJsonFile.lastModified() > (1000 * 60 * 60 * 5)) {
request.addOption("--write-info-json")
request.addOption("--no-clean-info-json")
request.addOption("-o", "infojson:${downloadItem.id}")
}else {
request.addOption("--load-info-json", infoJsonFile.absolutePath)
}
}
val preferredAudioCodec = sharedPreferences.getString("audio_codec", "")!!
val aCodecPrefIndex = context.getStringArray(R.array.audio_codec_values).indexOf(preferredAudioCodec)
val aCodecPref = runCatching { context.getStringArray(R.array.audio_codec_values_ytdlp)[aCodecPrefIndex] }.getOrElse { "" }

@ -41,64 +41,75 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
<HorizontalScrollView
android:layout_width="wrap_content"
android:scrollbars="none"
<com.google.android.material.chip.ChipGroup
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/content"
app:layout_constraintHorizontal_bias="0.0"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
<TextView
android:id="@+id/preferredTemplate"
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="@+id/preferredTemplate"
style="@style/Widget.Material3.FloatingActionButton.Large.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorPrimaryContainer"
android:clickable="false"
android:gravity="center"
android:visibility="gone"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
android:text="@string/preferred_command_template"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
android:layout_height="wrap_content"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorPrimaryContainer"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
android:text="@string/preferred_command_template"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/useInExtraCommands"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginEnd="5dp"
android:text="@string/extra_command"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondaryContainer"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/useInExtraCommands"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/extra_command"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorSecondaryContainer"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<TextView
android:id="@+id/dataFetchingExtraCommands"
style="@style/Widget.Material3.FloatingActionButton.Large.Tertiary"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/data_fetching_extra_command"
android:background="@drawable/rounded_corner"
android:backgroundTint="?attr/colorTertiaryContainer"
android:clickable="false"
android:gravity="center"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textSize="12sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</HorizontalScrollView>
</com.google.android.material.chip.ChipGroup>

@ -437,4 +437,6 @@
<string name="data_fetching_extra_command">Data Fetching Extra Command</string>
<string name="thumbnail">Thumbnail</string>
<string name="data_fetching_extra_command_summary">Enable command templates to be used for data fetching as extra commands</string>
<string name="disable_write_info_json">Disable Write Info Json</string>
<string name="disable_write_info_json_summary">(Not Recommended) Every time you restart / resume the download, yt-dlp will re-download json data from the servers.</string>
</resources>

@ -33,4 +33,12 @@
android:title="@string/data_fetching_extra_command" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/downloading">
<SwitchPreferenceCompat
android:icon="@drawable/if_file_rename"
android:key="disable_write_info_json"
android:summary="@string/disable_write_info_json_summary"
android:title="@string/disable_write_info_json" />
</PreferenceCategory>
</PreferenceScreen>

@ -41,11 +41,11 @@ buildscript {
plugins {
id 'com.android.application' version '8.5.2' apply false
id 'com.android.library' version '8.5.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.8.10" apply false
id "org.jetbrains.kotlin.plugin.parcelize" version "1.8.10" apply false
id 'org.jetbrains.kotlin.android' version '2.0.21' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "2.0.21" apply false
id "org.jetbrains.kotlin.plugin.parcelize" version "2.0.21" apply false
id 'com.android.test' version '8.5.2' apply false
id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false
id 'com.google.devtools.ksp' version '2.0.21-1.0.28' apply false
}
tasks.register('clean', Delete) {

@ -11,9 +11,9 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Sun Oct 08 20:53:48 CEST 2023
android.defaults.buildfeatures.buildconfig=true
android.enableJetifier=true
android.nonFinalResIds=false
android.nonTransitiveRClass=false
android.suppressUnsupportedCompileSdk=35
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1024M" -Dfile.encoding\=UTF-8

Loading…
Cancel
Save