Skip to content

Commit f0b2cde

Browse files
Merge pull request #356 from trinadhthatakula/feat/support-kofi-buymeacoffee
feat(support): offer Ko-fi and Buy Me a Coffee in the app, like the site already does
2 parents 8968321 + 909c32a commit f0b2cde

10 files changed

Lines changed: 151 additions & 8 deletions

File tree

app/src/foss/java/com/valhalla/thor/presentation/settings/SupportDeveloperHelper.kt

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,20 @@ fun SupportDeveloperHelper(
2323
val sponsorsDesc = stringResource(R.string.sponsor_github_desc)
2424
val patreonTitle = stringResource(R.string.become_patreon_title)
2525
val patreonDesc = stringResource(R.string.become_patreon_desc)
26+
val kofiTitle = stringResource(R.string.support_kofi_title)
27+
val kofiDesc = stringResource(R.string.support_kofi_desc)
28+
val coffeeTitle = stringResource(R.string.buy_me_a_coffee_title)
29+
val coffeeDesc = stringResource(R.string.buy_me_a_coffee_desc)
2630
val paypalTitle = stringResource(R.string.donate_paypal_title)
2731
val paypalDesc = stringResource(R.string.donate_paypal_desc)
2832

2933
val actions = remember(
30-
sponsorsTitle, sponsorsDesc, patreonTitle, patreonDesc, paypalTitle, paypalDesc
34+
sponsorsTitle, sponsorsDesc, patreonTitle, patreonDesc,
35+
kofiTitle, kofiDesc, coffeeTitle, coffeeDesc, paypalTitle, paypalDesc
3136
) {
3237
listOf(
33-
// First deliberately: lowest fees of the three, and it sits beside the source, which is
34-
// where a FOSS user already is.
38+
// First deliberately: lowest fees of the five, and it sits beside the source, which is
39+
// where a FOSS user already is. After it, recurring-capable before one-off.
3540
SupportAction(
3641
iconRes = R.drawable.brand_github,
3742
title = sponsorsTitle,
@@ -55,6 +60,26 @@ fun SupportDeveloperHelper(
5560
onDismiss()
5661
}
5762
),
63+
SupportAction(
64+
iconRes = R.drawable.brand_kofi,
65+
title = kofiTitle,
66+
description = kofiDesc,
67+
onClick = {
68+
val intent = Intent(Intent.ACTION_VIEW, "https://ko-fi.com/trinadh".toUri())
69+
runCatching { context.startActivity(intent) }
70+
onDismiss()
71+
}
72+
),
73+
SupportAction(
74+
iconRes = R.drawable.brand_buymeacoffee,
75+
title = coffeeTitle,
76+
description = coffeeDesc,
77+
onClick = {
78+
val intent = Intent(Intent.ACTION_VIEW, "https://www.buymeacoffee.com/trinadh".toUri())
79+
runCatching { context.startActivity(intent) }
80+
onDismiss()
81+
}
82+
),
5883
SupportAction(
5984
iconRes = R.drawable.shield_with_heart,
6085
title = paypalTitle,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!-- SPDX-FileCopyrightText: 2025-2026 Trinadh Thatakula <github.com/trinadhthatakula/Thor> -->
2+
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
3+
<!--
4+
A lidded takeaway cup with steam. Not Buy Me a Coffee's trademark — see brand_kofi for why a brand
5+
mark is not an option here. The silhouette is deliberately NOT a mug: brand_kofi sits directly
6+
above this one in the support sheet, and two coffee cups that differ only in their detail are two
7+
identical smudges at 24dp. Lid + taper + steam against mug + handle + saucer reads apart at a
8+
glance.
9+
10+
The steam is stroked rather than filled. Icon(tint = ...) applies a ColorFilter over the whole
11+
drawable, so strokeColor is tinted along with fillColor — no fillColor is needed on those paths.
12+
-->
13+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
14+
android:width="24dp"
15+
android:height="24dp"
16+
android:viewportWidth="24"
17+
android:viewportHeight="24">
18+
<path
19+
android:strokeColor="#000000"
20+
android:strokeWidth="1.5"
21+
android:strokeLineCap="round"
22+
android:pathData="M8.4,2.2 c1,1 -1,1.9 0,2.9" />
23+
<path
24+
android:strokeColor="#000000"
25+
android:strokeWidth="1.5"
26+
android:strokeLineCap="round"
27+
android:pathData="M12,1.7 c1,1 -1,1.9 0,2.9" />
28+
<path
29+
android:strokeColor="#000000"
30+
android:strokeWidth="1.5"
31+
android:strokeLineCap="round"
32+
android:pathData="M15.6,2.2 c1,1 -1,1.9 0,2.9" />
33+
<path
34+
android:fillColor="#000000"
35+
android:pathData="M4.9,6.9 h14.2 a1.3,1.3 0 0 1 1.29,1.44 l-0.13,1.2 a1.3,1.3 0 0 1 -1.29,1.16 H4.99 a1.3,1.3 0 0 1 -1.29,-1.16 l-0.13,-1.2 A1.3,1.3 0 0 1 4.9,6.9 z" />
36+
<path
37+
android:fillColor="#000000"
38+
android:pathData="M5.15,10.4 h13.7 l-1.2,9.4 a2.1,2.1 0 0 1 -2.08,1.8 H8.43 a2.1,2.1 0 0 1 -2.08,-1.8 z" />
39+
</vector>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!-- SPDX-FileCopyrightText: 2025-2026 Trinadh Thatakula <github.com/trinadhthatakula/Thor> -->
2+
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
3+
<!--
4+
A mug with a heart, on a saucer. Not Ko-fi's trademark: SupportDeveloperBottomSheet draws every
5+
action icon with Icon(tint = colorScheme.primary), so a brand mark could never keep its brand
6+
colour anyway — the same reason PayPal already uses the generic shield_with_heart. It only has to
7+
read as "Ko-fi" beside its own label, and to be distinguishable from brand_buymeacoffee one row
8+
below, which is a lidded takeaway cup with steam.
9+
10+
fillType="evenOdd" is load-bearing: it is what makes the heart a HOLE in the cup. Everything here
11+
is drawn in one tint, so a heart drawn as a second filled subpath would be invisible.
12+
-->
13+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
14+
android:width="24dp"
15+
android:height="24dp"
16+
android:viewportWidth="24"
17+
android:viewportHeight="24">
18+
<path
19+
android:fillColor="#000000"
20+
android:fillType="evenOdd"
21+
android:pathData="M4,4 h12 a1,1 0 0 1 1,1 v7 a5,5 0 0 1 -5,5 H8 a5,5 0 0 1 -5,-5 V5 a1,1 0 0 1 1,-1 z M10,14.1 C10,14.1 5.9,11.4 5.9,8.85 C5.9,7.55 6.95,6.5 8.2,6.5 C8.95,6.5 9.65,6.9 10,7.45 C10.35,6.9 11.05,6.5 11.8,6.5 C13.05,6.5 14.1,7.55 14.1,8.85 C14.1,11.4 10,14.1 10,14.1 Z" />
22+
<path
23+
android:fillColor="#000000"
24+
android:pathData="M17,6.2 h1.6 a3.4,3.4 0 0 1 0,6.8 H17 v-2 h1.6 a1.4,1.4 0 0 0 0,-2.8 H17 z" />
25+
<path
26+
android:fillColor="#000000"
27+
android:pathData="M3.2,18.6 h13.6 a1.2,1.2 0 0 1 0,2.4 H3.2 a1.2,1.2 0 0 1 0,-2.4 z" />
28+
</vector>

app/src/main/res/values-ar/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,10 @@
433433
<string name="sponsor_github_desc">تبرع لمرة واحدة أو شهريًا، بجانب الشيفرة المصدرية مباشرة</string>
434434
<string name="become_patreon_title">كن داعمًا على Patreon</string>
435435
<string name="become_patreon_desc">دعم التطوير المستمر باشتراك شهري</string>
436+
<string name="support_kofi_title">الدعم عبر Ko-fi</string>
437+
<string name="support_kofi_desc">اشترِ قهوة مرة واحدة أو كل شهر</string>
438+
<string name="buy_me_a_coffee_title">الدعم عبر Buy Me a Coffee</string>
439+
<string name="buy_me_a_coffee_desc">قهوة لمرة واحدة أو عضوية شهرية</string>
436440
<string name="donate_paypal_title">التبرع عبر PayPal</string>
437441
<string name="donate_paypal_desc">أرسل تبرعًا لمرة واحدة مباشرة</string>
438442

app/src/main/res/values-es/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,10 @@
399399
<string name="sponsor_github_desc">Puntual o mensual, justo al lado del código</string>
400400
<string name="become_patreon_title">Hacerse Patreon</string>
401401
<string name="become_patreon_desc">Apoya el desarrollo continuo con una suscripción mensual</string>
402+
<string name="support_kofi_title">Apoyar en Ko-fi</string>
403+
<string name="support_kofi_desc">Invita a un café, una vez o cada mes</string>
404+
<string name="buy_me_a_coffee_title">Apoyar en Buy Me a Coffee</string>
405+
<string name="buy_me_a_coffee_desc">Un café puntual o una membresía mensual</string>
402406
<string name="donate_paypal_title">Donar a través de PayPal</string>
403407
<string name="donate_paypal_desc">Envía una donación única directamente</string>
404408

app/src/main/res/values-fr/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,10 @@
399399
<string name="sponsor_github_desc">Ponctuel ou mensuel, au plus près du code</string>
400400
<string name="become_patreon_title">Devenir Patreon</string>
401401
<string name="become_patreon_desc">Soutenir le développement continu avec un abonnement mensuel</string>
402+
<string name="support_kofi_title">Soutenir sur Ko-fi</string>
403+
<string name="support_kofi_desc">Offrir un café, une fois ou chaque mois</string>
404+
<string name="buy_me_a_coffee_title">Soutenir sur Buy Me a Coffee</string>
405+
<string name="buy_me_a_coffee_desc">Un café ponctuel ou un abonnement mensuel</string>
402406
<string name="donate_paypal_title">Faire un don via PayPal</string>
403407
<string name="donate_paypal_desc">Envoyer un don unique directement</string>
404408

app/src/main/res/values-zh-rCN/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,10 @@
391391
<string name="sponsor_github_desc">一次性或按月赞助,就在代码旁边</string>
392392
<string name="become_patreon_title">成为 Patreon 赞助者</string>
393393
<string name="become_patreon_desc">通过按月订阅支持持续开发</string>
394+
<string name="support_kofi_title">在 Ko-fi 上支持</string>
395+
<string name="support_kofi_desc">请我喝杯咖啡,一次或每月</string>
396+
<string name="buy_me_a_coffee_title">在 Buy Me a Coffee 上支持</string>
397+
<string name="buy_me_a_coffee_desc">单次请我喝杯咖啡,或按月成为会员</string>
394398
<string name="donate_paypal_title">通过 PayPal 捐赠</string>
395399
<string name="donate_paypal_desc">直接发送一次性捐赠</string>
396400

app/src/main/res/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,10 @@
540540
<string name="sponsor_github_desc">One-off or monthly, right next to the code</string>
541541
<string name="become_patreon_title">Become a Patreon</string>
542542
<string name="become_patreon_desc">Support ongoing development with a monthly subscription</string>
543+
<string name="support_kofi_title">Support on Ko-fi</string>
544+
<string name="support_kofi_desc">Buy a coffee once, or every month</string>
545+
<string name="buy_me_a_coffee_title">Buy Me a Coffee</string>
546+
<string name="buy_me_a_coffee_desc">A one-off coffee, or a monthly membership</string>
543547
<string name="donate_paypal_title">Donate via PayPal</string>
544548
<string name="donate_paypal_desc">Send a one-time donation directly</string>
545549

app/src/store/java/com/valhalla/thor/presentation/settings/SupportDeveloperHelper.kt

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,27 @@ fun SupportDeveloperHelper(
4343

4444
var pendingChangeProductId by remember { mutableStateOf<String?>(null) }
4545

46-
// "Direct" tab — GitHub Sponsors + Patreon + PayPal. Always available, including in the store
46+
// "Direct" tab — GitHub Sponsors + Patreon + Ko-fi + Buy Me a Coffee + PayPal, the same five
47+
// routes the website and .github/FUNDING.yml advertise. Always available, including in the store
4748
// build. Resolve strings via stringResource (configuration-aware) in composable scope, then pass
4849
// them into remember as keys so the list recomputes on locale/config change.
4950
val sponsorsTitle = stringResource(R.string.sponsor_github_title)
5051
val sponsorsDesc = stringResource(R.string.sponsor_github_desc)
5152
val patreonTitle = stringResource(R.string.become_patreon_title)
5253
val patreonDesc = stringResource(R.string.become_patreon_desc)
54+
val kofiTitle = stringResource(R.string.support_kofi_title)
55+
val kofiDesc = stringResource(R.string.support_kofi_desc)
56+
val coffeeTitle = stringResource(R.string.buy_me_a_coffee_title)
57+
val coffeeDesc = stringResource(R.string.buy_me_a_coffee_desc)
5358
val paypalTitle = stringResource(R.string.donate_paypal_title)
5459
val paypalDesc = stringResource(R.string.donate_paypal_desc)
5560
val directActions = remember(
56-
sponsorsTitle, sponsorsDesc, patreonTitle, patreonDesc, paypalTitle, paypalDesc
61+
sponsorsTitle, sponsorsDesc, patreonTitle, patreonDesc,
62+
kofiTitle, kofiDesc, coffeeTitle, coffeeDesc, paypalTitle, paypalDesc
5763
) {
5864
listOf(
59-
// First deliberately: lowest fees of the three, and it sits beside the source.
65+
// First deliberately: lowest fees of the five, and it sits beside the source. After it,
66+
// recurring-capable before one-off.
6067
SupportAction(
6168
iconRes = R.drawable.brand_github,
6269
title = sponsorsTitle,
@@ -80,6 +87,26 @@ fun SupportDeveloperHelper(
8087
onDismiss()
8188
}
8289
),
90+
SupportAction(
91+
iconRes = R.drawable.brand_kofi,
92+
title = kofiTitle,
93+
description = kofiDesc,
94+
onClick = {
95+
val intent = Intent(Intent.ACTION_VIEW, "https://ko-fi.com/trinadh".toUri())
96+
runCatching { context.startActivity(intent) }
97+
onDismiss()
98+
}
99+
),
100+
SupportAction(
101+
iconRes = R.drawable.brand_buymeacoffee,
102+
title = coffeeTitle,
103+
description = coffeeDesc,
104+
onClick = {
105+
val intent = Intent(Intent.ACTION_VIEW, "https://www.buymeacoffee.com/trinadh".toUri())
106+
runCatching { context.startActivity(intent) }
107+
onDismiss()
108+
}
109+
),
83110
SupportAction(
84111
iconRes = R.drawable.shield_with_heart,
85112
title = paypalTitle,

release-notes/v1.94.0/github.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Thor v1.94.0 Release Notes
22

33
The first stable since **v1.93.0**, consolidating everything that shipped through the
4-
`v1.93.1`, `v1.93.2` and `v1.93.3` pre-release builds — **65 pull requests**.
4+
`v1.93.1`, `v1.93.2` and `v1.93.3` pre-release builds — **66 pull requests**.
55

66
Two threads run through it. The first is **new ground**: freeze profiles, bulk backup and
77
`.xapk` export, permission filtering, and a support catalogue that comes from Play instead of
@@ -133,9 +133,12 @@ suspension another privilege mode applied.
133133
* The in-app **language picker works below API 33** (#345), and a language change reaches the
134134
caches that hold copies.
135135

136-
### 💖 Support (#311, #342, #351)
136+
### 💖 Support (#311, #342, #351, #356)
137137

138138
* **GitHub Sponsors** alongside Patreon and PayPal (#311).
139+
* **Ko-fi and Buy Me a Coffee are now in the app** (#356). The website and `FUNDING.yml` have
140+
advertised five funding routes for a while; the in-app sheet only ever offered three. All five
141+
now agree.
139142
* **Support tiers are probed rather than hardcoded** (#351). Play exposes no catalogue-
140143
enumeration API, so Thor queries a candidate ID set and renders whatever Play answers with —
141144
a tier added in Play Console shows up without an app release. Prices and their ordering come
@@ -179,6 +182,7 @@ suspension another privilege mode applied.
179182

180183
## 🛠 Commits Log (`v1.93.0...v1.94.0`)
181184

185+
* `fbf2d54e`#356 Ko-fi and Buy Me a Coffee in the app
182186
* `0ea6f93b`#354 lint warning sweep, guards preserved
183187
* `1f31a36f`#352 release 1.93.3
184188
* `172583f7`#351 probe support tiers instead of hardcoding them

0 commit comments

Comments
 (0)