This commit is contained in:
ponzischeme89
2026-08-25 23:47:03 +12:00
parent 3c247a0afd
commit 919a12f8d5
8 changed files with 64 additions and 30 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ val membyGatewayUrl: String = (project.findProperty("memby.gatewayUrl") as Strin
val membyDiagnosticLogLevel: String = (project.findProperty("memby.diagnosticLogLevel") as String?) val membyDiagnosticLogLevel: String = (project.findProperty("memby.diagnosticLogLevel") as String?)
?.trim()?.uppercase()?.takeIf { it in setOf("INFO", "DEBUG", "TRACE") } ?: "INFO" ?.trim()?.uppercase()?.takeIf { it in setOf("INFO", "DEBUG", "TRACE") } ?: "INFO"
val defaultVersionName = "0.3.25" val defaultVersionName = "0.3.26"
val membyVersionName: String = val membyVersionName: String =
(project.findProperty("memby.versionName") as String?) (project.findProperty("memby.versionName") as String?)
?.trim() ?.trim()
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

@@ -38,6 +38,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.tv.material3.Icon
import androidx.tv.material3.Text import androidx.tv.material3.Text
import coil.compose.AsyncImage import coil.compose.AsyncImage
import coil.request.ImageRequest import coil.request.ImageRequest
@@ -46,10 +47,11 @@ import com.ponzischeme89.memby.ui.TitleLogoImage
import com.ponzischeme89.memby.ui.cinematicBackdropPullBack import com.ponzischeme89.memby.ui.cinematicBackdropPullBack
import com.ponzischeme89.memby.ui.theme.MembyAccentBright import com.ponzischeme89.memby.ui.theme.MembyAccentBright
import com.ponzischeme89.memby.ui.theme.MembyCardCorner import com.ponzischeme89.memby.ui.theme.MembyCardCorner
import com.ponzischeme89.memby.ui.theme.MembyHairline import com.ponzischeme89.memby.ui.theme.MembyIcon
import com.ponzischeme89.memby.ui.theme.MembyMutedText import com.ponzischeme89.memby.ui.theme.MembyMutedText
import com.ponzischeme89.memby.ui.theme.MembyOnSurface import com.ponzischeme89.memby.ui.theme.MembyOnSurface
import com.ponzischeme89.memby.ui.theme.MembySurface import com.ponzischeme89.memby.ui.theme.MembySurface
import com.ponzischeme89.memby.ui.theme.mark
import com.ponzischeme89.memby.ui.useTextTitleForLogo import com.ponzischeme89.memby.ui.useTextTitleForLogo
/** The already-resolved metadata needed to render a pause without doing repository work. */ /** The already-resolved metadata needed to render a pause without doing repository work. */
@@ -172,14 +174,7 @@ private fun PauseHeroContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier, verticalArrangement = Arrangement.Top) { Column(modifier, verticalArrangement = Arrangement.Top) {
Text( PauseHeroHeading()
text = stringResource(R.string.player_paused),
color = MembyAccentBright,
fontSize = 12.sp,
lineHeight = 15.sp,
fontWeight = FontWeight.Bold,
letterSpacing = 0.18.em,
)
Spacer(Modifier.height(10.dp)) Spacer(Modifier.height(10.dp))
PauseHeroTitle(metadata) PauseHeroTitle(metadata)
if (metadata.isEpisode) { if (metadata.isEpisode) {
@@ -196,7 +191,18 @@ private fun PauseHeroContent(
) )
} }
} }
Spacer(Modifier.height(if (castVisible) 12.dp else 18.dp)) // The synopsis is pushed to the foot of the content area rather than sat directly
// under the episode line. What is paused is said once at the top — mark, heading,
// title treatment, episode — and the description is reference material somebody
// reads only if they want it, so it belongs away from that block and out of the
// artwork's middle. The cast panel takes a fixed gap instead: it is the thing being
// looked at when it is up, and anchoring it to the bottom edge would leave a hole
// where the summary had been.
if (castVisible) {
Spacer(Modifier.height(12.dp))
} else {
Spacer(Modifier.weight(1f).heightIn(min = 18.dp))
}
Crossfade( Crossfade(
targetState = castVisible, targetState = castVisible,
animationSpec = tween(PauseHeroSectionFadeMs), animationSpec = tween(PauseHeroSectionFadeMs),
@@ -273,10 +279,6 @@ private fun PauseHeroSummary(metadata: PauseMediaHeroMetadata) {
}, },
) )
} }
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
Text( Text(
text = synopsis, text = synopsis,
color = MembyMutedText, color = MembyMutedText,
@@ -284,15 +286,41 @@ private fun PauseHeroSummary(metadata: PauseMediaHeroMetadata) {
lineHeight = 22.sp, lineHeight = 22.sp,
maxLines = if (metadata.isEpisode) 5 else 7, maxLines = if (metadata.isEpisode) 5 else 7,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) modifier = Modifier.weight(1f),
Box(Modifier.fillMaxWidth().height(1.dp).background(MembyHairline))
Text(
text = stringResource(R.string.player_pause_resume_hint),
color = MembyOnSurface.copy(alpha = 0.76f),
fontSize = 13.sp,
) )
} }
} }
/**
* The paused mark and its heading.
*
* The word alone was one small green line in a corner, which on a still frame reads as a
* label rather than as the reason the picture has stopped — so the mark carries the state
* and the word names it. There is deliberately nothing after it: this player is driven by
* the remote's own Play/Pause key, and a screen that has to explain that is one that does
* not trust its own transport.
*/
@Composable
private fun PauseHeroHeading() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Icon(
imageVector = MembyIcon.Pause.mark,
contentDescription = null,
tint = MembyAccentBright,
modifier = Modifier.size(16.dp),
)
Text(
text = stringResource(R.string.player_paused),
color = MembyAccentBright,
fontSize = 12.sp,
lineHeight = 15.sp,
fontWeight = FontWeight.Bold,
letterSpacing = 0.18.em,
)
}
} }
internal fun pauseHeroEpisodeLabel(metadata: PauseMediaHeroMetadata): String? { internal fun pauseHeroEpisodeLabel(metadata: PauseMediaHeroMetadata): String? {
@@ -47,6 +47,7 @@ import com.composables.icons.fontawesome.solid.Mountain
import com.composables.icons.fontawesome.solid.Music import com.composables.icons.fontawesome.solid.Music
import com.composables.icons.fontawesome.solid.Palette import com.composables.icons.fontawesome.solid.Palette
import com.composables.icons.fontawesome.solid.PhotoVideo import com.composables.icons.fontawesome.solid.PhotoVideo
import com.composables.icons.fontawesome.solid.Pause
import com.composables.icons.fontawesome.solid.Play import com.composables.icons.fontawesome.solid.Play
import com.composables.icons.fontawesome.solid.PlayCircle import com.composables.icons.fontawesome.solid.PlayCircle
import com.composables.icons.fontawesome.solid.Plus import com.composables.icons.fontawesome.solid.Plus
@@ -91,6 +92,7 @@ internal val fontAwesomeIconPack = MembyIconPack(
MembyIcon.Event to { FontAwesome.Solid.CalendarDay }, MembyIcon.Event to { FontAwesome.Solid.CalendarDay },
MembyIcon.Play to { FontAwesome.Solid.Play }, MembyIcon.Play to { FontAwesome.Solid.Play },
MembyIcon.PlayCircle to { FontAwesome.Solid.PlayCircle }, MembyIcon.PlayCircle to { FontAwesome.Solid.PlayCircle },
MembyIcon.Pause to { FontAwesome.Solid.Pause },
MembyIcon.Favourite to { FontAwesome.Solid.Heart }, MembyIcon.Favourite to { FontAwesome.Solid.Heart },
MembyIcon.Bookmark to { FontAwesome.Solid.Bookmark }, MembyIcon.Bookmark to { FontAwesome.Solid.Bookmark },
MembyIcon.PlaylistAdd to { FontAwesome.Solid.PlusCircle }, MembyIcon.PlaylistAdd to { FontAwesome.Solid.PlusCircle },
@@ -47,6 +47,7 @@ import com.composables.icons.lucide.MountainSnow
import com.composables.icons.lucide.Music2 import com.composables.icons.lucide.Music2
import com.composables.icons.lucide.Palette import com.composables.icons.lucide.Palette
import com.composables.icons.lucide.Pin import com.composables.icons.lucide.Pin
import com.composables.icons.lucide.Pause
import com.composables.icons.lucide.Play import com.composables.icons.lucide.Play
import com.composables.icons.lucide.Plus import com.composables.icons.lucide.Plus
import com.composables.icons.lucide.Power import com.composables.icons.lucide.Power
@@ -93,6 +94,7 @@ internal val lucideIconPack = MembyIconPack(
MembyIcon.Event to { Lucide.CalendarClock }, MembyIcon.Event to { Lucide.CalendarClock },
MembyIcon.Play to { Lucide.Play }, MembyIcon.Play to { Lucide.Play },
MembyIcon.PlayCircle to { Lucide.CirclePlay }, MembyIcon.PlayCircle to { Lucide.CirclePlay },
MembyIcon.Pause to { Lucide.Pause },
MembyIcon.FavouriteOutline to { Lucide.Heart }, MembyIcon.FavouriteOutline to { Lucide.Heart },
MembyIcon.BookmarkOutline to { Lucide.Bookmark }, MembyIcon.BookmarkOutline to { Lucide.Bookmark },
MembyIcon.PlaylistAdd to { Lucide.ListPlus }, MembyIcon.PlaylistAdd to { Lucide.ListPlus },
@@ -55,6 +55,7 @@ import androidx.compose.material.icons.filled.NotificationsNone
import androidx.compose.material.icons.filled.NotificationsOff import androidx.compose.material.icons.filled.NotificationsOff
import androidx.compose.material.icons.filled.Palette import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.PlayCircleFilled import androidx.compose.material.icons.filled.PlayCircleFilled
import androidx.compose.material.icons.filled.PlaylistRemove import androidx.compose.material.icons.filled.PlaylistRemove
@@ -107,6 +108,7 @@ object MaterialIconPack {
MembyIcon.Event to { Icons.Default.Event }, MembyIcon.Event to { Icons.Default.Event },
MembyIcon.Play to { Icons.Default.PlayArrow }, MembyIcon.Play to { Icons.Default.PlayArrow },
MembyIcon.PlayCircle to { Icons.Default.PlayCircleFilled }, MembyIcon.PlayCircle to { Icons.Default.PlayCircleFilled },
MembyIcon.Pause to { Icons.Default.Pause },
MembyIcon.Favourite to { Icons.Default.Favorite }, MembyIcon.Favourite to { Icons.Default.Favorite },
MembyIcon.FavouriteOutline to { Icons.Default.FavoriteBorder }, MembyIcon.FavouriteOutline to { Icons.Default.FavoriteBorder },
MembyIcon.Bookmark to { Icons.Default.Bookmark }, MembyIcon.Bookmark to { Icons.Default.Bookmark },
@@ -37,6 +37,7 @@ enum class MembyIcon {
// Playback and library actions // Playback and library actions
Play, Play,
PlayCircle, PlayCircle,
Pause,
Favourite, Favourite,
FavouriteOutline, FavouriteOutline,
Bookmark, Bookmark,
-1
View File
@@ -16,7 +16,6 @@
<string name="player_now_playing">NOW PLAYING</string> <string name="player_now_playing">NOW PLAYING</string>
<string name="player_paused">PAUSED</string> <string name="player_paused">PAUSED</string>
<string name="player_pause_poster">Movie poster</string> <string name="player_pause_poster">Movie poster</string>
<string name="player_pause_resume_hint">Press OK to resume</string>
<string name="player_pause_overview_fallback">No description is available for this title.</string> <string name="player_pause_overview_fallback">No description is available for this title.</string>
<string name="player_position_separator">/</string> <string name="player_position_separator">/</string>
<string name="player_loading_duration">Loading duration…</string> <string name="player_loading_duration">Loading duration…</string>