From 494e158950949e8e401efe0e2804d70f2658dff7 Mon Sep 17 00:00:00 2001 From: alexdivadi Date: Thu, 26 Feb 2026 20:50:59 -0600 Subject: [PATCH 1/3] fix: don't expire dev preview --- .github/workflows/firebase-hosting-pull-request.yml | 1 - .../presentation/event_feed/event_feed_screen.dart | 4 ++-- lib/core/shared_prefs/shared_prefs.dart | 11 ++++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml index 885ca47..3bcf020 100644 --- a/.github/workflows/firebase-hosting-pull-request.yml +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -31,7 +31,6 @@ jobs: repoToken: ${{ secrets.GITHUB_TOKEN }} firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_ANYSTEP_COMMUNITY_SERVICES }} channelId: dev - expires: 12h projectId: anystep-community-services env: FIREBASE_CLI_EXPERIMENTS: webframeworks diff --git a/lib/core/features/events/presentation/event_feed/event_feed_screen.dart b/lib/core/features/events/presentation/event_feed/event_feed_screen.dart index 2b8115e..0916877 100644 --- a/lib/core/features/events/presentation/event_feed/event_feed_screen.dart +++ b/lib/core/features/events/presentation/event_feed/event_feed_screen.dart @@ -52,14 +52,14 @@ class _EventFeedScreenState extends ConsumerState { _welcomeChecked = true; final prefs = await ref.read(appPreferencesProvider.future); - if (prefs.getWelcomeMessageSeen()) return; final remoteConfig = await ref.read(remoteConfigProvider.future); final message = remoteConfig.welcomeMessage; if (message.isEmpty) return; + if (prefs.getWelcomeMessageContent() == message) return; if (!mounted) return; - await prefs.setWelcomeMessageSeen(); + await prefs.setWelcomeMessageContent(message); if (!mounted) return; context.showModal( _WelcomeMessageModal( diff --git a/lib/core/shared_prefs/shared_prefs.dart b/lib/core/shared_prefs/shared_prefs.dart index 1c0df7b..2002d75 100644 --- a/lib/core/shared_prefs/shared_prefs.dart +++ b/lib/core/shared_prefs/shared_prefs.dart @@ -14,7 +14,7 @@ class AppPreferences { static const String themeModeKey = 'theme_mode'; static const String localeCodeKey = 'locale_code'; static const String eventNotificationsKey = 'event_notifications'; - static const String welcomeMessageSeenKey = 'welcome_message_seen'; + static const String welcomeMessageContentKey = 'welcome_message_content'; String? getAuthStateJson() => _prefs.getString(authStateKey); Future setAuthStateJson(String token) async => await _prefs.setString(authStateKey, token); @@ -44,10 +44,11 @@ class AppPreferences { Future clearEventNotificationsEnabled() async => await _prefs.remove(eventNotificationsKey); - bool getWelcomeMessageSeen() => _prefs.getBool(welcomeMessageSeenKey) ?? false; - Future setWelcomeMessageSeen({bool seen = true}) async => - await _prefs.setBool(welcomeMessageSeenKey, seen); - Future clearWelcomeMessageSeen() async => await _prefs.remove(welcomeMessageSeenKey); + String? getWelcomeMessageContent() => _prefs.getString(welcomeMessageContentKey); + Future setWelcomeMessageContent(String message) async => + await _prefs.setString(welcomeMessageContentKey, message); + Future clearWelcomeMessageContent() async => + await _prefs.remove(welcomeMessageContentKey); } @Riverpod(keepAlive: true) From 3b35481a314d76a18a3ac41ea8002559ab553a42 Mon Sep 17 00:00:00 2001 From: alexdivadi Date: Thu, 26 Feb 2026 21:00:47 -0600 Subject: [PATCH 2/3] feat: add donate button --- .../firebase-hosting-pull-request.yml | 1 + .../event_detail/event_detail_screen.dart | 23 +++++++------ .../event_feed/event_feed_screen.dart | 9 +++++ .../onboarding/welcome_screen.dart | 2 +- .../agreement/locale_icon_button.dart | 2 +- .../presentation/settings_screen.dart | 6 ++-- .../presentation/widgets/donate_tile.dart | 34 +++++++++++++++++++ .../{ => widgets}/locale_setting.dart | 1 - .../{ => widgets}/theme_mode_setting.dart | 0 lib/l10n/app_en.arb | 2 ++ lib/l10n/app_es.arb | 2 ++ lib/l10n/generated/app_localizations.dart | 6 ++++ lib/l10n/generated/app_localizations_en.dart | 3 ++ lib/l10n/generated/app_localizations_es.dart | 3 ++ 14 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 lib/core/features/settings/presentation/widgets/donate_tile.dart rename lib/core/features/settings/presentation/{ => widgets}/locale_setting.dart (98%) rename lib/core/features/settings/presentation/{ => widgets}/theme_mode_setting.dart (100%) diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml index 3bcf020..885ca47 100644 --- a/.github/workflows/firebase-hosting-pull-request.yml +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -31,6 +31,7 @@ jobs: repoToken: ${{ secrets.GITHUB_TOKEN }} firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_ANYSTEP_COMMUNITY_SERVICES }} channelId: dev + expires: 12h projectId: anystep-community-services env: FIREBASE_CLI_EXPERIMENTS: webframeworks diff --git a/lib/core/features/events/presentation/event_detail/event_detail_screen.dart b/lib/core/features/events/presentation/event_detail/event_detail_screen.dart index c9852c4..233a13f 100644 --- a/lib/core/features/events/presentation/event_detail/event_detail_screen.dart +++ b/lib/core/features/events/presentation/event_detail/event_detail_screen.dart @@ -155,17 +155,18 @@ class _EventDetailScreenState extends ConsumerState { child: Center(child: SignUpButton(event: event)), ), if (userAsync.hasValue && !isEditing) - isPast - ? AttendanceList( - eventId: widget.id, - isAdmin: userAsync.value?.role.canEditEvent == true, - onAddAttendee: () => - context.push(AddAttendeeScreen.getPath(widget.id)), - ) - : (userAsync.value?.role.canEditEvent == true - ? SliverToBoxAdapter(child: SignUpList(eventId: widget.id)) - : const SliverToBoxAdapter(child: SizedBox.shrink())), - if (userAsync.hasValue && userAsync.value == null) + if (userAsync.value?.role.canEditEvent == true) + isPast + ? AttendanceList( + eventId: widget.id, + isAdmin: true, + onAddAttendee: () => + context.push(AddAttendeeScreen.getPath(widget.id)), + ) + : SliverToBoxAdapter(child: SignUpList(eventId: widget.id)) + else + const SliverToBoxAdapter(child: SizedBox.shrink()), + if (!isPast && userAsync.hasValue && userAsync.value == null) SliverToBoxAdapter( child: Padding( padding: .only( diff --git a/lib/core/features/events/presentation/event_feed/event_feed_screen.dart b/lib/core/features/events/presentation/event_feed/event_feed_screen.dart index 0916877..4f13d3e 100644 --- a/lib/core/features/events/presentation/event_feed/event_feed_screen.dart +++ b/lib/core/features/events/presentation/event_feed/event_feed_screen.dart @@ -177,6 +177,15 @@ class _EventFeedScreenState extends ConsumerState { } } + if (!isAuthenticated) { + slivers.add( + SliverToBoxAdapter( + child: DashboardSectionHeader(title: loc.dashboardCalendar), + ), + ); + slivers.add(const SliverToBoxAdapter(child: DashboardCalendarCard())); + } + slivers.add( SliverToBoxAdapter( child: DashboardSectionHeader(title: loc.dashboardUpcomingEvents), diff --git a/lib/core/features/onboarding/presentation/onboarding/welcome_screen.dart b/lib/core/features/onboarding/presentation/onboarding/welcome_screen.dart index 9b145f9..aa52bf3 100644 --- a/lib/core/features/onboarding/presentation/onboarding/welcome_screen.dart +++ b/lib/core/features/onboarding/presentation/onboarding/welcome_screen.dart @@ -8,7 +8,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:anystep/core/features/onboarding/presentation/onboarding/welcome_screen_controller.dart'; import 'package:go_router/go_router.dart'; import 'package:anystep/l10n/generated/app_localizations.dart'; -import 'package:anystep/core/features/settings/presentation/locale_setting.dart'; +import 'package:anystep/core/features/settings/presentation/widgets/locale_setting.dart'; /// Multi-page onboarding / welcome flow. /// Shows 4 pages in a PageView with a dot indicator. The final page displays diff --git a/lib/core/features/profile/presentation/agreement/locale_icon_button.dart b/lib/core/features/profile/presentation/agreement/locale_icon_button.dart index 04a7666..bf5a1f0 100644 --- a/lib/core/features/profile/presentation/agreement/locale_icon_button.dart +++ b/lib/core/features/profile/presentation/agreement/locale_icon_button.dart @@ -1,5 +1,5 @@ import 'package:anystep/core/config/locale/locale_controller.dart'; -import 'package:anystep/core/features/settings/presentation/locale_setting.dart'; +import 'package:anystep/core/features/settings/presentation/widgets/locale_setting.dart'; import 'package:anystep/l10n/generated/app_localizations.dart'; import 'package:anystep/core/common/widgets/any_step_modal.dart'; import 'package:flutter/material.dart'; diff --git a/lib/core/features/settings/presentation/settings_screen.dart b/lib/core/features/settings/presentation/settings_screen.dart index fa81535..82a5f94 100644 --- a/lib/core/features/settings/presentation/settings_screen.dart +++ b/lib/core/features/settings/presentation/settings_screen.dart @@ -2,8 +2,9 @@ import 'package:anystep/core/common/constants/spacing.dart'; import 'package:anystep/core/common/widgets/widgets.dart'; import 'package:anystep/core/features/auth/data/auth_repository.dart'; import 'package:anystep/core/features/screens.dart'; -import 'package:anystep/core/features/settings/presentation/theme_mode_setting.dart'; -import 'package:anystep/core/features/settings/presentation/locale_setting.dart'; +import 'package:anystep/core/features/settings/presentation/widgets/donate_tile.dart'; +import 'package:anystep/core/features/settings/presentation/widgets/theme_mode_setting.dart'; +import 'package:anystep/core/features/settings/presentation/widgets/locale_setting.dart'; import 'package:anystep/l10n/generated/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -37,6 +38,7 @@ class SettingsScreen extends ConsumerWidget { trailing: const Icon(Icons.chevron_right), onTap: () => context.push(AboutScreen.path), ), + const DonateTile(), const ThemeModeSetting(), const LocaleSetting(), ListTile( diff --git a/lib/core/features/settings/presentation/widgets/donate_tile.dart b/lib/core/features/settings/presentation/widgets/donate_tile.dart new file mode 100644 index 0000000..fa74f61 --- /dev/null +++ b/lib/core/features/settings/presentation/widgets/donate_tile.dart @@ -0,0 +1,34 @@ +import 'package:anystep/core/common/utils/log_utils.dart'; +import 'package:anystep/l10n/generated/app_localizations.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class DonateTile extends StatelessWidget { + const DonateTile({super.key}); + + static const _donateUrl = 'https://www.anystepcommunity.com/donate-1'; + + Future _openLink(String url) async { + final uri = Uri.tryParse(url); + if (uri == null) return; + try { + final launched = await launchUrl(uri, mode: LaunchMode.externalApplication); + if (!launched) { + Log.e('Failed to open external link: $uri'); + } + } catch (e) { + Log.e('Error opening external link', e); + } + } + + @override + Widget build(BuildContext context) { + final loc = AppLocalizations.of(context); + return ListTile( + leading: const Icon(Icons.volunteer_activism), + title: Text(loc.donate), + trailing: const Icon(Icons.open_in_new), + onTap: () => _openLink(_donateUrl), + ); + } +} diff --git a/lib/core/features/settings/presentation/locale_setting.dart b/lib/core/features/settings/presentation/widgets/locale_setting.dart similarity index 98% rename from lib/core/features/settings/presentation/locale_setting.dart rename to lib/core/features/settings/presentation/widgets/locale_setting.dart index 0ec8b1c..0a7c6a6 100644 --- a/lib/core/features/settings/presentation/locale_setting.dart +++ b/lib/core/features/settings/presentation/widgets/locale_setting.dart @@ -18,7 +18,6 @@ class LocaleSetting extends ConsumerWidget { return ListTile( leading: const Icon(Icons.language), title: Text(loc.languageLabel), - subtitle: Text(_labelForLocale(current, loc)), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/core/features/settings/presentation/theme_mode_setting.dart b/lib/core/features/settings/presentation/widgets/theme_mode_setting.dart similarity index 100% rename from lib/core/features/settings/presentation/theme_mode_setting.dart rename to lib/core/features/settings/presentation/widgets/theme_mode_setting.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f057282..31cb256 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -25,6 +25,8 @@ , "settingsTitle": "Settings", "@settingsTitle": {"description": "Title for the Settings screen app bar"}, + "donate": "Donate", + "@donate": {"description": "Label for the donate link in settings"}, "themeLabel": "Theme", "@themeLabel": {"description": "Settings tile label for theme selection"}, "themeAuto": "Auto", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index e49632a..81212e8 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -25,6 +25,8 @@ , "settingsTitle": "Configuración", "@settingsTitle": {"description": "Título de la pantalla de configuración"}, + "donate": "Donar", + "@donate": {"description": "Etiqueta del enlace de donación en configuración"}, "themeLabel": "Tema", "@themeLabel": {"description": "Etiqueta para selección de tema"}, "themeAuto": "Automático", diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index ab81616..22fce69 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -134,6 +134,12 @@ abstract class AppLocalizations { /// **'Settings'** String get settingsTitle; + /// Label for the donate link in settings + /// + /// In en, this message translates to: + /// **'Donate'** + String get donate; + /// Settings tile label for theme selection /// /// In en, this message translates to: diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index 34b1ac3..911000f 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -37,6 +37,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsTitle => 'Settings'; + @override + String get donate => 'Donate'; + @override String get themeLabel => 'Theme'; diff --git a/lib/l10n/generated/app_localizations_es.dart b/lib/l10n/generated/app_localizations_es.dart index b6f7c27..10f60e5 100644 --- a/lib/l10n/generated/app_localizations_es.dart +++ b/lib/l10n/generated/app_localizations_es.dart @@ -37,6 +37,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get settingsTitle => 'Configuración'; + @override + String get donate => 'Donar'; + @override String get themeLabel => 'Tema'; From facb79f7552c078ddb3cc1a9f2dd295a9c13b32b Mon Sep 17 00:00:00 2001 From: alexdivadi Date: Thu, 26 Feb 2026 21:02:02 -0600 Subject: [PATCH 3/3] fix: update donate link --- .../features/settings/presentation/widgets/donate_tile.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/features/settings/presentation/widgets/donate_tile.dart b/lib/core/features/settings/presentation/widgets/donate_tile.dart index fa74f61..3978e51 100644 --- a/lib/core/features/settings/presentation/widgets/donate_tile.dart +++ b/lib/core/features/settings/presentation/widgets/donate_tile.dart @@ -6,7 +6,8 @@ import 'package:url_launcher/url_launcher.dart'; class DonateTile extends StatelessWidget { const DonateTile({super.key}); - static const _donateUrl = 'https://www.anystepcommunity.com/donate-1'; + static const _donateUrl = + 'https://www.zeffy.com/en-US/donation-form/high-five-for-seniors-step-up-give-back-move-forward'; Future _openLink(String url) async { final uri = Uri.tryParse(url);