Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

End of Year: Epilogue story design #567

Merged
merged 9 commits into from
Nov 15, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ private val ShareButtonStrokeWidth = 2.dp
private val StoryViewCornerSize = 10.dp
private val StoriesViewMaxSize = 700.dp
private const val MaxHeightPercentFactor = 0.9f
private const val LongPressThresholdTimeInMs = 150
const val StoriesViewAspectRatioForTablet = 2f

@OptIn(ExperimentalComposeUiApi::class)
Expand Down Expand Up @@ -303,7 +304,7 @@ private fun StoriesErrorView(
StoriesEmptyView(
content = {
TextP50(
text = "Failed to load stories.", // TODO: replace hardcoded text
text = stringResource(id = LR.string.end_of_year_stories_failed),
color = Color.White,
)
},
Expand Down Expand Up @@ -343,7 +344,6 @@ private fun StorySwitcher(
content: (@Composable () -> Unit)?,
) {
var screenWidth by remember { mutableStateOf(1) }
var isPaused by remember { mutableStateOf(false) }
Box(
modifier = modifier
.fillMaxSize()
Expand All @@ -352,24 +352,24 @@ private fun StorySwitcher(
}
.pointerInput(Unit) {
detectTapGestures(
onTap = {
if (!isPaused) {
if (it.x > screenWidth / 2) {
onSkipNext()
onPress = {
val pressStartTime = System.currentTimeMillis()
onPause()
val isReleased = tryAwaitRelease()
if (isReleased) {
val pressEndTime = System.currentTimeMillis()
val diffPressTime = pressEndTime - pressStartTime
if (diffPressTime < LongPressThresholdTimeInMs) {
if (it.x > screenWidth / 2) {
onSkipNext()
} else {
onSkipPrevious()
}
} else {
onSkipPrevious()
onStart()
}
}
},
onLongPress = {
isPaused = true
onPause()
},
onPress = {
awaitRelease()
if (isPaused) {
} else {
onStart()
isPaused = false
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class StoriesViewModel @Inject constructor(
}

fun start() {
if (timer != null) clear()

val currentState = state.value as State.Loaded
val progressFraction =
(PROGRESS_UPDATE_INTERVAL_MS / totalLengthInMs.toFloat())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import androidx.compose.ui.graphics.graphicsLayer
import au.com.shiftyjelly.pocketcasts.models.entity.Podcast

fun Modifier.podcastDynamicBackground(podcast: Podcast) =
dynamicBackground(Color(podcast.getTintColor(false)))

fun Modifier.dynamicBackground(color: Color) =
graphicsLayer {
/*
https://rb.gy/iju6fn
Expand All @@ -20,7 +23,7 @@ fun Modifier.podcastDynamicBackground(podcast: Podcast) =
Color.Black,
Color(0x80000000), // 50% Black
)
drawRect(color = Color(podcast.getTintColor(false)))
drawRect(color = color)
drawRect(
brush = Brush.verticalGradient(
colors,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,89 +1,136 @@
package au.com.shiftyjelly.pocketcasts.endofyear.views.stories

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import au.com.shiftyjelly.pocketcasts.compose.AppTheme
import au.com.shiftyjelly.pocketcasts.compose.components.TextH30
import au.com.shiftyjelly.pocketcasts.compose.preview.ThemePreviewParameterProvider
import au.com.shiftyjelly.pocketcasts.localization.R
import au.com.shiftyjelly.pocketcasts.compose.components.TextP40
import au.com.shiftyjelly.pocketcasts.endofyear.R
import au.com.shiftyjelly.pocketcasts.endofyear.components.PodcastLogoWhite
import au.com.shiftyjelly.pocketcasts.endofyear.components.StoryPrimaryText
import au.com.shiftyjelly.pocketcasts.endofyear.components.StorySecondaryText
import au.com.shiftyjelly.pocketcasts.endofyear.utils.dynamicBackground
import au.com.shiftyjelly.pocketcasts.repositories.endofyear.stories.StoryEpilogue
import au.com.shiftyjelly.pocketcasts.ui.theme.Theme
import au.com.shiftyjelly.pocketcasts.localization.R as LR

private val HeartImageSize = 72.dp
private const val BackgroundColor = 0xFFFDDC68

@Composable
fun StoryEpilogueView(
story: StoryEpilogue,
onReplayClicked: () -> Unit,
modifier: Modifier = Modifier,
) {

Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.fillMaxSize()
.dynamicBackground(Color(BackgroundColor))
.verticalScroll(rememberScrollState())
) {
TextH30(
text = "Thank you for letting Pocket Casts be a part of your listening experience in 2022",
color = story.tintColor,
textAlign = TextAlign.Center,
modifier = modifier.padding(16.dp)
)
TextH30(
text = "Don't forget to share with your friends and give a shout out to your favorite podcasts creators",
color = story.tintColor,
textAlign = TextAlign.Center,
modifier = modifier.padding(16.dp)
)
Spacer(modifier = modifier.height(40.dp))

Spacer(modifier = modifier.weight(1f))

HeartImage()

Spacer(modifier = modifier.weight(0.34f))

PrimaryText(story)

Spacer(modifier = modifier.weight(0.16f))

SecondaryText(story)

Spacer(modifier = modifier.weight(0.32f))

ReplayButton(onClick = onReplayClicked)

Spacer(modifier = modifier.weight(1f))

PodcastLogoWhite()

Spacer(modifier = modifier.height(40.dp))
}
}

@Composable
private fun HeartImage(
modifier: Modifier = Modifier,
) {
Image(
painter = painterResource(id = R.drawable.heart),
contentDescription = null,
modifier = modifier
.size(HeartImageSize)
)
}

@Composable
private fun PrimaryText(
story: StoryEpilogue,
modifier: Modifier = Modifier,
) {
val text = stringResource(id = LR.string.end_of_year_story_epilogue_title)
StoryPrimaryText(text = text, color = story.tintColor, modifier = modifier)
}

@Composable
private fun SecondaryText(
story: StoryEpilogue,
modifier: Modifier = Modifier,
) {
val text = stringResource(id = LR.string.end_of_year_story_epilogue_subtitle)
StorySecondaryText(text = text, color = story.tintColor, modifier = modifier)
}

@Composable
private fun ReplayButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Button(
onClick = { onClick() },
elevation = ButtonDefaults.elevation(
defaultElevation = 0.dp,
pressedElevation = 0.dp,
hoveredElevation = 0.dp,
focusedElevation = 0.dp,
),
colors = ButtonDefaults
.outlinedButtonColors(
.buttonColors(
backgroundColor = Color.Transparent,
contentColor = Color.White,
contentColor = Color.Transparent
),
) {
Icon(imageVector = Icons.Default.Refresh, contentDescription = "")
Text(
text = stringResource(id = R.string.end_of_year_replay),
fontSize = 18.sp,
Icon(
imageVector = Icons.Default.Refresh,
contentDescription = null,
tint = Color.White
)
TextP40(
text = stringResource(id = LR.string.end_of_year_replay),
color = Color.White,
modifier = modifier.padding(2.dp)
)
}
}

@Preview(showBackground = true)
@Composable
private fun StoryEpiloguePreview(
@PreviewParameter(ThemePreviewParameterProvider::class) themeType: Theme.ThemeType,
) {
AppTheme(themeType) {
Surface(color = Color.Black) {
StoryEpilogueView(
StoryEpilogue(),
onReplayClicked = {}
)
}
}
}
14 changes: 14 additions & 0 deletions modules/features/endofyear/src/main/res/drawable/heart.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="73dp"
android:height="74dp"
android:viewportWidth="73"
android:viewportHeight="74">
<path
android:pathData="M36.5,62.13C36.5,62.13 8.194,46.278 8.194,27.03C8.194,18.9 14.783,12.311 22.913,12.311C28.854,12.311 34.213,15.883 36.5,21.369C39.625,13.865 48.244,10.315 55.748,13.443C61.231,15.727 64.806,21.086 64.806,27.03C64.806,46.278 36.5,62.13 36.5,62.13Z"
android:strokeAlpha="0.24"
android:fillColor="#ffffff"
android:fillAlpha="0.24"/>
<path
android:pathData="M37.604,60.151C37.559,60.125 37.462,60.069 37.318,59.987C37.069,59.842 36.78,59.67 36.455,59.472C35.515,58.9 34.465,58.229 33.335,57.467C30.1,55.288 26.865,52.817 23.853,50.108C15.437,42.533 10.447,34.65 10.447,27.021C10.447,20.14 16.021,14.567 22.902,14.567C27.929,14.567 32.464,17.59 34.397,22.229C35.17,24.086 37.802,24.086 38.575,22.229C41.219,15.877 48.51,12.877 54.859,15.52C59.499,17.454 62.522,21.988 62.522,27.015C62.522,34.644 57.532,42.527 49.116,50.099C46.104,52.808 42.869,55.279 39.633,57.456C38.501,58.217 37.451,58.885 36.514,59.457C36.186,59.655 35.897,59.825 35.651,59.97C35.507,60.052 35.41,60.108 35.365,60.131H37.576L37.604,60.151ZM35.39,64.103C36.075,64.485 36.913,64.485 37.601,64.103C37.845,63.964 38.283,63.709 38.886,63.341C39.88,62.732 40.989,62.028 42.178,61.224C45.578,58.934 48.975,56.335 52.156,53.473C61.432,45.123 67.057,36.235 67.057,27.021C67.057,20.163 62.932,13.981 56.603,11.343C47.944,7.734 38,11.827 34.391,20.486L38.569,20.485C35.931,14.156 29.746,10.032 22.89,10.032C13.51,10.032 5.907,17.635 5.907,27.015C5.907,36.226 11.531,45.114 20.807,53.465C23.986,56.326 27.385,58.925 30.785,61.212C31.974,62.013 33.081,62.718 34.077,63.327C34.68,63.692 35.119,63.949 35.362,64.085L35.39,64.103Z"
android:fillColor="#ffffff"/>
</vector>