// ignore_for_file: unnecessary_import import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/home_page_content/content.dart'; import 'package:didvan/models/home_page_content/home_page_list.dart'; import 'package:didvan/models/home_page_content/swot.dart'; import 'package:didvan/services/app_initalizer.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/views/home/explore/explore.dart'; import 'package:didvan/views/home/main/main_page_state.dart'; import 'package:didvan/views/home/main/widgets/main_content.dart'; import 'package:didvan/views/home/main/widgets/story_section.dart'; import 'package:didvan/views/home/main/widgets/simple_explore_card.dart'; import 'package:didvan/views/home/main/widgets/didvan_plus_section.dart'; import 'package:didvan/views/home/main/widgets/didvan_voice_section.dart'; import 'package:didvan/views/home/new_statistic/new_statistics_state.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:didvan/views/widgets/carousel_3d.dart'; import 'package:didvan/views/home/home_state.dart'; import 'package:didvan/views/widgets/text_divider.dart'; import 'package:didvan/views/widgets/home_app_bar.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:flutter/foundation.dart' show kIsWeb, defaultTargetPlatform; import 'package:universal_html/html.dart' as html; bool isAnyMobile() { if (kIsWeb) { final userAgent = html.window.navigator.userAgent.toLowerCase(); return userAgent.contains('mobile') || userAgent.contains('android') || userAgent.contains('ios'); } return defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.iOS; } class MainPage extends StatefulWidget { const MainPage({ super.key, }); @override State createState() => _MainPageState(); } class _MainPageState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { context.read().init(); context.read().init(); }); } @override Widget build(BuildContext context) { return StateHandler( onRetry: () => context.read().init(), state: context.watch(), builder: (context, state) { debugPrint( '🏠 MainPage build - didvanPlus: ${state.didvanPlus != null}'); debugPrint( '🏠 MainPage build - didvanVoice: ${state.didvanVoice != null}'); return Column( children: [ const HomeAppBar( showBackButton: false, showSearchField: true, ), Expanded( child: ListView( padding: const EdgeInsets.only(top: 0, bottom: 16), children: [ if (state.stories.isNotEmpty) ...[ const TextDivider(text: 'دیده‌بان') .animate() .fadeIn(delay: 400.ms, duration: 500.ms), const _DidvanSignalsTitle() .animate() .fadeIn(delay: 500.ms, duration: 500.ms), Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: StorySection(stories: state.stories), ).animate().fadeIn(delay: 600.ms, duration: 500.ms), ], if (state.didvanPlus != null) ...[ const SizedBox(height: 16), DidvanPlusSection(didvanPlus: state.didvanPlus!) .animate() .fadeIn(delay: 650.ms, duration: 500.ms), ], const SizedBox(height: 12), const TextDivider(text: 'پیشخوان استراتژیک') .animate() .fadeIn(delay: 700.ms, duration: 500.ms), const Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: MainPageMainContent(), ).animate().fadeIn(delay: 800.ms, duration: 500.ms), if (state.content != null && state.content!.lists.isNotEmpty) ...[ const _ExploreLatestTitle() .animate() .fadeIn(delay: 900.ms, duration: 500.ms), _ExploreLatestSlider( lists: state.content!.lists, swotItems: state.swotItems, ).animate().fadeIn(delay: 1000.ms, duration: 500.ms), ], if (state.swotItems.isNotEmpty) SwotSection(swotItems: state.swotItems,headerSize: 13,moreSize: 12,) .animate() .fadeIn(delay: 1100.ms, duration: 500.ms), if (state.didvanVoice != null) ...[ const SizedBox(height: 16), const _DidvanVoiceTitle() .animate() .fadeIn(delay: 1150.ms, duration: 500.ms), const SizedBox(height: 12), DidvanVoiceSection(didvanVoice: state.didvanVoice!) .animate() .fadeIn(delay: 1200.ms, duration: 500.ms), ], // const _IndustryPulseTitle() // .animate() // .fadeIn(delay: 1100.ms, duration: 500.ms), // const _IndustryPulseCards() // .animate() // .fadeIn(delay: 1200.ms, duration: 500.ms), ], ), ), ], ); }, ); } } class _DidvanSignalsTitle extends StatelessWidget { const _DidvanSignalsTitle(); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only( left: 16, right: 16, bottom: 16, top: 0, ), child: Row( children: [ SvgPicture.asset( 'lib/assets/icons/voice-square.svg', color: Theme.of(context).colorScheme.title, width: 30, height: 30, ), const SizedBox(width: 5), DidvanText( "سیگنال‌های دیدوان", style: Theme.of(context).textTheme.titleMedium, color: const Color.fromARGB(255, 0, 89, 119), fontSize: 13, ), ], ), ); } } class _DidvanVoiceTitle extends StatelessWidget { const _DidvanVoiceTitle(); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ SvgPicture.asset( 'lib/assets/icons/voice-square.svg', color: Theme.of(context).colorScheme.title, width: 30, height: 30, ), const SizedBox(width: 5), DidvanText( "صدای دیدوان ", style: Theme.of(context).textTheme.titleMedium, color: const Color.fromARGB(255, 0, 89, 119), fontSize: 13, fontWeight: FontWeight.bold, ), DidvanText( "(خلاصه تازه‌ترین پویش افق)", style: Theme.of(context).textTheme.bodySmall, color: const Color.fromARGB(255, 0, 89, 119), fontSize: 11, ), ], ), ); } } class _ExploreLatestTitle extends StatelessWidget { const _ExploreLatestTitle(); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only( left: 16, right: 16, bottom: 16, top: 0, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ SvgPicture.asset( 'lib/assets/icons/discover.svg', color: Theme.of(context).colorScheme.title, width: 30, height: 30, ), const SizedBox(width: 5), DidvanText( "تازه‌ترین‌های کاوش", style: Theme.of(context).textTheme.titleMedium, color: DesignConfig.isDark ? const Color.fromARGB(255, 0, 125, 166) : const Color.fromARGB(255, 0, 89, 119), fontSize: 13, ), ], ), GestureDetector( onTap: () { context.read().tabController.animateTo(3); }, child: const Row( children: [ DidvanText( "مشاهده همه", color: Color.fromARGB(255, 0, 126, 167), fontWeight: FontWeight.normal, fontSize: 12, ), ], ), ) ], ), ); } } class _ExploreLatestSlider extends StatelessWidget { final List lists; final List swotItems; const _ExploreLatestSlider({required this.lists, required this.swotItems}); @override Widget build(BuildContext context) { final List items = []; final List< ({String type, MainPageContentType? content, SwotItem? swotItem})> itemsData = []; for (var list in lists) { if (list.type == 'video' || list.type == 'podcast' || list.type == 'news' || list.type == 'radar') { continue; } if (list.contents.isNotEmpty) { final newestContent = list.contents.first; items.add( Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: SimpleExploreCard( content: newestContent, type: list.type, ), ), ); itemsData .add((type: list.type, content: newestContent, swotItem: null)); } } if (swotItems.isNotEmpty) { items.add( Padding( padding: const EdgeInsets.symmetric(horizontal: 4.0), child: SimpleExploreCard( swotItem: swotItems.first, ), ), ); itemsData.add((type: 'swot', content: null, swotItem: swotItems.first)); } if (items.isEmpty) { return const SizedBox.shrink(); } return Carousel3D( items: items, height: 220, autoPlayDuration: const Duration(seconds: 5), showControls: true, onItemChanged: (index) { // Optional: Handle item change if needed }, onItemTap: (index) { final data = itemsData[index]; if (data.swotItem != null) { AppInitializer.openWebLink( context, 'http://opportunity-threat.didvan.com/posts/${data.swotItem!.id}/?accessToken=${RequestService.token}', mode: LaunchMode.inAppWebView, ); } else if (data.content != null) { context.read().navigationHandler( data.type, data.content!.id, data.content!.link, description: data.content!.title, ); } }, ); } } // class _IndustryPulseTitle extends StatelessWidget { // const _IndustryPulseTitle(); // @override // Widget build(BuildContext context) { // return Padding( // padding: const EdgeInsets.only( // left: 16, // right: 16, // bottom: 16, // top: 16, // ), // child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Row( // children: [ // SvgPicture.asset( // 'lib/assets/icons/chart 2.svg', // color: Theme.of(context).colorScheme.title, // width: 30, // height: 30, // ), // const SizedBox(width: 5), // DidvanText( // "نبض صنعت", // style: Theme.of(context).textTheme.titleMedium, // color: const Color.fromARGB(255, 0, 89, 119), // fontSize: 13, // ), // ], // ), // GestureDetector( // onTap: () { // context.read().tabController.animateTo(2); // }, // child: const Row( // children: [ // DidvanText( // "مشاهده همه", // color: Color.fromARGB(255, 0, 126, 167), // fontWeight: FontWeight.normal, // fontSize: 12, // ), // ], // ), // ) // ], // ), // ); // } // } // class _IndustryPulseCards extends StatefulWidget { // const _IndustryPulseCards(); // @override // State<_IndustryPulseCards> createState() => _IndustryPulseCardsState(); // } // class _IndustryPulseCardsState extends State<_IndustryPulseCards> { // late PageController _pageController; // @override // void initState() { // super.initState(); // _pageController = PageController(viewportFraction: 0.45); // } // @override // void dispose() { // _pageController.dispose(); // super.dispose(); // } // @override // Widget build(BuildContext context) { // return StateHandler( // state: context.watch(), // placeholder: const Center(child: CircularProgressIndicator()), // onRetry: () => context.read().init(), // builder: (context, statisticState) { // if (statisticState.contents.isEmpty) { // return const SizedBox.shrink(); // } // final List allItems = []; // statisticState.contents.forEach((category) { // allItems.addAll(category.contents); // }); // final List desiredTitles = [ // 'دلار', // 'بیت کوین', // 'نیکل', // 'نفت خام' // ]; // final List itemsToShow = allItems // .where((item) => desiredTitles.contains(item.title)) // .toList(); // if (itemsToShow.isEmpty) { // return const SizedBox.shrink(); // } // return Padding( // padding: const EdgeInsets.only(left: 16.0), // child: Align( // alignment: Alignment.centerLeft, // child: SizedBox( // height: 165, // child: PageView.builder( // padEnds: false, // controller: _pageController, // itemCount: itemsToShow.length, // itemBuilder: (context, index) { // return Padding( // padding: const EdgeInsets.only(right: 8.0), // child: AspectRatio( // aspectRatio: 1, // child: _IndustryPulseCard(statistic: itemsToShow[index]), // ), // ) // .animate() // .fadeIn(delay: (200 * index).ms, duration: 500.ms) // .slideX( // begin: -0.5, duration: 500.ms, curve: Curves.easeOut); // }, // ), // ), // ), // ); // }, // ); // } // } // class _IndustryPulseCard extends StatelessWidget { // final Content statistic; // const _IndustryPulseCard({required this.statistic}); // Color _diffColor(BuildContext context) => statistic.data.dt == 'high' // ? Theme.of(context).colorScheme.success // : Theme.of(context).colorScheme.error; // bool get _hasDiff => statistic.data.dp != 0; // @override // Widget build(BuildContext context) { // final state = context.read(); // return GestureDetector( // onTap: () => // Navigator.of(context).pushNamed(Routes.statisticDetails, arguments: { // 'onMarkChanged': (value) => onMarkChanged(statistic.id, value), // 'label': statistic.label, // 'title': statistic.title, // 'marked': statistic.marked, // }).then( // (value) => state.getStatistic(), // ), // child: DidvanCard( // padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 9), // child: Column( // mainAxisAlignment: MainAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.center, // children: [ // Padding( // padding: const EdgeInsets.symmetric(horizontal: 8.0), // child: Row( // children: [ // Expanded( // child: MiniChart( // label: statistic.label, // width: double.infinity, // height: 38, // lineColor: _hasDiff // ? _diffColor(context) // : Theme.of(context).colorScheme.primary, // changePercent: statistic.data.dp.toDouble(), // trend: statistic.data.dt, // ), // ), // ], // ), // ), // const SizedBox(height: 20), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // if (statistic.marked) // Icon( // Icons.star, // color: Theme.of(context).colorScheme.yellow, // size: 16, // ), // if (statistic.marked) const SizedBox(width: 4), // DidvanText( // statistic.title, // style: Theme.of(context).textTheme.bodyMedium?.copyWith( // fontWeight: FontWeight.w600, // ), // maxLines: 1, // overflow: TextOverflow.ellipsis, // ), // ], // ), // const SizedBox(height: 6), // DidvanText( // statistic.data.p, // style: Theme.of(context).textTheme.bodySmall?.copyWith( // fontWeight: FontWeight.w500, // ), // ), // if (_hasDiff) const SizedBox(height: 6), // if (_hasDiff) // Container( // padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), // decoration: BoxDecoration( // color: statistic.data.dt == 'high' // ? const Color.fromRGBO(245, 255, 252, 1) // : const Color.fromRGBO(255, 248, 248, 1), // borderRadius: BorderRadius.circular(4), // ), // child: Row( // mainAxisSize: MainAxisSize.min, // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Icon( // statistic.data.dt == 'high' // ? DidvanIcons.angle_up_regular // : DidvanIcons.angle_down_regular, // size: 16, // color: _diffColor(context), // ), // const SizedBox(width: 4), // DidvanText( // '${statistic.data.dp}%', // style: Theme.of(context).textTheme.bodySmall, // color: _diffColor(context), // ), // ], // ), // ), // ], // ), // ), // ); // } // void onMarkChanged(int id, bool value) { // UserProvider.changeStatisticMark(id, value); // } // }