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! ☕️