import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hum/core/constants/app_text.dart'; import 'package:hum/core/constants/app_theme.dart'; import 'package:hum/core/utils/icon_mapper.dart'; import 'package:hum/services/firestore_api.dart'; import 'package:hum/views/home/modes/home_ai_view.dart'; import 'package:hum/views/home/panels/home_categories.dart'; import 'package:hum/views/home/panels/home_filters.dart'; import 'package:hum/views/home/modes/home_grid.dart'; import 'package:hum/views/home/widgets/home_widgets.dart'; import 'package:hum/widgets/widget_buttons.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; class HomeView extends StatefulWidget { const HomeView({super.key}); @override State createState() => _HomeViewState(); } class _HomeViewState extends State with SingleTickerProviderStateMixin { int _ideaIndex = 0; Timer? _ideasTimer; bool showFilters = false; bool showViewMode = false; FocusNode searchFocusMode = FocusNode(); String viewMode = 'ai'; List> categories = []; final double navBarIconSize = 32; late final AnimationController _borderController; final List colorsGlow = [ Color(0xFF00FFFF), Color(0xFF2155E5), Color(0xFFFF00FF), Color(0xFF0DFFEF), ]; Future _initData() async { List> dbCategories = await dbGetCategories(); if (mounted) { setState(() { categories = [ {'id': 'all', 'icon': 'squaresFour', 'name': 'All'}, ...dbCategories, ]; }); } } @override void initState() { super.initState(); _borderController = AnimationController(vsync: this, duration: const Duration(seconds: 5)) ..repeat(); searchFocusMode.addListener(() { setState(() { showFilters = searchFocusMode.hasFocus; }); }); _ideasTimer = Timer.periodic(const Duration(seconds: 3), (_) { if (!mounted) return; setState(() { _ideaIndex = (_ideaIndex + 1) % homeViewIdeas.length; }); }); _initData(); } @override void dispose() { _borderController.dispose(); _ideasTimer?.cancel(); searchFocusMode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final bottomInset = MediaQuery.of(context).viewInsets.bottom; return CupertinoPageScaffold( child: Stack( children: [ Positioned.fill( child: SafeArea( top: false, // allow content under status/nav bar child: AnimatedPadding( duration: const Duration(milliseconds: 200), curve: Curves.easeOutCubic, padding: EdgeInsets.only(bottom: bottomInset), child: MediaQuery.removePadding( context: context, removeTop: true, // critical so it can slide under the bar child: SafeArea( child: Column( spacing: 8, children: [ if (viewMode == 'ai') HomeAIView(), if (viewMode == 'grid') HomeViewGrid(), // if (viewMode == 'map') HomeViewMap(), ], ), ), ), ), ), ), Positioned( bottom: MediaQuery.of(context).padding.bottom, left: 0, right: 0, child: Container( // color: CupertinoDynamicColor.resolve(colorBackground, context), decoration: BoxDecoration( color: CupertinoDynamicColor.resolve(colorBackground, context), // gradient: LinearGradient( // begin: Alignment.topCenter, // end: Alignment.bottomCenter, // colors: [ // CupertinoDynamicColor.resolve(colorBackground, context).withValues(alpha: 0), // Transparent at top // CupertinoDynamicColor.resolve(colorBackground, context).withValues(alpha: 255), // Solid at bottom // ], // stops: [0.0, .1], // ), ), child: Padding( padding: const EdgeInsets.only(left: 6.0, right: 6.0, top: 12.0, bottom: 20), child: SizedBox( height: searchBarHeight, width: double.infinity, child: Row( spacing: 0, children: [ Expanded( child: SizedBox( height: searchBarHeight, child: CupertinoSearchTextField( focusNode: searchFocusMode, padding: EdgeInsetsGeometry.symmetric(horizontal: 6), borderRadius: BorderRadius.circular(16), placeholder: homeViewSearchPlaceholder, ), ), ), AnimatedOpacity( duration: Duration(milliseconds: 150), opacity: viewMode != 'ai' ? 1 : 0, child: AnimatedContainer( curve: Curves.easeInOut, width: viewMode != 'ai' ? 46 : 0, duration: Duration(milliseconds: 150), child: Padding( padding: const EdgeInsets.only(left: 4.0), child: SizedBox( width: 42, child: BTNRoundBG( icon: PhosphorIconHelper.fromString('fadersHorizontal'), action: () { showCupertinoModalBottomSheet( topRadius: Radius.circular(radiusCards), useRootNavigator: true, isDismissible: true, context: context, builder: (context) => Container( height: MediaQuery.of(context).size.height / 1.3, color: CupertinoDynamicColor.resolve( colorBarBackground, context, ), child: HomeFilters(), ), ); }, ), ), ), ), ), AnimatedOpacity( duration: Duration(milliseconds: 150), opacity: viewMode != 'ai' ? 1 : 0, child: AnimatedContainer( curve: Curves.easeInOut, width: viewMode != 'ai' ? 46 : 0, duration: Duration(milliseconds: 150), child: Padding( padding: const EdgeInsets.only(left: 4.0), child: BTNRoundBG( // icon: CupertinoIcons.square_grid_2x2_fill, icon: PhosphorIconHelper.fromString('circlesFour', style: 'fill'), action: () { showCupertinoModalBottomSheet( topRadius: Radius.circular(radiusCards), useRootNavigator: true, isDismissible: true, context: context, builder: (context) => Container( height: MediaQuery.of(context).size.height / 1.55, color: CupertinoDynamicColor.resolve( colorBarBackground, context, ), child: HomePanelCategory(categories: categories), ), ); }, ), ), ), ), ], ), ), ), ), ), Positioned( top: 0, left: 0, right: 0, child: SafeArea( bottom: false, child: CupertinoNavigationBar( backgroundColor: Colors.transparent, enableBackgroundFilterBlur: false, automaticBackgroundVisibility: false, border: null, // remove bottom hairline automaticallyImplyLeading: false, leading: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox(width: 80, child: Image.asset('assets/images/logo_large_green.png')), ], ), trailing: Row( spacing: 6, // crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ HomeToggleView( mode: viewMode, onChanged: (newView) { setState(() { viewMode = newView; }); }, ), Container( decoration: BoxDecoration( border: Border.all( width: 2, color: CupertinoDynamicColor.resolve(colorBackground, context), ), borderRadius: BorderRadius.circular(100), ), child: CircleAvatar( // radius: 24, child: ClipRRect( borderRadius: BorderRadius.circular(999), child: Image.asset('assets/images/profile_test_002.jpg'), ), ), ), ], ), ), ), ), ], ), ); } }