import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../l10n/app_localizations.dart'; import '../providers/category_provider.dart'; import '../providers/payment_card_provider.dart'; import '../providers/subscription_provider.dart'; import '../utils/subscription_grouping_helper.dart'; import '../widgets/empty_state_widget.dart'; import '../widgets/main_summary_card.dart'; import '../widgets/native_ad_widget.dart'; import '../widgets/subscription_list_widget.dart'; class HomeContent extends StatefulWidget { final AnimationController fadeController; final AnimationController rotateController; final AnimationController slideController; final AnimationController pulseController; final AnimationController waveController; final ScrollController scrollController; final VoidCallback onAddPressed; const HomeContent({ super.key, required this.fadeController, required this.rotateController, required this.slideController, required this.pulseController, required this.waveController, required this.scrollController, required this.onAddPressed, }); @override State createState() => _HomeContentState(); } class _HomeContentState extends State { static const _groupingPrefKey = 'home_grouping_mode'; SubscriptionGroupingMode _groupingMode = SubscriptionGroupingMode.category; @override void initState() { super.initState(); _loadGroupingPreference(); } Future _loadGroupingPreference() async { final prefs = await SharedPreferences.getInstance(); final stored = prefs.getString(_groupingPrefKey); if (stored == 'paymentCard') { setState(() { _groupingMode = SubscriptionGroupingMode.paymentCard; }); } } Future _saveGroupingPreference(SubscriptionGroupingMode mode) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString( _groupingPrefKey, mode == SubscriptionGroupingMode.paymentCard ? 'paymentCard' : 'category'); } void _updateGroupingMode(SubscriptionGroupingMode mode) { if (_groupingMode == mode) return; setState(() { _groupingMode = mode; }); _saveGroupingPreference(mode); } @override Widget build(BuildContext context) { final subscriptionProvider = context.watch(); final categoryProvider = context.watch(); final paymentCardProvider = context.watch(); if (subscriptionProvider.isLoading) { return Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation( Theme.of(context).colorScheme.primary, ), ), ); } if (subscriptionProvider.subscriptions.isEmpty) { return EmptyStateWidget( fadeController: widget.fadeController, rotateController: widget.rotateController, slideController: widget.slideController, onAddPressed: widget.onAddPressed, ); } final groupedSubscriptions = SubscriptionGroupingHelper.buildGroups( context: context, subscriptions: subscriptionProvider.subscriptions, mode: _groupingMode, categoryProvider: categoryProvider, paymentCardProvider: paymentCardProvider, ); return RefreshIndicator( onRefresh: () async { await subscriptionProvider.refreshSubscriptions(); }, color: Theme.of(context).colorScheme.primary, child: CustomScrollView( controller: widget.scrollController, physics: const BouncingScrollPhysics(), slivers: [ SliverToBoxAdapter( child: SizedBox( height: kToolbarHeight + MediaQuery.of(context).padding.top, ), ), const SliverToBoxAdapter( child: NativeAdWidget(key: ValueKey('home_ad')), ), SliverToBoxAdapter( child: SlideTransition( position: Tween( begin: const Offset(0, 0.2), end: Offset.zero, ).animate(CurvedAnimation( parent: widget.slideController, curve: Curves.easeOutCubic)), child: MainScreenSummaryCard( provider: subscriptionProvider, fadeController: widget.fadeController, pulseController: widget.pulseController, waveController: widget.waveController, slideController: widget.slideController, ), ), ), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.fromLTRB(20, 24, 20, 4), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SlideTransition( position: Tween( begin: const Offset(-0.2, 0), end: Offset.zero, ).animate(CurvedAnimation( parent: widget.slideController, curve: Curves.easeOutCubic)), child: Text( AppLocalizations.of(context).mySubscriptions, style: Theme.of(context).textTheme.titleLarge?.copyWith( color: Theme.of(context).colorScheme.onSurface, ), ), ), SlideTransition( position: Tween( begin: const Offset(0.2, 0), end: Offset.zero, ).animate(CurvedAnimation( parent: widget.slideController, curve: Curves.easeOutCubic)), child: Row( children: [ Text( AppLocalizations.of(context).subscriptionCount( subscriptionProvider.subscriptions.length), style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Theme.of(context).colorScheme.primary, ), ), const SizedBox(width: 4), Icon( Icons.arrow_forward_ios, size: 14, color: Theme.of(context).colorScheme.primary, ), ], ), ), ], ), ), ), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), child: Wrap( spacing: 8, children: [ ChoiceChip( label: Text(AppLocalizations.of(context).category), selected: _groupingMode == SubscriptionGroupingMode.category, onSelected: (_) => _updateGroupingMode(SubscriptionGroupingMode.category), ), ChoiceChip( label: Text(AppLocalizations.of(context).paymentCard), selected: _groupingMode == SubscriptionGroupingMode.paymentCard, onSelected: (_) => _updateGroupingMode( SubscriptionGroupingMode.paymentCard), ), ], ), ), ), SubscriptionListWidget( groups: groupedSubscriptions, fadeController: widget.fadeController, ), SliverToBoxAdapter( child: SizedBox( height: 120 + MediaQuery.of(context).padding.bottom, ), ), ], ), ); } }