Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.runtime.LaunchedEffect
Expand All @@ -17,6 +18,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
Expand Down Expand Up @@ -44,6 +46,7 @@ import io.middlepoint.tvsleep.ui.screens.Timer
import io.middlepoint.tvsleep.ui.screens.timer.TimerScreen
import io.middlepoint.tvsleep.ui.screens.mapToScreen
import io.middlepoint.tvsleep.ui.theme.TVsleepTheme
import io.middlepoint.tvsleep.ui.theme.V2BackgroundBrush
import androidx.core.content.edit

@Suppress("ktlint:standard:no-consecutive-comments")
Expand All @@ -64,11 +67,9 @@ class MainActivity : ComponentActivity() {
modifier =
Modifier
.fillMaxSize()
.safeContentPadding(),
colors =
SurfaceDefaults.colors(
containerColor = MaterialTheme.colorScheme.background,
),
.safeContentPadding()
.background(V2BackgroundBrush),
colors = SurfaceDefaults.colors(containerColor = Color.Transparent),
) {
NavHost(
navController = navController,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.middlepoint.tvsleep.ui.components

import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.middlepoint.tvsleep.DashedBorder

fun Modifier.dashedBorder(
color: Color = DashedBorder,
strokeWidth: Dp = 2.dp,
cornerRadius: Dp = 22.dp,
dashLength: Float = 10f,
gapLength: Float = 10f
): Modifier = this.drawBehind {
val stroke = Stroke(
width = strokeWidth.toPx(),
pathEffect = PathEffect.dashPathEffect(floatArrayOf(dashLength, gapLength))
)
drawRoundRect(
color = color,
topLeft = Offset(strokeWidth.toPx() / 2, strokeWidth.toPx() / 2),
size = Size(
size.width - strokeWidth.toPx(),
size.height - strokeWidth.toPx()
),
cornerRadius = CornerRadius(cornerRadius.toPx()),
style = stroke
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package io.middlepoint.tvsleep.ui.components

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import io.middlepoint.tvsleep.R

@Composable
fun TVCPBanner(
onBannerClick: () -> Unit,
modifier: Modifier = Modifier
) {
V2FocusableCard(
onClick = onBannerClick,
modifier = modifier
.fillMaxWidth()
.height(120.dp),
shape = RoundedCornerShape(16.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color(0xFF1A1A2E))
.padding(horizontal = 24.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(R.drawable.ic_tvcp_logo),
contentDescription = "TVCP Logo",
modifier = Modifier.size(84.dp)
)

Spacer(modifier = Modifier.width(24.dp))

Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.Center
) {
Text(
text = "FROM THE CREATORS OF TV TIMER+",
fontSize = 12.sp,
fontWeight = FontWeight.W500,
color = Color.White.copy(alpha = 0.6f),
letterSpacing = 0.5.sp
)

Spacer(modifier = Modifier.height(4.dp))

Text(
text = "TV Control Plus",
fontSize = 24.sp,
fontWeight = FontWeight.W700,
color = Color.White
)

Spacer(modifier = Modifier.height(2.dp))

Text(
text = "Control your TV from your phone",
fontSize = 14.sp,
color = Color.White.copy(alpha = 0.8f)
)
}

Box(
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.background(MaterialTheme.colorScheme.primary)
.padding(horizontal = 20.dp, vertical = 10.dp)
) {
Text(
text = "Get it",
fontSize = 14.sp,
fontWeight = FontWeight.W600,
color = Color.White
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.middlepoint.tvsleep.ui.components

import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border
import androidx.tv.material3.Card
import androidx.tv.material3.CardDefaults
import androidx.tv.material3.ExperimentalTvMaterial3Api
import io.middlepoint.tvsleep.FocusRing

@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun V2FocusableCard(
onClick: () -> Unit,
modifier: Modifier = Modifier,
onLongClick: (() -> Unit)? = null,
shape: Shape = RoundedCornerShape(22.dp),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit
) {
val isFocused by interactionSource.collectIsFocusedAsState()
val offsetY by animateDpAsState(
targetValue = if (isFocused) (-2).dp else 0.dp,
label = "FocusLift"
)

Card(
onClick = onClick,
onLongClick = onLongClick,
modifier = modifier.offset(y = offsetY),
shape = CardDefaults.shape(shape),
border = CardDefaults.border(
focusedBorder = Border(BorderStroke(3.dp, FocusRing))
),
interactionSource = interactionSource,
content = { content() }
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.middlepoint.tvsleep.ui.components

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text

@Composable
fun V2Header(
step: Int,
totalSteps: Int,
eyebrow: String,
title: String,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
V2StepDots(
currentStep = step,
totalSteps = totalSteps
)

Spacer(modifier = Modifier.height(16.dp))

Text(
text = eyebrow,
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.7f),
letterSpacing = 0.1.em
)

Spacer(modifier = Modifier.height(8.dp))

Text(
text = title,
fontSize = 96.sp,
fontWeight = FontWeight.W600,
letterSpacing = (-0.035).em,
color = MaterialTheme.colorScheme.onPrimary
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.middlepoint.tvsleep.ui.components

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun V2StepDots(
currentStep: Int,
totalSteps: Int,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
repeat(totalSteps) { index ->
val isActive = index < currentStep
Box(
modifier = Modifier
.width(if (isActive) 24.dp else 12.dp)
.height(6.dp)
.alpha(if (isActive) 1f else 0.4f)
.background(
color = Color.White,
shape = RoundedCornerShape(3.dp)
)
)
}
}
}
Loading