make layout respect different fontsizes

This commit is contained in:
Christian Schabesberger 2024-09-02 14:40:19 +02:00
parent cdcfeaedd7
commit 1e39f97bee
8 changed files with 85 additions and 45 deletions

View File

@ -58,6 +58,7 @@ import net.newpipe.newplayer.utils.getDefaultBrightness
import net.newpipe.newplayer.utils.getInsets import net.newpipe.newplayer.utils.getInsets
val CONTROLLER_UI_BACKGROUND_COLOR = Color(0x75000000) val CONTROLLER_UI_BACKGROUND_COLOR = Color(0x75000000)
val STREAMSELECT_UI_BACKGROUND_COLOR = Color(0xba000000)
@Composable @Composable
fun VideoPlayerControllerUI( fun VideoPlayerControllerUI(

View File

@ -57,6 +57,7 @@ import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
import net.newpipe.newplayer.Chapter import net.newpipe.newplayer.Chapter
import net.newpipe.newplayer.NewPlayerException import net.newpipe.newplayer.NewPlayerException
import net.newpipe.newplayer.playerInternals.PlaylistItem import net.newpipe.newplayer.playerInternals.PlaylistItem
import net.newpipe.newplayer.ui.STREAMSELECT_UI_BACKGROUND_COLOR
import net.newpipe.newplayer.ui.videoplayer.streamselect.ChapterItem import net.newpipe.newplayer.ui.videoplayer.streamselect.ChapterItem
import net.newpipe.newplayer.ui.videoplayer.streamselect.ChapterSelectTopBar import net.newpipe.newplayer.ui.videoplayer.streamselect.ChapterSelectTopBar
import net.newpipe.newplayer.ui.videoplayer.streamselect.StreamItem import net.newpipe.newplayer.ui.videoplayer.streamselect.StreamItem
@ -72,7 +73,7 @@ fun StreamSelectUI(
val insets = getInsets() val insets = getInsets()
Surface( Surface(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
color = CONTROLLER_UI_BACKGROUND_COLOR color = STREAMSELECT_UI_BACKGROUND_COLOR
) { ) {
Scaffold( Scaffold(
modifier = Modifier modifier = Modifier
@ -94,7 +95,7 @@ fun StreamSelectUI(
modifier = Modifier modifier = Modifier
.padding(innerPadding) .padding(innerPadding)
.fillMaxSize(), .fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(10.dp), // verticalArrangement = Arrangement.spacedBy(10.dp),
contentPadding = PaddingValues(start = 8.dp, end = 4.dp) contentPadding = PaddingValues(start = 8.dp, end = 4.dp)
) { ) {
if (isChapterSelect) { if (isChapterSelect) {

View File

@ -42,6 +42,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -55,9 +56,7 @@ import net.newpipe.newplayer.utils.getEmbeddedUiConfig
@Composable @Composable
fun TopUI( fun TopUI(
modifier: Modifier, modifier: Modifier, viewModel: VideoPlayerViewModel, uiState: VideoPlayerUIState
viewModel: VideoPlayerViewModel,
uiState: VideoPlayerUIState
) { ) {
val embeddedUiConfig = getEmbeddedUiConfig(activity = LocalContext.current as Activity) val embeddedUiConfig = getEmbeddedUiConfig(activity = LocalContext.current as Activity)
Row( Row(
@ -66,11 +65,15 @@ fun TopUI(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
) { ) {
Column(horizontalAlignment = Alignment.Start, modifier = Modifier.weight(1F)) { Column(horizontalAlignment = Alignment.Start, modifier = Modifier.weight(1F)) {
Text("The Title", fontSize = 15.sp, fontWeight = FontWeight.Bold)
Text( Text(
"The Channel", "The Title",
fontSize = 12.sp, fontSize = 15.sp,
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Text(
"The Channel", fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis
) )
} }
Button( Button(

View File

@ -37,6 +37,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -64,6 +65,7 @@ fun ChapterItem(
Row( Row(
modifier = modifier modifier = modifier
.height(80.dp) .height(80.dp)
.padding(5.dp)
.clickable { onClicked(id) } .clickable { onClicked(id) }
) { ) {
val contentDescription = stringResource(R.string.chapter) val contentDescription = stringResource(R.string.chapter)
@ -98,8 +100,18 @@ fun ChapterItem(
modifier = Modifier.padding(start = 8.dp), modifier = Modifier.padding(start = 8.dp),
horizontalAlignment = Alignment.Start, horizontalAlignment = Alignment.Start,
) { ) {
Text(text = chapterTitle, fontSize = 18.sp, fontWeight = FontWeight.Bold) Text(
Text(getTimeStringFromMs(chapterStartInMs, locale)) text = chapterTitle,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Text(
getTimeStringFromMs(chapterStartInMs, locale),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
} }
} }

View File

@ -35,6 +35,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import net.newpipe.newplayer.R import net.newpipe.newplayer.R
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
@ -45,8 +46,7 @@ fun ChapterSelectTopBar(modifier: Modifier = Modifier, onClose: () -> Unit) {
TopAppBar(modifier = modifier, TopAppBar(modifier = modifier,
colors = topAppBarColors(containerColor = Color.Transparent), colors = topAppBarColors(containerColor = Color.Transparent),
title = { title = {
Text("Chapter TODO") Text(stringResource(R.string.chapter), maxLines = 1, overflow = TextOverflow.Ellipsis)
//Text(stringResource(R.string.chapter))
}, actions = { }, actions = {
IconButton( IconButton(
onClick = onClose onClick = onClose

View File

@ -25,13 +25,16 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.DragHandle import androidx.compose.material.icons.filled.DragHandle
@ -47,6 +50,7 @@ import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -77,34 +81,40 @@ fun StreamItem(
val locale = getLocale()!! val locale = getLocale()!!
Row(modifier = modifier Row(modifier = modifier
.clickable { onClicked(id) } .clickable { onClicked(id) }
.height(80.dp)) { .padding(5.dp)
Box { .height(IntrinsicSize.Min)) {
Box(
modifier = Modifier
.aspectRatio(16f / 9f)
.wrapContentHeight()
.fillMaxWidth()
) {
val contentDescription = stringResource(R.string.chapter) val contentDescription = stringResource(R.string.chapter)
if (thumbnail != null) { if (thumbnail != null) {
when (thumbnail) { when (thumbnail) {
is OnlineThumbnail -> AsyncImage( is OnlineThumbnail -> AsyncImage(
modifier = Modifier.fillMaxSize(),
model = thumbnail.url, model = thumbnail.url,
contentDescription = contentDescription contentDescription = contentDescription
) )
is BitmapThumbnail -> Image( is BitmapThumbnail -> Image(
modifier = Modifier.fillMaxSize(),
bitmap = thumbnail.img, bitmap = thumbnail.img,
contentDescription = contentDescription contentDescription = contentDescription
) )
is VectorThumbnail -> Image( is VectorThumbnail -> Image(
modifier = Modifier.fillMaxSize(),
imageVector = thumbnail.vec, imageVector = thumbnail.vec,
contentDescription = contentDescription contentDescription = contentDescription
) )
} }
AsyncImage(
model = thumbnail,
contentDescription = contentDescription
)
} else { } else {
Image( Image(
painterResource(R.drawable.tiny_placeholder), modifier = Modifier.fillMaxSize(),
contentDescription = stringResource(R.string.chapter_thumbnail) painter = painterResource(R.drawable.tiny_placeholder),
contentDescription = contentDescription
) )
} }
Surface( Surface(
@ -118,28 +128,37 @@ fun StreamItem(
modifier = Modifier.padding( modifier = Modifier.padding(
start = 4.dp, start = 4.dp,
end = 4.dp, end = 4.dp,
top = 2.dp, top = 0.5.dp,
bottom = 2.dp bottom = 0.5.dp
), text = getTimeStringFromMs(lengthInMs, locale) ),
text = getTimeStringFromMs(lengthInMs, locale, leadingZerosForMinutes = false),
fontSize = 14.sp,
) )
} }
} }
Column( Column(
modifier = Modifier modifier = Modifier
.padding(8.dp) .padding(1.dp)
.weight(1f) .weight(1f)
.fillMaxSize() .height(IntrinsicSize.Min)
.fillMaxWidth()
) { ) {
Text(text = title, fontSize = 18.sp, fontWeight = FontWeight.Bold) Text(
text = title, fontSize = 14.sp, fontWeight = FontWeight.Bold, maxLines = 1,
overflow = TextOverflow.Ellipsis
)
if (creator != null) { if (creator != null) {
Text(text = creator) Text(
text = creator, fontSize = 13.sp, fontWeight = FontWeight.Light, maxLines = 1,
overflow = TextOverflow.Ellipsis
)
} }
} }
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxHeight()
.aspectRatio(1f) .aspectRatio(1f)
.fillMaxSize()
.pointerInteropFilter { .pointerInteropFilter {
when (it.action) { when (it.action) {
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
@ -157,7 +176,7 @@ fun StreamItem(
}) { }) {
Icon( Icon(
modifier = Modifier modifier = Modifier
.size(40.dp) .size(25.dp)
.align(Alignment.Center), .align(Alignment.Center),
imageVector = Icons.Filled.DragHandle, imageVector = Icons.Filled.DragHandle,
//contentDescription = stringResource(R.string.stream_item_drag_handle) //contentDescription = stringResource(R.string.stream_item_drag_handle)
@ -172,9 +191,9 @@ fun StreamItem(
fun StreamItemPreview() { fun StreamItemPreview() {
VideoPlayerTheme { VideoPlayerTheme {
Surface(modifier = Modifier.fillMaxSize(), color = Color.DarkGray) { Surface(modifier = Modifier.fillMaxSize(), color = Color.DarkGray) {
Box(modifier = Modifier.fillMaxSize()) {
StreamItem( StreamItem(
id = 0, id = 0,
modifier = Modifier.fillMaxSize(),
title = "Video Title", title = "Video Title",
creator = "Video Creator", creator = "Video Creator",
thumbnail = null, thumbnail = null,
@ -186,3 +205,4 @@ fun StreamItemPreview() {
} }
} }
} }
}

View File

@ -41,6 +41,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.media3.common.Player import androidx.media3.common.Player
import net.newpipe.newplayer.NewPlayerException import net.newpipe.newplayer.NewPlayerException
@ -68,7 +69,9 @@ fun StreamSelectTopBar(
val duration = getPlaylistDurationInS(uiState.playList).toLong() * 1000 val duration = getPlaylistDurationInS(uiState.playList).toLong() * 1000
val durationString = getTimeStringFromMs(timeSpanInMs = duration, locale) val durationString = getTimeStringFromMs(timeSpanInMs = duration, locale)
Text( Text(
text = "00:00/$durationString" text = "00:00/$durationString",
maxLines = 1,
overflow = TextOverflow.Ellipsis
) )
}, actions = { }, actions = {
IconButton( IconButton(

View File

@ -113,7 +113,7 @@ private const val MILLIS_PER_DAY =
private const val MILLIS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND private const val MILLIS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND
private const val MILLIS_PER_MINUTE = SECONDS_PER_MINUTE * MILLIS_PER_SECOND private const val MILLIS_PER_MINUTE = SECONDS_PER_MINUTE * MILLIS_PER_SECOND
fun getTimeStringFromMs(timeSpanInMs: Long, locale: Locale): String { fun getTimeStringFromMs(timeSpanInMs: Long, locale: Locale, leadingZerosForMinutes:Boolean = true): String {
val days = timeSpanInMs / MILLIS_PER_DAY val days = timeSpanInMs / MILLIS_PER_DAY
val millisThisDay = timeSpanInMs - days * MILLIS_PER_DAY val millisThisDay = timeSpanInMs - days * MILLIS_PER_DAY
val hours = millisThisDay / MILLIS_PER_HOUR val hours = millisThisDay / MILLIS_PER_HOUR
@ -126,7 +126,7 @@ fun getTimeStringFromMs(timeSpanInMs: Long, locale: Locale): String {
val time_string = val time_string =
if (0L < days) String.format(locale, "%d:%02d:%02d:%02d", days, hours, minutes, seconds) if (0L < days) String.format(locale, "%d:%02d:%02d:%02d", days, hours, minutes, seconds)
else if (0L < hours) String.format(locale, "%d:%02d:%02d", hours, minutes, seconds) else if (0L < hours) String.format(locale, "%d:%02d:%02d", hours, minutes, seconds)
else String.format(locale, "%02d:%02d", minutes, seconds) else String.format(locale, if(leadingZerosForMinutes) "%02d:%02d" else "%d:%02d", minutes, seconds)
return time_string return time_string
} }