diff --git a/commons/src/main/AndroidManifest.xml b/commons/src/main/AndroidManifest.xml
index 5b7a39e79..1c15af909 100644
--- a/commons/src/main/AndroidManifest.xml
+++ b/commons/src/main/AndroidManifest.xml
@@ -57,6 +57,11 @@
android:exported="false"
android:label="@string/manage_blocked_numbers" />
+
+
{
val showWebsite = remember { resources.getBoolean(R.bool.show_donate_in_about) && !showExternalLinks }
var version = intent.getStringExtra(APP_VERSION_NAME) ?: ""
@@ -170,7 +170,7 @@ class AboutActivity : ComponentActivity() {
}
private fun onEmailClick(
- showConfirmationAdvancedDialog: () -> Unit
+ showConfirmationAdvancedDialog: () -> Unit,
) {
if (intent.getBooleanExtra(SHOW_FAQ_BEFORE_MAIL, false) && !baseConfig.wasBeforeAskingShown) {
baseConfig.wasBeforeAskingShown = true
@@ -228,7 +228,7 @@ class AboutActivity : ComponentActivity() {
private fun onRateUsClick(
showConfirmationAdvancedDialog: () -> Unit,
- showRateStarsDialog: () -> Unit
+ showRateStarsDialog: () -> Unit,
) {
if (baseConfig.wasBeforeRateShown) {
launchRateUsPrompt(showRateStarsDialog)
@@ -239,7 +239,7 @@ class AboutActivity : ComponentActivity() {
}
private fun launchRateUsPrompt(
- showRateStarsDialog: () -> Unit
+ showRateStarsDialog: () -> Unit,
) {
if (baseConfig.wasAppRated) {
redirectToRateUs()
@@ -266,7 +266,7 @@ class AboutActivity : ComponentActivity() {
private fun onDonateClick() {
- launchViewIntent(getString(R.string.donate_url))
+ startActivity(Intent(applicationContext, DonationActivity::class.java))
}
private fun onGithubClick() {
diff --git a/commons/src/main/kotlin/org/fossify/commons/activities/DonationActivity.kt b/commons/src/main/kotlin/org/fossify/commons/activities/DonationActivity.kt
new file mode 100644
index 000000000..0a8ee107b
--- /dev/null
+++ b/commons/src/main/kotlin/org/fossify/commons/activities/DonationActivity.kt
@@ -0,0 +1,38 @@
+package org.fossify.commons.activities
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.ui.platform.LocalClipboardManager
+import androidx.compose.ui.text.AnnotatedString
+import org.fossify.commons.R
+import org.fossify.commons.compose.extensions.enableEdgeToEdgeSimple
+import org.fossify.commons.compose.screens.donation.DonationScreen
+import org.fossify.commons.compose.screens.donation.FossifyCryptoAddresses
+import org.fossify.commons.compose.screens.donation.FossifyDonationPlatforms
+import org.fossify.commons.compose.theme.AppThemeSurface
+import org.fossify.commons.extensions.openWebsiteIntent
+import org.fossify.commons.extensions.toast
+
+class DonationActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdgeSimple()
+ setContent {
+ val clipboardManager = LocalClipboardManager.current
+ AppThemeSurface {
+ DonationScreen(
+ donationOptions = FossifyDonationPlatforms,
+ cryptoAddresses = FossifyCryptoAddresses,
+ goBack = ::finish,
+ openWebsite = ::openWebsiteIntent,
+ copyToClipboard = {
+ clipboardManager.setText(AnnotatedString(it))
+ toast(R.string.value_copied_to_clipboard)
+ },
+ )
+ }
+ }
+ }
+}
diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/screens/AboutScreen.kt b/commons/src/main/kotlin/org/fossify/commons/compose/screens/AboutScreen.kt
index 8ac98be3c..c3d97c865 100644
--- a/commons/src/main/kotlin/org/fossify/commons/compose/screens/AboutScreen.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/compose/screens/AboutScreen.kt
@@ -63,8 +63,8 @@ internal fun HelpUsSection(
if (showDonate) {
TwoLinerTextItem(
click = onDonateClick,
- text = stringResource(id = R.string.donate),
- icon = R.drawable.ic_dollar_vector
+ text = stringResource(id = R.string.donate_to_fossify),
+ icon = R.drawable.ic_donate_vector
)
}
SettingsHorizontalDivider()
@@ -126,7 +126,7 @@ internal fun OtherSection(
internal fun AboutSection(
setupFAQ: Boolean,
onFAQClick: () -> Unit,
- onEmailClick: () -> Unit
+ onEmailClick: () -> Unit,
) {
SettingsGroup(title = {
SettingsTitleTextComponent(text = stringResource(id = R.string.support), modifier = startingTitlePadding)
@@ -151,7 +151,7 @@ internal fun AboutSection(
internal fun SocialSection(
onGithubClick: () -> Unit,
onRedditClick: () -> Unit,
- onTelegramClick: () -> Unit
+ onTelegramClick: () -> Unit,
) {
SettingsGroup(title = {
SettingsTitleTextComponent(text = stringResource(id = R.string.social), modifier = startingTitlePadding)
@@ -181,7 +181,7 @@ internal fun SocialText(
text: String,
icon: Int,
tint: Color? = null,
- click: () -> Unit
+ click: () -> Unit,
) {
SettingsListItem(
click = click,
diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/screens/donation/DonationData.kt b/commons/src/main/kotlin/org/fossify/commons/compose/screens/donation/DonationData.kt
new file mode 100644
index 000000000..269f575f2
--- /dev/null
+++ b/commons/src/main/kotlin/org/fossify/commons/compose/screens/donation/DonationData.kt
@@ -0,0 +1,75 @@
+package org.fossify.commons.compose.screens.donation
+
+import org.fossify.commons.R
+
+sealed class Donation {
+ data class Platform(
+ val fee: Int,
+ val icon: Int,
+ val link: String,
+ val name: String,
+ ) : Donation()
+
+ data class Crypto(
+ val address: String,
+ val icon: Int,
+ val name: String,
+ ) : Donation()
+}
+
+val FossifyDonationPlatforms = listOf(
+ Donation.Platform(
+ fee = 0,
+ icon = R.drawable.ic_github_tinted_vector,
+ link = "https://github.com/sponsors/FossifyOrg",
+ name = "GitHub Sponsors"
+ ),
+ Donation.Platform(
+ fee = 0,
+ icon = R.drawable.ic_liberapay_vector,
+ link = "https://liberapay.com/naveensingh",
+ name = "Liberapay"
+ ),
+ Donation.Platform(
+ fee = 10,
+ icon = R.drawable.ic_open_collective_vector,
+ link = "https://opencollective.com/fossify/donate?interval=month&amount=20",
+ name = "OpenCollective"
+ ),
+ Donation.Platform(
+ fee = 10,
+ icon = R.drawable.ic_patreon_vector,
+ link = "https://www.patreon.com/naveen3singh",
+ name = "Patreon"
+ ),
+ Donation.Platform(
+ fee = 5,
+ icon = R.drawable.ic_paypal_vector,
+ link = "https://paypal.me/naveen3singh",
+ name = "PayPal"
+ ),
+)
+
+@Suppress("SpellCheckingInspection")
+val FossifyCryptoAddresses = listOf(
+ Donation.Crypto(
+ address = "bc1qn5h97qdqsazpzvxm7gryke6vmrcx85t7neqp95",
+ icon = R.drawable.ic_bitcoin_vector,
+ name = "Bitcoin (BTC)"
+ ),
+ Donation.Crypto(
+ address = "0x9354fC372BC3BdA58766a8a9Fabadf77A76CdE01",
+ icon = R.drawable.ic_ethereum_vector,
+ name = "Ethereum (ETH)"
+ ),
+ Donation.Crypto(
+ address = "48FkVUcJ7AGeBMR4SC4J7QU5nAt6YNwKZWz6sGDT1s5haEY7reZtJr5CniXLaQzTzGAuZNoc83BQAcETHw1d3Lkn8AAf1XF",
+ icon = R.drawable.ic_monero_vector,
+ name = "Monero (XMR)"
+ ),
+ Donation.Crypto(
+ address = "TGi4VpD1D9A9ZvyP9d3aVowwzMSvev2hub",
+ icon = R.drawable.ic_tron_vector,
+ name = "Tron (TRX)"
+ )
+)
diff --git a/commons/src/main/kotlin/org/fossify/commons/compose/screens/donation/DonationScreen.kt b/commons/src/main/kotlin/org/fossify/commons/compose/screens/donation/DonationScreen.kt
new file mode 100644
index 000000000..71b464a36
--- /dev/null
+++ b/commons/src/main/kotlin/org/fossify/commons/compose/screens/donation/DonationScreen.kt
@@ -0,0 +1,163 @@
+package org.fossify.commons.compose.screens.donation
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.ContentCopy
+import androidx.compose.material3.Icon
+import androidx.compose.material3.ListItem
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import org.fossify.commons.R
+import org.fossify.commons.compose.lists.SimpleColumnScaffold
+import org.fossify.commons.compose.settings.SettingsGroup
+import org.fossify.commons.compose.settings.SettingsHorizontalDivider
+import org.fossify.commons.compose.settings.SettingsTitleTextComponent
+import org.fossify.commons.compose.theme.Shapes
+import org.fossify.commons.compose.theme.SimpleTheme
+import org.fossify.commons.compose.theme.textSubTitleColor
+
+@Composable
+fun DonationScreen(
+ donationOptions: List,
+ cryptoAddresses: List,
+ goBack: () -> Unit,
+ openWebsite: (String) -> Unit,
+ copyToClipboard: (String) -> Unit,
+) {
+ SimpleColumnScaffold(title = stringResource(id = R.string.donate_to_fossify), goBack = goBack) {
+ DonationPlatforms(
+ options = donationOptions,
+ copyToClipboard = copyToClipboard,
+ openWebsite = openWebsite
+ )
+
+ SettingsHorizontalDivider()
+
+ DonationCryptos(
+ options = cryptoAddresses,
+ copyToClipboard = copyToClipboard,
+ )
+ }
+}
+
+@Composable
+fun DonationPlatforms(
+ options: List,
+ openWebsite: (String) -> Unit,
+ copyToClipboard: (String) -> Unit,
+) {
+ SettingsGroup(title = {
+ SettingsTitleTextComponent(
+ text = stringResource(id = R.string.platforms),
+ modifier = Modifier
+ .padding(start = 56.dp)
+ )
+ }) {
+ options.forEach {
+ DonationListItem(
+ name = it.name,
+ description = if (it.fee == 0) {
+ stringResource(id = R.string.little_to_no_fee)
+ } else {
+ stringResource(R.string.fee_up_to_pct, it.fee)
+ },
+ icon = it.icon,
+ onClick = { openWebsite(it.link) },
+ onCopyClick = { copyToClipboard(it.link) },
+ )
+ }
+ }
+}
+
+@Composable
+fun DonationCryptos(
+ options: List,
+ copyToClipboard: (String) -> Unit,
+) {
+ SettingsGroup(title = {
+ SettingsTitleTextComponent(
+ text = stringResource(id = R.string.cryptocurrency),
+ modifier = Modifier
+ .padding(start = 56.dp)
+ )
+ }) {
+ options.forEach {
+ DonationListItem(
+ name = it.name,
+ description = it.address,
+ icon = it.icon,
+ onClick = { copyToClipboard(it.address) },
+ onCopyClick = { copyToClipboard(it.address) },
+ )
+ }
+ }
+}
+
+@Composable
+fun DonationListItem(
+ name: String,
+ description: String,
+ @DrawableRes icon: Int,
+ onClick: () -> Unit,
+ onCopyClick: () -> Unit,
+) {
+ ListItem(
+ modifier = Modifier
+ .clickable(onClick = onClick),
+ headlineContent = {
+ Text(
+ text = name,
+ modifier = Modifier
+ .fillMaxWidth(),
+ )
+ },
+ leadingContent = {
+ Image(
+ modifier = Modifier
+ .size(SimpleTheme.dimens.icon.medium),
+ painter = painterResource(id = icon),
+ contentDescription = name,
+ )
+ },
+ supportingContent = {
+ Text(
+ text = description,
+ style = SimpleTheme.typography.bodyMedium.copy(color = textSubTitleColor)
+ )
+ },
+ trailingContent = {
+ Icon(
+ imageVector = Icons.Rounded.ContentCopy,
+ contentDescription = stringResource(id = R.string.copy_to_clipboard),
+ tint = SimpleTheme.colorScheme.primary,
+ modifier = Modifier
+ .clip(Shapes.extraLarge)
+ .clickable(onClick = onCopyClick)
+ .padding(12.dp),
+ )
+ }
+ )
+}
+
+@Composable
+@Preview
+fun PreviewDonationScreen() {
+ DonationScreen(
+ donationOptions = FossifyDonationPlatforms,
+ cryptoAddresses = FossifyCryptoAddresses,
+ goBack = {},
+ openWebsite = {},
+ copyToClipboard = {},
+ )
+}
diff --git a/commons/src/main/res/drawable/ic_bitcoin_vector.xml b/commons/src/main/res/drawable/ic_bitcoin_vector.xml
new file mode 100644
index 000000000..1d5d7223a
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_bitcoin_vector.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_donate_vector.xml b/commons/src/main/res/drawable/ic_donate_vector.xml
new file mode 100644
index 000000000..64929b77a
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_donate_vector.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/commons/src/main/res/drawable/ic_ethereum_vector.xml b/commons/src/main/res/drawable/ic_ethereum_vector.xml
new file mode 100644
index 000000000..48828b65a
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_ethereum_vector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_github_tinted_vector.xml b/commons/src/main/res/drawable/ic_github_tinted_vector.xml
new file mode 100644
index 000000000..6ce798247
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_github_tinted_vector.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_liberapay_vector.xml b/commons/src/main/res/drawable/ic_liberapay_vector.xml
new file mode 100644
index 000000000..bbacd41f2
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_liberapay_vector.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_monero_vector.xml b/commons/src/main/res/drawable/ic_monero_vector.xml
new file mode 100644
index 000000000..571360413
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_monero_vector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_open_collective_vector.xml b/commons/src/main/res/drawable/ic_open_collective_vector.xml
new file mode 100644
index 000000000..18242a286
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_open_collective_vector.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_patreon_vector.xml b/commons/src/main/res/drawable/ic_patreon_vector.xml
new file mode 100644
index 000000000..23af9bb8c
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_patreon_vector.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_paypal_vector.xml b/commons/src/main/res/drawable/ic_paypal_vector.xml
new file mode 100644
index 000000000..400b4218b
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_paypal_vector.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/commons/src/main/res/drawable/ic_tron_vector.xml b/commons/src/main/res/drawable/ic_tron_vector.xml
new file mode 100644
index 000000000..be9f7944e
--- /dev/null
+++ b/commons/src/main/res/drawable/ic_tron_vector.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/commons/src/main/res/values/strings.xml b/commons/src/main/res/values/strings.xml
index 4eebdc3ce..d2eb2d122 100644
--- a/commons/src/main/res/values/strings.xml
+++ b/commons/src/main/res/values/strings.xml
@@ -975,6 +975,13 @@
]]>
+
+ Donate to Fossify
+ Platforms
+ Little to no fee
+ Up to %1$d%% fee
+ Cryptocurrency
+
Frequently asked questions
Before you ask a question, please first read the