From 84e8d7050d0617ccb4ff1ec0642fcb08923ec420 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Tue, 18 Oct 2022 16:31:44 +0530 Subject: [PATCH 1/4] Add end of year feature flag --- base.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base.gradle b/base.gradle index ce79c8f7aac..98202c4c699 100644 --- a/base.gradle +++ b/base.gradle @@ -27,6 +27,9 @@ android { buildConfigField "String", "SETTINGS_ENCRYPT_SECRET", "\"${project.settingsEncryptSecret}\"" buildConfigField "String", "SHARING_SERVER_SECRET", "\"${project.sharingServerSecret}\"" + // Feature Flags + buildConfigField "boolean", "END_OF_YEAR_ENABLED", "false" + testInstrumentationRunner project.testInstrumentationRunner testApplicationId "au.com.shiftyjelly.pocketcasts.test" + project.name.replace("-", "_") vectorDrawables.useSupportLibrary = true From db7d7948352cfc5e6d9c1707deb8bd13602a4a83 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Tue, 18 Oct 2022 16:56:15 +0530 Subject: [PATCH 2/4] Add compose modal bottom sheet --- .../compose/bottomsheet/BottomSheetContent.kt | 143 ++++++++++++++++++ .../compose/bottomsheet/ModalBottomSheet.kt | 51 +++++++ .../compose/components/TextStyles.kt | 10 +- 3 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt create mode 100644 modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/ModalBottomSheet.kt diff --git a/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt new file mode 100644 index 00000000000..1a25ec18dd1 --- /dev/null +++ b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt @@ -0,0 +1,143 @@ +package au.com.shiftyjelly.pocketcasts.compose.bottomsheet + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.material.Button +import androidx.compose.material.MaterialTheme +import androidx.compose.material.OutlinedButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +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 au.com.shiftyjelly.pocketcasts.compose.AppThemeWithBackground +import au.com.shiftyjelly.pocketcasts.compose.components.TextH40 +import au.com.shiftyjelly.pocketcasts.compose.components.TextP50 +import au.com.shiftyjelly.pocketcasts.compose.preview.ThemePreviewParameterProvider +import au.com.shiftyjelly.pocketcasts.compose.theme +import au.com.shiftyjelly.pocketcasts.ui.theme.Theme + +private val outlinedBorder: BorderStroke + @Composable + get() = BorderStroke(2.dp, MaterialTheme.colors.primary) + +class BottomSheetContentState( + val content: Content, +) { + data class Content( + val titleText: String, + val summaryText: String, + val primaryButton: Button.Primary, + val secondaryButton: Button.Secondary? = null, + ) { + sealed interface Button { + val label: String + val onClick: (() -> Unit)? + + data class Primary( + override val label: String, + override val onClick: () -> Unit, + ) : Button + + data class Secondary( + override val label: String, + override val onClick: (() -> Unit)? = null, + ) : Button + } + } +} + +@Composable +fun BottomSheetContent( + state: BottomSheetContentState, + onDismiss: () -> Unit, + modifier: Modifier = Modifier +) { + Box( + modifier = modifier + .fillMaxWidth() + .wrapContentWidth(unbounded = false) + .wrapContentHeight(unbounded = true) + .padding(24.dp) + ) { + Column( + modifier = modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val content = state.content + + Spacer(modifier = modifier.height(16.dp)) + + TextH40( + text = content.titleText, + color = MaterialTheme.theme.colors.primaryText01, + maxLines = 1 + ) + + Spacer(modifier = modifier.height(16.dp)) + + TextP50( + text = content.summaryText, + style = MaterialTheme.typography.body1, + color = MaterialTheme.theme.colors.primaryText02, + textAlign = TextAlign.Center + ) + + Spacer(modifier = modifier.height(16.dp)) + + Button(onClick = content.primaryButton.onClick) { + Text(text = content.primaryButton.label) + } + + Spacer(modifier = modifier.height(8.dp)) + + if (content.secondaryButton != null) { + OutlinedButton( + border = outlinedBorder, + onClick = { + onDismiss.invoke() + content.secondaryButton.onClick?.invoke() + } + ) { + Text(text = content.secondaryButton.label) + } + } + } + } +} + +@Preview(showBackground = true) +@Composable +private fun BottomSheetContentPreview( + @PreviewParameter(ThemePreviewParameterProvider::class) themeType: Theme.ThemeType, +) { + AppThemeWithBackground(themeType) { + BottomSheetContent( + state = BottomSheetContentState( + content = BottomSheetContentState.Content( + titleText = "Heading", + summaryText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + primaryButton = BottomSheetContentState.Content.Button.Primary( + label = "Confirm", + onClick = {} + ), + secondaryButton = BottomSheetContentState.Content.Button.Secondary( + label = "Not now", + ), + ) + ), + onDismiss = {} + ) + } +} diff --git a/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/ModalBottomSheet.kt b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/ModalBottomSheet.kt new file mode 100644 index 00000000000..816cb832458 --- /dev/null +++ b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/ModalBottomSheet.kt @@ -0,0 +1,51 @@ +package au.com.shiftyjelly.pocketcasts.compose.bottomsheet + +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun ModalBottomSheet( + showOnLoad: Boolean = false, + content: BottomSheetContentState.Content, +) { + val sheetState = rememberModalBottomSheetState( + initialValue = if (showOnLoad) ModalBottomSheetValue.Expanded else ModalBottomSheetValue.Hidden, + ) + val coroutineScope = rememberCoroutineScope() + + BackHandler(sheetState.isVisible) { + hideBottomSheet(coroutineScope, sheetState) + } + + ModalBottomSheetLayout( + sheetState = sheetState, + sheetContent = { + BottomSheetContent( + state = BottomSheetContentState(content), + onDismiss = { + hideBottomSheet(coroutineScope, sheetState) + } + ) + }, + sheetShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), + content = {} + ) +} + +@OptIn(ExperimentalMaterialApi::class) +fun hideBottomSheet(coroutineScope: CoroutineScope, sheetState: ModalBottomSheetState) { + coroutineScope.launch { + sheetState.hide() + } +} diff --git a/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/components/TextStyles.kt b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/components/TextStyles.kt index ff4897ac235..56620e7529e 100644 --- a/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/components/TextStyles.kt +++ b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/components/TextStyles.kt @@ -130,14 +130,16 @@ fun TextP50( modifier: Modifier = Modifier, color: Color? = null, maxLines: Int? = null, - style: TextStyle? = null + style: TextStyle? = null, + textAlign: TextAlign? = null, ) { TextP50( text = AnnotatedString(text), modifier = modifier, color = color, maxLines = maxLines, - style = style + style = style, + textAlign = textAlign, ) } @@ -147,7 +149,8 @@ fun TextP50( modifier: Modifier = Modifier, color: Color? = null, maxLines: Int? = null, - style: TextStyle? = null + style: TextStyle? = null, + textAlign: TextAlign? = null, ) { Text( text = text, @@ -157,6 +160,7 @@ fun TextP50( maxLines = maxLines ?: Int.MAX_VALUE, overflow = TextOverflow.Ellipsis, style = style ?: LocalTextStyle.current, + textAlign = textAlign, modifier = modifier ) } From 231bc2cafa1a18f55fd2fe0e78e28c8eab41376b Mon Sep 17 00:00:00 2001 From: ashiagr Date: Tue, 18 Oct 2022 16:29:31 +0530 Subject: [PATCH 3/4] Show end of year launch modal bottom sheet --- .../pocketcasts/ui/MainActivity.kt | 30 +++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 6 ++++ .../compose/bottomsheet/ModalBottomSheet.kt | 2 ++ .../src/main/res/values/strings.xml | 7 +++++ 4 files changed, 45 insertions(+) diff --git a/app/src/main/java/au/com/shiftyjelly/pocketcasts/ui/MainActivity.kt b/app/src/main/java/au/com/shiftyjelly/pocketcasts/ui/MainActivity.kt index 85496b3209f..1fc7e1a65ff 100644 --- a/app/src/main/java/au/com/shiftyjelly/pocketcasts/ui/MainActivity.kt +++ b/app/src/main/java/au/com/shiftyjelly/pocketcasts/ui/MainActivity.kt @@ -12,6 +12,7 @@ import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.widget.Toolbar +import androidx.compose.ui.res.stringResource import androidx.core.view.isVisible import androidx.core.view.updatePadding import androidx.fragment.app.Fragment @@ -26,6 +27,10 @@ import au.com.shiftyjelly.pocketcasts.account.PromoCodeUpgradedFragment import au.com.shiftyjelly.pocketcasts.analytics.AnalyticsEvent import au.com.shiftyjelly.pocketcasts.analytics.AnalyticsTrackerWrapper import au.com.shiftyjelly.pocketcasts.analytics.FirebaseAnalyticsTracker +import au.com.shiftyjelly.pocketcasts.compose.AppTheme +import au.com.shiftyjelly.pocketcasts.compose.bottomsheet.BottomSheetContentState +import au.com.shiftyjelly.pocketcasts.compose.bottomsheet.BottomSheetContentState.Content.Button +import au.com.shiftyjelly.pocketcasts.compose.bottomsheet.ModalBottomSheet import au.com.shiftyjelly.pocketcasts.databinding.ActivityMainBinding import au.com.shiftyjelly.pocketcasts.discover.view.DiscoverFragment import au.com.shiftyjelly.pocketcasts.filters.FiltersFragment @@ -249,6 +254,10 @@ class MainActivity : handleIntent(intent, savedInstanceState) updateSystemColors() + + if (BuildConfig.END_OF_YEAR_ENABLED) { + setupEndOfYearLaunchBottomSheet() + } } override fun onStart() { @@ -446,6 +455,27 @@ class MainActivity : showBottomSheet(UpNextFragment.newInstance(source = source)) } + private fun setupEndOfYearLaunchBottomSheet() { + binding.modalBottomSheet.setContent { + AppTheme(themeType = theme.activeTheme) { + ModalBottomSheet( + showOnLoad = true, + content = BottomSheetContentState.Content( + titleText = stringResource(LR.string.end_of_year_launch_modal_title), + summaryText = stringResource(LR.string.end_of_year_launch_modal_summary), + primaryButton = Button.Primary( + label = stringResource(LR.string.end_of_year_launch_modal_primary_button_title), + onClick = {} + ), + secondaryButton = Button.Secondary( + label = stringResource(LR.string.end_of_year_launch_modal_secondary_button_title), + ), + ) + ) + } + } + } + @OptIn(DelicateCoroutinesApi::class) @Suppress("DEPRECATION") private fun setupPlayerViews() { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e79fec5d026..b7a99246bec 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -62,6 +62,12 @@ android:clickable="true" android:translationZ="200dp"/> + + You have exceeded the storage limit for your account. Title is required. + + + Your Year in Podcasts + See your top podcasts, categories, listening stats and more. Share with friends and shout out your favorite creators! + View my 2022 + Not Now + From cf006e6af2bf6814b430f28ab1942e27cc675077 Mon Sep 17 00:00:00 2001 From: ashiagr Date: Wed, 19 Oct 2022 13:24:24 +0530 Subject: [PATCH 4/4] Remove maxLines --- .../pocketcasts/compose/bottomsheet/BottomSheetContent.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt index 1a25ec18dd1..a8515894f70 100644 --- a/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt +++ b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/BottomSheetContent.kt @@ -82,7 +82,6 @@ fun BottomSheetContent( TextH40( text = content.titleText, color = MaterialTheme.theme.colors.primaryText01, - maxLines = 1 ) Spacer(modifier = modifier.height(16.dp))