From 82e06daea44895f1fa24f7a60ad40ecc3da3313f Mon Sep 17 00:00:00 2001 From: junkfood <69683722+JunkFood02@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:38:55 +0800 Subject: [PATCH] feat(ui): add sponsor dialog --- .../ui/page/settings/tips/SponsorDialog.kt | 134 ++++++++++++++++++ .../page/settings/tips/TipsAndSupportPage.kt | 7 +- app/src/main/res/values/strings.xml | 2 + 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/me/ash/reader/ui/page/settings/tips/SponsorDialog.kt diff --git a/app/src/main/java/me/ash/reader/ui/page/settings/tips/SponsorDialog.kt b/app/src/main/java/me/ash/reader/ui/page/settings/tips/SponsorDialog.kt new file mode 100644 index 00000000..458380f9 --- /dev/null +++ b/app/src/main/java/me/ash/reader/ui/page/settings/tips/SponsorDialog.kt @@ -0,0 +1,134 @@ +package me.ash.reader.ui.page.settings.tips + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +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.shape.CircleShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import me.ash.reader.R +import me.ash.reader.infrastructure.preference.OpenLinkPreference +import me.ash.reader.ui.component.base.RYAsyncImage +import me.ash.reader.ui.ext.openURL + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SponsorDialog(modifier: Modifier = Modifier, onDismissRequest: () -> Unit) { + ModalBottomSheet(modifier = modifier, onDismissRequest = onDismissRequest) { + SponsorDialogContent() + } +} + + +private fun githubAvatar(login: String): String = "https://github.com/${login}.png" + +@Composable +private fun SponsorDialogContent(modifier: Modifier = Modifier) { + val context = LocalContext.current + Column(modifier = modifier) { + Column( + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(bottom = 16.dp) + ) { + Text( + text = stringResource(R.string.become_a_sponsor), + style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.Medium), + ) + Spacer(Modifier.height(12.dp)) + Text( + text = stringResource(R.string.sponsor_desc), + style = MaterialTheme.typography.bodyMedium, + ) + } + + SponsorItem( + model = githubAvatar("Ashinch"), + name = "Ash", + description = "Lead Developer", + ) { + context.openURL("https://ash7.io/sponsor/", openLink = OpenLinkPreference.default) + } + SponsorItem( + model = githubAvatar("JunkFood02"), + name = "junkfood", + description = "Maintainer", + ) { + context.openURL( + "https://github.com/sponsors/JunkFood02", + openLink = OpenLinkPreference.default + ) + } + Spacer(Modifier.height(8.dp)) + } +} + +@Composable +private fun SponsorItem( + modifier: Modifier = Modifier, + model: Any?, + name: String, + description: String, + onClick: () -> Unit, +) { + val interactionSource = remember { MutableInteractionSource() } + Row( + modifier = + modifier + .fillMaxWidth() + .clickable( + enabled = true, + indication = null, + interactionSource = interactionSource, + onClick = onClick, + ) + .padding(vertical = 12.dp) + .padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + RYAsyncImage( + data = model, + modifier = Modifier + .size(64.dp) + .aspectRatio(1f) + .clip(CircleShape), + contentScale = ContentScale.Crop, + ) + Column( + modifier = Modifier + .weight(1f) + .padding(start = 16.dp) + ) { + Text(name, style = MaterialTheme.typography.titleMedium) + Spacer(Modifier.height(4.dp)) + Text( + description, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + FilledTonalButton(onClick = onClick, interactionSource = interactionSource) { + Text(stringResource(R.string.sponsor)) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/page/settings/tips/TipsAndSupportPage.kt b/app/src/main/java/me/ash/reader/ui/page/settings/tips/TipsAndSupportPage.kt index da494443..19b63a0f 100644 --- a/app/src/main/java/me/ash/reader/ui/page/settings/tips/TipsAndSupportPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/settings/tips/TipsAndSupportPage.kt @@ -85,6 +85,8 @@ fun TipsAndSupportPage( targetValue = pressAMP, animationSpec = tween() ) + + var showSponsorDialog by remember { mutableStateOf(false) } LaunchedEffect(Unit) { currentVersion = context.getCurrentVersion().toString() @@ -210,7 +212,7 @@ fun TipsAndSupportPage( ) { view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP) view.playSoundEffect(SoundEffectConstants.CLICK) - context.showToast(context.getString(R.string.coming_soon)) + showSponsorDialog = true }) Spacer(modifier = Modifier.width(16.dp)) @@ -250,6 +252,9 @@ fun TipsAndSupportPage( ) UpdateDialog() + if (showSponsorDialog) { + SponsorDialog { showSponsorDialog = false } + } } @Immutable diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ac023b1..501eb1f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -458,4 +458,6 @@ bionic-reading.com https://bionic-reading.com Mark as read on scroll + Become a sponsor + We build and upkeep this free, open-source app in our off-hours. If you enjoy it, please consider supporting us with a small donation! ☕️