From 3bda49dd2dfaec4b0f33771071216ad098165cb7 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Sun, 13 Nov 2022 07:14:46 +0530 Subject: [PATCH 1/5] Add epilogue story design --- .../views/stories/StoryEpilogueView.kt | 135 ++++++++++++------ .../endofyear/src/main/res/drawable/heart.xml | 14 ++ 2 files changed, 105 insertions(+), 44 deletions(-) create mode 100644 modules/features/endofyear/src/main/res/drawable/heart.xml diff --git a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt index 60ea54ed80f..16a9da303a8 100644 --- a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt +++ b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt @@ -1,30 +1,37 @@ package au.com.shiftyjelly.pocketcasts.endofyear.views.stories +import androidx.compose.foundation.Image +import androidx.compose.foundation.background 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.colorResource +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.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 @Composable fun StoryEpilogueView( @@ -32,25 +39,70 @@ fun StoryEpilogueView( onReplayClicked: () -> Unit, modifier: Modifier = Modifier, ) { + Column( horizontalAlignment = Alignment.CenterHorizontally, + modifier = modifier + .fillMaxSize() + .background(colorResource(id = R.color.black_26)) + .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, @@ -58,32 +110,27 @@ private fun ReplayButton( ) { 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 = {} - ) - } - } -} diff --git a/modules/features/endofyear/src/main/res/drawable/heart.xml b/modules/features/endofyear/src/main/res/drawable/heart.xml new file mode 100644 index 00000000000..36f5482c9f0 --- /dev/null +++ b/modules/features/endofyear/src/main/res/drawable/heart.xml @@ -0,0 +1,14 @@ + + + + From 99f9971f94c8adc74843b779d5a7543badd82aa3 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Sun, 13 Nov 2022 07:53:17 +0530 Subject: [PATCH 2/5] Fix accidental story speed issue Timer should not be running before it is started. --- .../com/shiftyjelly/pocketcasts/endofyear/StoriesViewModel.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesViewModel.kt b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesViewModel.kt index 0d867b2965e..95530c153b7 100644 --- a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesViewModel.kt +++ b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesViewModel.kt @@ -83,6 +83,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()) From 644425e44453930e962f01b98b3d10dc585d9200 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Sun, 13 Nov 2022 19:03:24 +0530 Subject: [PATCH 3/5] Improve pause behavior --- .../pocketcasts/endofyear/StoriesPage.kt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt index 1dc67820de9..01c521b5dfd 100644 --- a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt +++ b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt @@ -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) @@ -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() @@ -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 } } ) From 0d0224fa91b1568d3b2401d32daa8c08e973e3a0 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Sun, 13 Nov 2022 19:04:42 +0530 Subject: [PATCH 4/5] Replace failed stories hardcoded text --- .../au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt index 01c521b5dfd..76b29b65bc8 100644 --- a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt +++ b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/StoriesPage.kt @@ -304,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, ) }, From 622888025e56572648db4614a3c37cd7c87fe818 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Mon, 14 Nov 2022 06:21:10 +0530 Subject: [PATCH 5/5] Update background color --- .../pocketcasts/endofyear/utils/StoryModifierExtensions.kt | 5 ++++- .../endofyear/views/stories/StoryEpilogueView.kt | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/utils/StoryModifierExtensions.kt b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/utils/StoryModifierExtensions.kt index bab30da6ab9..04d6e01ef02 100644 --- a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/utils/StoryModifierExtensions.kt +++ b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/utils/StoryModifierExtensions.kt @@ -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 @@ -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, diff --git a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt index 16a9da303a8..fe6c2ea6499 100644 --- a/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt +++ b/modules/features/endofyear/src/main/java/au/com/shiftyjelly/pocketcasts/endofyear/views/stories/StoryEpilogueView.kt @@ -1,7 +1,6 @@ package au.com.shiftyjelly.pocketcasts.endofyear.views.stories import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -19,7 +18,6 @@ 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.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -28,10 +26,12 @@ 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.localization.R as LR private val HeartImageSize = 72.dp +private const val BackgroundColor = 0xFFFDDC68 @Composable fun StoryEpilogueView( @@ -44,7 +44,7 @@ fun StoryEpilogueView( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier .fillMaxSize() - .background(colorResource(id = R.color.black_26)) + .dynamicBackground(Color(BackgroundColor)) .verticalScroll(rememberScrollState()) ) { Spacer(modifier = modifier.height(40.dp))