mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-28 07:50:31 +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.datetime)
|
||||
implementation(libs.kotlinx.serialization.retrofit)
|
||||
testImplementation(libs.testng)
|
||||
|
||||
/* Cronet and Coil */
|
||||
coreLibraryDesugaring(libs.desugaring)
|
||||
|
@ -18,6 +18,7 @@ import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.toastFromMainDispatcher
|
||||
import com.github.libretube.helpers.PreferenceHelper
|
||||
import com.github.libretube.util.TextUtils
|
||||
import com.github.libretube.util.TextUtils.parseDurationString
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@ -52,7 +53,7 @@ class SubmitSegmentDialog : DialogFragment() {
|
||||
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()
|
||||
|
||||
@ -72,8 +73,9 @@ class SubmitSegmentDialog : DialogFragment() {
|
||||
|
||||
requireDialog().hide()
|
||||
|
||||
val startTime = binding.startTime.text.toString().toFloatOrNull()
|
||||
var endTime = binding.endTime.text.toString().toFloatOrNull()
|
||||
val startTime = binding.startTime.text.toString().parseDurationString()
|
||||
var endTime = binding.endTime.text.toString().parseDurationString()
|
||||
|
||||
if (endTime == null || startTime == null || startTime > endTime) {
|
||||
context.toastFromMainDispatcher(R.string.sb_invalid_segment)
|
||||
return
|
||||
|
@ -7,6 +7,7 @@ import android.os.Build
|
||||
import android.text.format.DateUtils
|
||||
import com.github.libretube.BuildConfig
|
||||
import com.github.libretube.R
|
||||
import com.google.common.math.IntMath.pow
|
||||
import kotlinx.datetime.toJavaLocalDate
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
@ -49,8 +50,44 @@ object TextUtils {
|
||||
* Get time in seconds from a YouTube video link.
|
||||
* @return Time in seconds
|
||||
*/
|
||||
fun String.toTimeInSeconds(): Long? {
|
||||
return toLongOrNull() ?: Duration.parseOrNull(this)?.inWholeSeconds
|
||||
fun String.toTimeInSeconds(): Long? = parseTimeString(this)?.toLong()
|
||||
|
||||
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:layout_width="match_parent"
|
||||
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
|
||||
|
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"
|
||||
core = "1.13.1"
|
||||
gradle = "8.5.0"
|
||||
junit = "4.13.2"
|
||||
kotlin = "1.9.24"
|
||||
ksp = "1.9.24-1.0.20"
|
||||
lifecycle = "2.8.2"
|
||||
@ -34,6 +35,7 @@ profileinstaller = "1.3.1"
|
||||
paging = "3.3.0"
|
||||
collection = "1.4.0"
|
||||
swiperefreshlayout = "1.1.0"
|
||||
testng = "6.9.6"
|
||||
|
||||
[libraries]
|
||||
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-fragment = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragment" }
|
||||
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-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
|
||||
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-collection = { group = "androidx.collection", name = "collection", version.ref = "collection" }
|
||||
androidx-swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
|
||||
testng = { group = "org.testng", name = "testng", version.ref = "testng" }
|
||||
|
||||
[plugins]
|
||||
androidTest = { id = "com.android.test", version.ref = "gradle" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user