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"/>
+
+
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,
+ )
+
+ 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..7befed55269
--- /dev/null
+++ b/modules/services/compose/src/main/java/au/com/shiftyjelly/pocketcasts/compose/bottomsheet/ModalBottomSheet.kt
@@ -0,0 +1,53 @@
+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.graphics.Color
+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),
+ scrimColor = Color.Black.copy(alpha = .25f),
+ 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
)
}
diff --git a/modules/services/localization/src/main/res/values/strings.xml b/modules/services/localization/src/main/res/values/strings.xml
index bd50f74f81e..d6fa6be4df1 100644
--- a/modules/services/localization/src/main/res/values/strings.xml
+++ b/modules/services/localization/src/main/res/values/strings.xml
@@ -1378,4 +1378,11 @@
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
+