mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 00:10:32 +05:30
feat: support for duration inputs in submit segment dialog
This commit is contained in:
parent
007dfbaf82
commit
3b0ef233e7
@ -126,6 +126,7 @@ dependencies {
|
|||||||
implementation(libs.kotlinx.serialization)
|
implementation(libs.kotlinx.serialization)
|
||||||
implementation(libs.kotlinx.datetime)
|
implementation(libs.kotlinx.datetime)
|
||||||
implementation(libs.kotlinx.serialization.retrofit)
|
implementation(libs.kotlinx.serialization.retrofit)
|
||||||
|
testImplementation(libs.testng)
|
||||||
|
|
||||||
/* Cronet and Coil */
|
/* Cronet and Coil */
|
||||||
coreLibraryDesugaring(libs.desugaring)
|
coreLibraryDesugaring(libs.desugaring)
|
||||||
|
@ -18,6 +18,7 @@ import com.github.libretube.extensions.TAG
|
|||||||
import com.github.libretube.extensions.toastFromMainDispatcher
|
import com.github.libretube.extensions.toastFromMainDispatcher
|
||||||
import com.github.libretube.helpers.PreferenceHelper
|
import com.github.libretube.helpers.PreferenceHelper
|
||||||
import com.github.libretube.util.TextUtils
|
import com.github.libretube.util.TextUtils
|
||||||
|
import com.github.libretube.util.TextUtils.parseDurationString
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -52,7 +53,7 @@ class SubmitSegmentDialog : DialogFragment() {
|
|||||||
lifecycleScope.launch { voteForSegment() }
|
lifecycleScope.launch { voteForSegment() }
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.startTime.setText((currentPosition.toFloat() / 1000).toString())
|
binding.startTime.setText(DateUtils.formatElapsedTime(((currentPosition.toFloat() / 1000).toLong())))
|
||||||
|
|
||||||
binding.segmentCategory.items = resources.getStringArray(R.array.sponsorBlockSegmentNames).toList()
|
binding.segmentCategory.items = resources.getStringArray(R.array.sponsorBlockSegmentNames).toList()
|
||||||
|
|
||||||
@ -72,8 +73,9 @@ class SubmitSegmentDialog : DialogFragment() {
|
|||||||
|
|
||||||
requireDialog().hide()
|
requireDialog().hide()
|
||||||
|
|
||||||
val startTime = binding.startTime.text.toString().toFloatOrNull()
|
val startTime = binding.startTime.text.toString().parseDurationString()
|
||||||
var endTime = binding.endTime.text.toString().toFloatOrNull()
|
var endTime = binding.endTime.text.toString().parseDurationString()
|
||||||
|
|
||||||
if (endTime == null || startTime == null || startTime > endTime) {
|
if (endTime == null || startTime == null || startTime > endTime) {
|
||||||
context.toastFromMainDispatcher(R.string.sb_invalid_segment)
|
context.toastFromMainDispatcher(R.string.sb_invalid_segment)
|
||||||
return
|
return
|
||||||
|
@ -7,6 +7,7 @@ import android.os.Build
|
|||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import com.github.libretube.BuildConfig
|
import com.github.libretube.BuildConfig
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
|
import com.google.common.math.IntMath.pow
|
||||||
import kotlinx.datetime.toJavaLocalDate
|
import kotlinx.datetime.toJavaLocalDate
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
@ -49,8 +50,44 @@ object TextUtils {
|
|||||||
* Get time in seconds from a YouTube video link.
|
* Get time in seconds from a YouTube video link.
|
||||||
* @return Time in seconds
|
* @return Time in seconds
|
||||||
*/
|
*/
|
||||||
fun String.toTimeInSeconds(): Long? {
|
fun String.toTimeInSeconds(): Long? = parseTimeString(this)?.toLong()
|
||||||
return toLongOrNull() ?: Duration.parseOrNull(this)?.inWholeSeconds
|
|
||||||
|
fun String.parseDurationString(): Float? = parseTimeString(this)
|
||||||
|
|
||||||
|
private fun parseTimeString(timeString: String): Float? {
|
||||||
|
if (timeString.all { it.isDigit() }) return timeString.toLongOrNull()?.toFloat()
|
||||||
|
|
||||||
|
if (timeString.all { it.isDigit() || ",.:".contains(it) }) {
|
||||||
|
var secondsTotal = 0
|
||||||
|
var secondsScoped = 0
|
||||||
|
|
||||||
|
var milliseconds = 0
|
||||||
|
var inMillis = false
|
||||||
|
|
||||||
|
for (char in timeString) {
|
||||||
|
if (inMillis) {
|
||||||
|
if (!char.isDigit()) break
|
||||||
|
|
||||||
|
milliseconds *= 10
|
||||||
|
milliseconds += char.digitToInt()
|
||||||
|
} else if (char.isDigit()) {
|
||||||
|
secondsScoped *= 10
|
||||||
|
secondsScoped += char.digitToInt()
|
||||||
|
} else if (char == ':') {
|
||||||
|
secondsTotal += secondsScoped * 60
|
||||||
|
secondsScoped = 0
|
||||||
|
} else if (",.".contains(char)) {
|
||||||
|
secondsTotal += secondsScoped
|
||||||
|
secondsScoped = 0
|
||||||
|
inMillis = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val millisDecimal = milliseconds.toFloat() / pow(10, milliseconds.toString().length)
|
||||||
|
return secondsTotal.toFloat() + millisDecimal
|
||||||
|
}
|
||||||
|
|
||||||
|
return Duration.parseOrNull(timeString)?.inWholeMilliseconds?.toFloat()?.div(1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
android:id="@+id/start_time"
|
android:id="@+id/start_time"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="numberDecimal" />
|
android:digits="0123456789.:"
|
||||||
|
android:inputType="number" />
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
16
app/src/test/java/com/github/libretube/TextParserTest.kt
Normal file
16
app/src/test/java/com/github/libretube/TextParserTest.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package com.github.libretube
|
||||||
|
|
||||||
|
import com.github.libretube.util.TextUtils.parseDurationString
|
||||||
|
import com.github.libretube.util.TextUtils.toTimeInSeconds
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
|
||||||
|
class TextParserTest {
|
||||||
|
@Test
|
||||||
|
fun testTimeParser() {
|
||||||
|
assertEquals(15L * 60 + 20, "15m 20s".toTimeInSeconds())
|
||||||
|
assertEquals(1520L, "1520".toTimeInSeconds())
|
||||||
|
assertEquals(15L * 60 + 20, "15:20.25".toTimeInSeconds())
|
||||||
|
assertEquals(15f * 60 + 20 + 0.25f, "15:20.25".parseDurationString())
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
appcompat = "1.7.0"
|
appcompat = "1.7.0"
|
||||||
core = "1.13.1"
|
core = "1.13.1"
|
||||||
gradle = "8.5.0"
|
gradle = "8.5.0"
|
||||||
|
junit = "4.13.2"
|
||||||
kotlin = "1.9.24"
|
kotlin = "1.9.24"
|
||||||
ksp = "1.9.24-1.0.20"
|
ksp = "1.9.24-1.0.20"
|
||||||
lifecycle = "2.8.2"
|
lifecycle = "2.8.2"
|
||||||
@ -34,6 +35,7 @@ profileinstaller = "1.3.1"
|
|||||||
paging = "3.3.0"
|
paging = "3.3.0"
|
||||||
collection = "1.4.0"
|
collection = "1.4.0"
|
||||||
swiperefreshlayout = "1.1.0"
|
swiperefreshlayout = "1.1.0"
|
||||||
|
testng = "6.9.6"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-activity = { group = "androidx.activity", name = "activity-ktx", version.ref = "activity" }
|
androidx-activity = { group = "androidx.activity", name = "activity-ktx", version.ref = "activity" }
|
||||||
@ -42,6 +44,7 @@ androidx-core = { group = "androidx.core", name = "core", version.ref = "core" }
|
|||||||
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
androidx-fragment = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragment" }
|
androidx-fragment = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragment" }
|
||||||
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
|
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
|
||||||
|
junit = { module = "junit:junit", version.ref = "junit" }
|
||||||
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
|
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
|
||||||
kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
|
kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
|
||||||
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptor" }
|
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptor" }
|
||||||
@ -81,6 +84,7 @@ androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profi
|
|||||||
androidx-paging = { group = "androidx.paging", name = "paging-runtime-ktx", version.ref = "paging" }
|
androidx-paging = { group = "androidx.paging", name = "paging-runtime-ktx", version.ref = "paging" }
|
||||||
androidx-collection = { group = "androidx.collection", name = "collection", version.ref = "collection" }
|
androidx-collection = { group = "androidx.collection", name = "collection", version.ref = "collection" }
|
||||||
androidx-swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
|
androidx-swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
|
||||||
|
testng = { group = "org.testng", name = "testng", version.ref = "testng" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
androidTest = { id = "com.android.test", version.ref = "gradle" }
|
androidTest = { id = "com.android.test", version.ref = "gradle" }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user