diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 08d6292..c9fe8c9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,8 +17,8 @@ android { applicationId = "com.donut.mixfile" minSdk = 26 targetSdk = 36 - versionCode = 152 - versionName = "2.0.7" + versionCode = 153 + versionName = "2.0.8" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -70,7 +70,7 @@ android { dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0") - implementation("com.github.InvertGeek:mixfile-core:2.0.7") + implementation("com.github.InvertGeek:mixfile-core:2.0.8") implementation("androidx.compose.material:material-icons-extended:1.7.8") implementation("com.tencent:mmkv:1.3.14") implementation("net.engawapg.lib:zoomable:1.6.1") diff --git a/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt b/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt index 89f99ec..faf6616 100644 --- a/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt +++ b/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt @@ -25,11 +25,7 @@ import androidx.compose.material3.Slider import androidx.compose.material3.SliderDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale @@ -40,7 +36,6 @@ import androidx.compose.ui.unit.sp import androidx.media3.exoplayer.ExoPlayer import com.donut.mixfile.ui.component.common.MixDialogBuilder import com.donut.mixfile.ui.component.common.SingleSelectItemList -import kotlinx.coroutines.delay @OptIn(ExperimentalMaterial3Api::class) @@ -50,8 +45,8 @@ fun BottomControl( modifier: Modifier, player: ExoPlayer, videos: List, - onPlayTimeChange: () -> Unit, - onTrackTimeChange: () -> Unit, + progress: Float, + onTrackTimeChange: (Float) -> Unit, ) { AnimatedVisibility( visible = visible, @@ -70,24 +65,13 @@ fun BottomControl( .padding(5.dp), ) { - var progress by remember { mutableFloatStateOf(0f) } - LaunchedEffect(player) { - while (true) { - progress = if (player.duration > 0) { - player.currentPosition.toFloat() / player.duration - } else 0f - onPlayTimeChange() - delay(1000) - } - } Slider( value = progress, onValueChange = { newValue -> - progress = newValue player.pause() player.seekTo((player.duration * newValue).toLong()) - onTrackTimeChange() + onTrackTimeChange(newValue) }, onValueChangeFinished = { player.play() diff --git a/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerView.kt b/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerView.kt index 9df4da0..e07e077 100644 --- a/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerView.kt +++ b/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerView.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.remember @@ -177,13 +178,13 @@ fun VideoPlayerScreen( controlsVisible.set(true) } + var progress by remember { mutableFloatStateOf(0f) } - BottomControl( - visible = controlsVisible.get, - modifier = Modifier.align(Alignment.BottomCenter), - player = player, - videos = videoUris, - onPlayTimeChange = { + LaunchedEffect(player) { + while (true) { + progress = if (player.duration > 0) { + player.currentPosition.toFloat() / player.duration + } else 0f playHistory = playHistory.filter { !it.hash.contentEquals(hash) }.toMutableList().apply { val history = @@ -193,8 +194,20 @@ fun VideoPlayerScreen( removeAt(lastIndex) } } - }, + delay(1000) + } + + } + + + BottomControl( + visible = controlsVisible.get, + modifier = Modifier.align(Alignment.BottomCenter), + player = player, + videos = videoUris, + progress = progress, onTrackTimeChange = { + progress = it controlsVisible.set(true) } ) diff --git a/app/src/main/java/com/donut/mixfile/util/file/FileDataLog.kt b/app/src/main/java/com/donut/mixfile/util/file/FileDataLog.kt index f8a9bc0..11e4c3b 100644 --- a/app/src/main/java/com/donut/mixfile/util/file/FileDataLog.kt +++ b/app/src/main/java/com/donut/mixfile/util/file/FileDataLog.kt @@ -3,10 +3,15 @@ package com.donut.mixfile.util.file import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.TextFieldValue import com.donut.mixfile.server.core.objects.FileDataLog import com.donut.mixfile.server.core.objects.MixShareInfo import com.donut.mixfile.server.core.utils.resolveMixShareInfo @@ -42,26 +47,43 @@ fun FileDataLog.updateDataList( fun FileDataLog.rename(callback: (FileDataLog) -> Unit = {}) { var shareInfo = resolveMixShareInfo(shareInfoData) ?: return MixDialogBuilder("重命名文件").apply { - var name by mutableStateOf(shareInfo.fileName) + var value by mutableStateOf(TextFieldValue(shareInfo.fileName)) + val focusRequester = FocusRequester() setContent { + + LaunchedEffect(Unit) { + focusRequester.requestFocus() + val text = value.text + val dotIndex = text.lastIndexOf('.') + val end = if (dotIndex == -1) text.length else dotIndex + + value = value.copy( + selection = TextRange(0, end) + ) + } + OutlinedTextField( - value = name, + value = value, onValueChange = { - name = it + value = it }, - modifier = Modifier.fillMaxWidth(), label = { + modifier = Modifier + .focusRequester(focusRequester) + .fillMaxWidth(), + label = { Text(text = "输入文件名") }, maxLines = 1 ) + } setDefaultNegative() setPositiveButton("确定") { - if (name.isEmpty()) { + if (value.text.isEmpty()) { showToast("文件名不能为空!") return@setPositiveButton } - val sanitizedName = name.sanitizeFileName() + val sanitizedName = value.text.sanitizeFileName() shareInfo = shareInfo.copy(fileName = sanitizedName) val renamedLog = copy( name = sanitizedName, diff --git a/app/src/test/java/com/donut/mixfile/ExampleUnitTest.kt b/app/src/test/java/com/donut/mixfile/ExampleUnitTest.kt index 0eefbfc..5342cb7 100644 --- a/app/src/test/java/com/donut/mixfile/ExampleUnitTest.kt +++ b/app/src/test/java/com/donut/mixfile/ExampleUnitTest.kt @@ -1,7 +1,6 @@ package com.donut.mixfile import org.junit.Test -import org.mozilla.javascript.Context /** @@ -15,14 +14,7 @@ class ExampleUnitTest { @Test fun main() { - val context = Context.enter() - try { - val scope = context.initStandardObjects() - val result = context.evaluateString(scope, "1 + 2", "script", 1, null) - println("结果: $result") // 输出 3 - } finally { - Context.exit() - } + }