Click on long press menu subtitle opens channel details

This commit is contained in:
Stypox 2025-02-11 15:03:37 +01:00
parent d4eb403e1d
commit 8e454dcb71
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
3 changed files with 114 additions and 20 deletions

View File

@ -2,8 +2,10 @@
package org.schabi.newpipe.ui.components.menu
import android.content.Context
import android.content.res.Configuration
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
@ -57,9 +59,12 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
@ -72,6 +77,7 @@ import org.schabi.newpipe.R
import org.schabi.newpipe.player.playqueue.PlayQueue
import org.schabi.newpipe.player.playqueue.SinglePlayQueue
import org.schabi.newpipe.ui.theme.AppTheme
import org.schabi.newpipe.ui.theme.customColors
import org.schabi.newpipe.util.Either
import org.schabi.newpipe.util.Localization
import java.time.OffsetDateTime
@ -346,20 +352,24 @@ fun LongPressMenuHeader(
modifier = Modifier.basicMarquee(iterations = Int.MAX_VALUE),
)
val subtitle = Localization.concatenateStrings(
item.uploader,
item.uploadDate?.match<String>(
{ it },
{ Localization.relativeTime(it) }
),
item.viewCount?.let { Localization.localizeViewCount(ctx, it) }
val subtitle = getSubtitleAnnotatedString(
item = item,
linkColor = MaterialTheme.customColors.onSurfaceVariantLink,
ctx = ctx,
)
if (subtitle.isNotBlank()) {
Spacer(Modifier.height(1.dp))
Text(
text = subtitle,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.basicMarquee(iterations = Int.MAX_VALUE),
modifier = if (item.uploaderUrl.isNullOrBlank()) {
Modifier
} else {
Modifier.clickable {
// TODO handle click on uploader URL
}
}.basicMarquee(iterations = Int.MAX_VALUE)
)
}
}
@ -367,6 +377,53 @@ fun LongPressMenuHeader(
}
}
fun getSubtitleAnnotatedString(
item: LongPressable,
linkColor: Color,
ctx: Context,
) = buildAnnotatedString {
var shouldAddSeparator = false
if (!item.uploaderUrl.isNullOrBlank()) {
withStyle(
SpanStyle(
fontWeight = FontWeight.Bold,
color = linkColor,
textDecoration = TextDecoration.Underline
)
) {
if (item.uploader.isNullOrBlank()) {
append(ctx.getString(R.string.show_channel_details))
} else {
append(item.uploader)
}
}
shouldAddSeparator = true
} else if (!item.uploader.isNullOrBlank()) {
append(item.uploader)
shouldAddSeparator = true
}
val uploadDate = item.uploadDate?.match<String>(
{ it },
{ Localization.relativeTime(it) }
)
if (!uploadDate.isNullOrBlank()) {
if (shouldAddSeparator) {
append(Localization.DOT_SEPARATOR)
}
shouldAddSeparator = true
append(uploadDate)
}
val viewCount = item.viewCount?.let { Localization.localizeViewCount(ctx, it) }
if (!viewCount.isNullOrBlank()) {
if (shouldAddSeparator) {
append(Localization.DOT_SEPARATOR)
}
append(viewCount)
}
}
@Composable
fun LongPressMenuButton(
icon: ImageVector,

View File

@ -0,0 +1,32 @@
package org.schabi.newpipe.ui.theme
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.Color
@Immutable
data class CustomColors(
val onSurfaceVariantLink: Color = Color.Unspecified,
)
val onSurfaceVariantLinkLight = Color(0xFF5060B0)
val onSurfaceVariantLinkDark = Color(0xFFC0D0FF)
val lightCustomColors = CustomColors(
onSurfaceVariantLink = onSurfaceVariantLinkLight
)
val darkCustomColors = CustomColors(
onSurfaceVariantLink = onSurfaceVariantLinkDark
)
val LocalCustomColors = staticCompositionLocalOf { CustomColors() }
val MaterialTheme.customColors: CustomColors
@Composable
@ReadOnlyComposable
get() = LocalCustomColors.current

View File

@ -5,6 +5,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.preference.PreferenceManager
@ -93,14 +94,18 @@ fun AppTheme(useDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable
val theme = sharedPreferences.getString("theme", "auto_device_theme")
val nightTheme = sharedPreferences.getString("night_theme", "dark_theme")
MaterialTheme(
colorScheme = if (!useDarkTheme) {
lightScheme
} else if (theme == "black_theme" || nightTheme == "black_theme") {
blackScheme
} else {
darkScheme
},
content = content
)
CompositionLocalProvider(
LocalCustomColors provides if (!useDarkTheme) lightCustomColors else darkCustomColors
) {
MaterialTheme(
colorScheme = if (!useDarkTheme) {
lightScheme
} else if (theme == "black_theme" || nightTheme == "black_theme") {
blackScheme
} else {
darkScheme
},
content = content
)
}
}