feat(supporters): merge hand-maintained supporters, rank by amount

Add a MANUAL_SUPPORTERS list in patreon.rs for donations that arrive
outside Patreon; both the native and web boot paths merge it with the
fetched patrons and sort the combined list by amount (highest first,
then alphabetically). This also sorts the web supporters list, which
previously arrived unordered, and keeps hand-maintained supporters
visible when the Patreon fetch returns nothing (offline / no token).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-08 00:32:12 +03:00
1 parent 31ac5372d6
commit b446786d7d
2 files changed
+37 -4

No files matched your search

+9 -4
View File
@@ -2730,12 +2730,17 @@ impl OpenCADStudio {
Task::none()
}
Message::PatronsFetched(Ok(names)) => {
self.patrons = names;
// Merge the hand-maintained supporters and rank everyone by
// amount (also sorts the web list, which arrives unsorted).
self.patrons = crate::patreon::merge_manual(names);
Task::none()
}
// No token / offline: still show any hand-maintained supporters
// (Start page shows a "Support on Patreon" prompt when empty).
Message::PatronsFetched(Err(_)) => {
self.patrons = crate::patreon::merge_manual(Vec::new());
Task::none()
}
// No token / offline: leave the list empty (Start page shows a
// "Support on Patreon" prompt instead).
Message::PatronsFetched(Err(_)) => Task::none(),
Message::PluginReleasesFetched(repo, Ok(tags)) => {
if let Some(first) = tags.first() {
self.repo_selected_tag
+28
View File
@@ -7,6 +7,34 @@
//! can still be extracted from a shipped binary, so it should be a
//! campaign-scoped token with the minimum needed access.
/// Supporters who donated outside Patreon (direct transfer, crypto, one-off
/// gifts, …), maintained by hand here. They are merged with the fetched patrons
/// and ranked together by amount, so the combined Start-page list is ordered by
/// pledge regardless of where the donation came from.
///
/// To add a supporter, add a `("Display name", cents)` line below. The amount is
/// in **cents**: a $25 donation is `2500`, €10 is `1000`.
const MANUAL_SUPPORTERS: &[(&str, i64)] = &[
("Stefano", 6000), // $60
];
/// Append the hand-maintained [`MANUAL_SUPPORTERS`] to `patrons` and sort the
/// combined list by amount (highest first, then alphabetically). Both the
/// native and web boot paths funnel their fetched list through here, so the
/// manual entries — and the ranking — are identical on every platform, and the
/// list is still sorted (and still shows the manual entries) even when the
/// fetch returns nothing because the app is offline or has no Patreon token.
pub fn merge_manual(mut patrons: Vec<(String, i64)>) -> Vec<(String, i64)> {
for &(name, cents) in MANUAL_SUPPORTERS {
let name = name.trim();
if !name.is_empty() {
patrons.push((name.to_string(), cents));
}
}
patrons.sort_by(|a, b| b.1.cmp(&a.1).then_with(|| a.0.cmp(&b.0)));
patrons
}
#[cfg(not(target_arch = "wasm32"))]
const UA: &str = concat!("OpenCADStudio/", env!("CARGO_PKG_VERSION"));