feat: add donation info

This commit is contained in:
cogwheel0
2025-10-02 15:14:34 +05:30
parent afd3231ae9
commit 089eb48bd7
10 changed files with 276 additions and 0 deletions

View File

@@ -35,6 +35,9 @@ import '../../../shared/widgets/model_avatar.dart';
/// Profile page (You tab) showing user info and main actions
/// Enhanced with production-grade design tokens for better cohesion
class ProfilePage extends ConsumerWidget {
static const _githubSponsorsUrl = 'https://github.com/sponsors/cogwheel0';
static const _buyMeACoffeeUrl = 'https://www.buymeacoffee.com/cogwheel0';
const ProfilePage({super.key});
@override
@@ -161,11 +164,123 @@ class ProfilePage extends ConsumerWidget {
end: 0,
curve: AnimationCurves.pageTransition,
),
const SizedBox(height: Spacing.sectionGap),
_buildSupportSection(context)
.animate()
.fadeIn(
delay: AnimationDelay.medium,
duration: AnimationDuration.pageTransition,
)
.slideY(
begin: 0.08,
end: 0,
curve: AnimationCurves.pageTransition,
),
],
),
);
}
Widget _buildSupportSection(BuildContext context) {
final theme = context.conduitTheme;
final textTheme =
theme.bodySmall?.copyWith(color: theme.textSecondary) ??
TextStyle(color: theme.textSecondary);
final supportTiles = [
_buildSupportOption(
context,
icon: UiUtils.platformIcon(
ios: CupertinoIcons.heart,
android: Icons.favorite_border,
),
title: AppLocalizations.of(context)!.githubSponsorsTitle,
subtitle: AppLocalizations.of(context)!.githubSponsorsSubtitle,
url: _githubSponsorsUrl,
color: theme.success,
),
_buildSupportOption(
context,
icon: UiUtils.platformIcon(
ios: CupertinoIcons.gift,
android: Icons.coffee,
),
title: AppLocalizations.of(context)!.buyMeACoffeeTitle,
subtitle: AppLocalizations.of(context)!.buyMeACoffeeSubtitle,
url: _buyMeACoffeeUrl,
color: theme.warning,
),
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
AppLocalizations.of(context)!.supportConduit,
style: theme.headingSmall?.copyWith(color: theme.textPrimary),
),
const SizedBox(height: Spacing.xs),
Text(
AppLocalizations.of(context)!.supportConduitSubtitle,
style: textTheme,
),
const SizedBox(height: Spacing.sm),
for (var i = 0; i < supportTiles.length; i++) ...[
supportTiles[i],
if (i != supportTiles.length - 1) const SizedBox(height: Spacing.md),
],
],
);
}
Widget _buildSupportOption(
BuildContext context, {
required IconData icon,
required String title,
required String subtitle,
required String url,
required Color color,
}) {
final theme = context.conduitTheme;
return _ProfileSettingTile(
onTap: () => _openExternalLink(context, url),
isDestructive: false,
leading: _buildIconBadge(context, icon, color: color),
title: title,
subtitle: subtitle,
trailing: Icon(
UiUtils.platformIcon(
ios: CupertinoIcons.arrow_up_right,
android: Icons.open_in_new,
),
color: theme.iconSecondary,
size: IconSize.small,
),
);
}
Future<void> _openExternalLink(BuildContext context, String url) async {
try {
final launched = await launchUrlString(
url,
mode: LaunchMode.externalApplication,
);
if (!launched && context.mounted) {
UiUtils.showMessage(
context,
AppLocalizations.of(context)!.errorMessage,
);
}
} on PlatformException catch (_) {
if (!context.mounted) return;
UiUtils.showMessage(context, AppLocalizations.of(context)!.errorMessage);
} catch (_) {
if (!context.mounted) return;
UiUtils.showMessage(context, AppLocalizations.of(context)!.errorMessage);
}
}
Widget _buildProfileHeader(
BuildContext context,
dynamic user,

View File

@@ -21,6 +21,12 @@
"description": "Statusnachricht nach einem erneuten Versuch ohne wiederhergestellte Verbindung"
},
"account": "Konto",
"supportConduit": "Conduit unterstützen",
"supportConduitSubtitle": "Hilf, die Weiterentwicklung und neue Funktionen zu finanzieren.",
"githubSponsorsTitle": "GitHub Sponsors",
"githubSponsorsSubtitle": "Werde monatliche*r Sponsor*in und unterstütze die Roadmap.",
"buyMeACoffeeTitle": "Buy Me a Coffee",
"buyMeACoffeeSubtitle": "Bedanke dich mit einer einmaligen Spende.",
"signOut": "Abmelden",
"endYourSession": "Sitzung beenden",
"defaultModel": "Standardmodell",

View File

@@ -30,6 +30,30 @@
"@pleaseCheckConnection": {"description": "Generic connectivity hint after an error."},
"account": "Account",
"@account": {"description": "Section header for account-related options."},
"supportConduit": "Support Conduit",
"@supportConduit": {
"description": "Section header inviting the user to financially support the project."
},
"supportConduitSubtitle": "Keep Conduit independent by funding ongoing development.",
"@supportConduitSubtitle": {
"description": "Subtitle explaining why donations are helpful."
},
"githubSponsorsTitle": "GitHub Sponsors",
"@githubSponsorsTitle": {
"description": "Tile title linking to the GitHub Sponsors page."
},
"githubSponsorsSubtitle": "Become a recurring sponsor to fund roadmap items.",
"@githubSponsorsSubtitle": {
"description": "Subtitle explaining the impact of recurring sponsorship."
},
"buyMeACoffeeTitle": "Buy Me a Coffee",
"@buyMeACoffeeTitle": {
"description": "Tile title linking to the Buy Me a Coffee page."
},
"buyMeACoffeeSubtitle": "Make a one-time donation to say thanks.",
"@buyMeACoffeeSubtitle": {
"description": "Subtitle encouraging one-time donations via Buy Me a Coffee."
},
"signOut": "Sign Out",
"@signOut": {"description": "Button/title for signing out of the app."},
"endYourSession": "End your session",

