Skip to content

Commit

Permalink
add: scroll lyrics change position and can select text
Browse files Browse the repository at this point in the history
  • Loading branch information
ZTFtrue committed Jan 29, 2024
1 parent eca52da commit 46d4af4
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 64 deletions.
7 changes: 1 addition & 6 deletions app/src/main/java/com/ztftrue/music/MusicViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,7 @@ class MusicViewModel : ViewModel() {
hasTime = LyricsType.VTT
currentCaptionList.addAll(readCaptions(File("$path.vtt"), LyricsType.VTT))
} else {
currentCaptionList.add(
Caption(
text = "No Lyrics, Double click to import lyrics",
0,
)
)

}

}
Expand Down
125 changes: 70 additions & 55 deletions app/src/main/java/com/ztftrue/music/ui/play/LyricsView.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.ztftrue.music.ui.play

import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
Expand All @@ -20,15 +22,18 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.media3.common.util.UnstableApi
import com.ztftrue.music.MainActivity
import com.ztftrue.music.MusicViewModel
import com.ztftrue.music.utils.Caption
import com.ztftrue.music.utils.CustomTextToolbar
import com.ztftrue.music.utils.LyricsType
import com.ztftrue.music.utils.Utils.openFile
import com.ztftrue.music.utils.Utils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
Expand All @@ -45,7 +50,7 @@ fun LyricsView(
val context = LocalContext.current
val listState = rememberLazyListState()
var currentI by remember { mutableIntStateOf(0) }

var isSelected by remember { mutableStateOf(true) }
LaunchedEffect(musicViewModel.sliderPosition.floatValue) {
val timeState = musicViewModel.sliderPosition.floatValue

Expand All @@ -54,11 +59,11 @@ fun LyricsView(
if (entry.timeStart > timeState) {
if (currentI != index) {
currentI = index
if (musicViewModel.autoScroll.value) {
if (musicViewModel.autoScroll.value && isSelected) {
launch(Dispatchers.Main) {
// TODO calculate the scroll position by 
listState.scrollToItem(
if ((currentI - 6) < 0) 0 else (currentI - 6),
if ((currentI - 1) < 0) 0 else (currentI - 1),
0
)
}
Expand All @@ -78,7 +83,7 @@ fun LyricsView(
}
if (cIndex >= 0 && cIndex != currentI) {
currentI = cIndex
if (musicViewModel.autoScroll.value) {
if (musicViewModel.autoScroll.value && isSelected) {
launch(Dispatchers.Main) {
// TODO calculate the scroll position by 
listState.scrollToItem(if ((currentI - 1) < 0) 0 else (currentI - 1), 0)
Expand All @@ -90,41 +95,28 @@ fun LyricsView(
if (musicViewModel.currentCaptionList.getOrElse(currentI) {
Caption("", 0)
}.text.isNotBlank()) {
if (musicViewModel.autoScroll.value) {
if (musicViewModel.autoScroll.value && isSelected) {
launch(Dispatchers.Main) {
listState.scrollToItem(if ((currentI - 6) < 0) 0 else (currentI - 6), 0)
listState.scrollToItem(if ((currentI - 1) < 0) 0 else (currentI - 1), 0)
}
}
}
}

}

LazyColumn(
state = listState,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.onSizeChanged { sizeIt ->
size.value = sizeIt
}
.padding(start = 20.dp, end = 20.dp)
.combinedClickable(
onLongClick = {
if (musicViewModel.autoScroll.value) {
musicViewModel.autoScroll.value = false
Toast
.makeText(context, "Auto scroll is disabled", Toast.LENGTH_SHORT)
.show()
} else {
musicViewModel.autoScroll.value = true
Toast
.makeText(context, "Auto scroll is enable", Toast.LENGTH_SHORT)
.show()
}

},
onDoubleClick = {
if (musicViewModel.currentCaptionList.size == 0) {
Text(
text = "No Lyrics, Click to import lyrics",
color = MaterialTheme.colorScheme.onBackground,
fontSize = MaterialTheme.typography.titleLarge.fontSize,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(2.dp)
.onSizeChanged { sizeIt ->
size.value = sizeIt
}
.clickable() {
if (musicViewModel.currentPlay.value != null) {
val regexPattern = Regex("[<>\"/~'{}?,+=)(^&*%!@#\$]")
val artistsFolder = musicViewModel.currentPlay.value?.artist
Expand All @@ -137,43 +129,66 @@ fun LyricsView(
folderPath
)
folder?.mkdirs()
val id = musicViewModel.currentPlay.value?.name?.replace(regexPattern, "_")
val id =
musicViewModel.currentPlay.value?.name?.replace(regexPattern, "_")
val pathLyrics: String =
context.getExternalFilesDir(folderPath)?.absolutePath + "/$id.lrc"
val path: String =
context.getExternalFilesDir(folderPath)?.absolutePath + "/$id.txt"
val lyrics = File(pathLyrics)
val text = File(path)
if (lyrics.exists()) {
openFile(lyrics.path, context = context)
Utils.openFile(lyrics.path, context = context)
} else if (text.exists()) {
openFile(text.path, context = context)
Utils.openFile(text.path, context = context)
} else {
val tempPath: String =
context.getExternalFilesDir(folderPath)?.absolutePath + "/$id."
(context as MainActivity).openFilePicker(tempPath)
}
}
},
) {
// Toast.makeText(context, "Double click to import lyrics", Toast.LENGTH_SHORT).show()
}
) {
items(musicViewModel.currentCaptionList.size) {
Text(
text = musicViewModel.currentCaptionList[it].text,
color = MaterialTheme.colorScheme.onBackground,
fontSize = if (currentI == it) MaterialTheme.typography.titleLarge.fontSize else
MaterialTheme.typography.titleMedium.fontSize,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(2.dp)
.onSizeChanged { sizeIt ->
size.value = sizeIt
}
)
} else {
CompositionLocalProvider(
LocalTextToolbar provides CustomTextToolbar(LocalView.current)
) {
SelectionContainer {
LazyColumn(
state = listState,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.onSizeChanged { sizeIt ->
size.value = sizeIt
}
.padding(start = 20.dp, end = 20.dp)
.combinedClickable(
) {
// Toast.makeText(context, "Double click to import lyrics", Toast.LENGTH_SHORT).show()
}
) {
items(musicViewModel.currentCaptionList.size) {
Text(
text = musicViewModel.currentCaptionList[it].text,
color = MaterialTheme.colorScheme.onBackground,
fontSize = if (currentI == it) MaterialTheme.typography.titleLarge.fontSize else
MaterialTheme.typography.titleMedium.fontSize,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(2.dp)
.onSizeChanged { sizeIt ->
size.value = sizeIt
}
)
}
)
}
}
}

}


}

51 changes: 49 additions & 2 deletions app/src/main/java/com/ztftrue/music/ui/play/PlayingPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import android.os.Bundle
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.view.MotionEvent
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -32,6 +34,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Slider
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRowDefaults
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
Expand All @@ -48,13 +51,16 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.pointer.motionEventSpy
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.media3.common.Player
Expand Down Expand Up @@ -228,7 +234,7 @@ fun PlayingPage(

OperateType.RemoveFromQueue -> {
val index = viewModel.musicQueue.indexOfFirst { it.id == music.id }
if(index == -1) return@OperateDialog
if (index == -1) return@OperateDialog
val bundle = Bundle()
bundle.putInt("index", index)
viewModel.mediaBrowser?.sendCustomAction(
Expand Down Expand Up @@ -308,8 +314,49 @@ fun PlayingPage(
.fillMaxHeight(),
topBar = {
Column(Modifier.fillMaxWidth()) {
key(Unit) {
key(Unit, pagerTabState.currentPage) {
TopBar(navController, viewModel, content = {
/**
* tabPositions[pagerTabState.currentPage]
* playViewTab
*/
if (playViewTab[pagerTabState.currentPage].id == LyricsID) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.combinedClickable(onLongClick = {
Toast
.makeText(
context,
"Switch auto scroll",
Toast.LENGTH_SHORT
)
.show()
}) {
viewModel.autoScroll.value = !viewModel.autoScroll.value
}
.padding(0.dp)
.height(50.dp)
) {
Text(
text = "Scroll",
modifier = Modifier.padding(0.dp),
color = MaterialTheme.colorScheme.onBackground,
fontSize = TextUnit(12f, TextUnitType.Sp),
lineHeight = TextUnit(12f, TextUnitType.Sp),
)
Switch(checked = viewModel.autoScroll.value,
modifier = Modifier
.scale(0.5f)
.padding(0.dp),
onCheckedChange = {
viewModel.autoScroll.value = it
}
)
}
}


IconButton(
modifier = Modifier.width(50.dp), onClick = {
showDialog = true
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/ztftrue/music/ui/public/TopBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fun TopBar(
})
}
BackButton(navController)
Row {
Row ( verticalAlignment = Alignment.CenterVertically){
IconButton(onClick = {
showDialog = true
}) {
Expand Down
Loading

0 comments on commit 46d4af4

Please sign in to comment.