View File

@@ -21,6 +21,12 @@
"description": "Message d'état après une tentative de reconnexion sans succès"
},
"account": "Compte",
"supportConduit": "Soutenir Conduit",
"supportConduitSubtitle": "Financez le développement continu et les nouvelles fonctionnalités.",
"githubSponsorsTitle": "GitHub Sponsors",
"githubSponsorsSubtitle": "Devenez sponsor récurrent pour soutenir la feuille de route.",
"buyMeACoffeeTitle": "Buy Me a Coffee",
"buyMeACoffeeSubtitle": "Faites un don ponctuel pour nous encourager.",
"signOut": "Se déconnecter",
"endYourSession": "Terminer votre session",
"defaultModel": "Modèle par défaut",

View File

@@ -21,6 +21,12 @@
"description": "Messaggio di stato dopo un tentativo di riconnessione senza successo"
},
"account": "Account",
"supportConduit": "Sostieni Conduit",
"supportConduitSubtitle": "Mantieni Conduit indipendente finanziando lo sviluppo continuo.",
"githubSponsorsTitle": "GitHub Sponsors",
"githubSponsorsSubtitle": "Diventa sponsor ricorrente per supportare la roadmap.",
"buyMeACoffeeTitle": "Buy Me a Coffee",
"buyMeACoffeeSubtitle": "Fai una donazione una tantum per dire grazie.",
"signOut": "Esci",
"endYourSession": "Termina la sessione",
"defaultModel": "Modello predefinito",

View File

@@ -174,6 +174,42 @@ abstract class AppLocalizations {
/// **'Account'**
String get account;
/// Section header inviting the user to financially support the project.
///
/// In en, this message translates to:
/// **'Support Conduit'**
String get supportConduit;
/// Subtitle explaining why donations are helpful.
///
/// In en, this message translates to:
/// **'Keep Conduit independent by funding ongoing development.'**
String get supportConduitSubtitle;
/// Tile title linking to the GitHub Sponsors page.
///
/// In en, this message translates to:
/// **'GitHub Sponsors'**
String get githubSponsorsTitle;
/// Subtitle explaining the impact of recurring sponsorship.
///
/// In en, this message translates to:
/// **'Become a recurring sponsor to fund roadmap items.'**
String get githubSponsorsSubtitle;
/// Tile title linking to the Buy Me a Coffee page.
///
/// In en, this message translates to:
/// **'Buy Me a Coffee'**
String get buyMeACoffeeTitle;
/// Subtitle encouraging one-time donations via Buy Me a Coffee.
///
/// In en, this message translates to:
/// **'Make a one-time donation to say thanks.'**
String get buyMeACoffeeSubtitle;
/// Button/title for signing out of the app.
///
/// In en, this message translates to:

View File

@@ -47,6 +47,27 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get account => 'Konto';
@override
String get supportConduit => 'Conduit unterstützen';
@override
String get supportConduitSubtitle =>
'Hilf, die Weiterentwicklung und neue Funktionen zu finanzieren.';
@override
String get githubSponsorsTitle => 'GitHub Sponsors';
@override
String get githubSponsorsSubtitle =>
'Werde monatliche*r Sponsor*in und unterstütze die Roadmap.';
@override
String get buyMeACoffeeTitle => 'Buy Me a Coffee';
@override
String get buyMeACoffeeSubtitle =>
'Bedanke dich mit einer einmaligen Spende.';
@override
String get signOut => 'Abmelden';

View File

@@ -47,6 +47,26 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get account => 'Account';
@override
String get supportConduit => 'Support Conduit';
@override
String get supportConduitSubtitle =>
'Keep Conduit independent by funding ongoing development.';
@override
String get githubSponsorsTitle => 'GitHub Sponsors';
@override
String get githubSponsorsSubtitle =>
'Become a recurring sponsor to fund roadmap items.';
@override
String get buyMeACoffeeTitle => 'Buy Me a Coffee';
@override
String get buyMeACoffeeSubtitle => 'Make a one-time donation to say thanks.';
@override
String get signOut => 'Sign Out';

View File

@@ -47,6 +47,27 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get account => 'Compte';
@override
String get supportConduit => 'Soutenir Conduit';
@override
String get supportConduitSubtitle =>
'Financez le développement continu et les nouvelles fonctionnalités.';
@override
String get githubSponsorsTitle => 'GitHub Sponsors';
@override
String get githubSponsorsSubtitle =>
'Devenez sponsor récurrent pour soutenir la feuille de route.';
@override
String get buyMeACoffeeTitle => 'Buy Me a Coffee';
@override
String get buyMeACoffeeSubtitle =>
'Faites un don ponctuel pour nous encourager.';
@override
String get signOut => 'Se déconnecter';

View File

@@ -46,6 +46,27 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get account => 'Account';
@override
String get supportConduit => 'Sostieni Conduit';
@override
String get supportConduitSubtitle =>
'Mantieni Conduit indipendente finanziando lo sviluppo continuo.';
@override
String get githubSponsorsTitle => 'GitHub Sponsors';
@override
String get githubSponsorsSubtitle =>
'Diventa sponsor ricorrente per supportare la roadmap.';
@override
String get buyMeACoffeeTitle => 'Buy Me a Coffee';
@override
String get buyMeACoffeeSubtitle =>
'Fai una donazione una tantum per dire grazie.';
@override
String get signOut => 'Esci';