didvan-app/lib/views/home/main/main_page.dart

520 lines
17 KiB
Dart

import 'package:didvan/config/theme_data.dart';
import 'package:didvan/models/home_page_content/home_page_list.dart';
import 'package:didvan/models/home_page_content/swot.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/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: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<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<MainPageState>().init();
context.read<NewStatisticState>().init();
});
}
@override
Widget build(BuildContext context) {
return StateHandler<MainPageState>(
onRetry: () => context.read<MainPageState>().init(),
state: context.watch<MainPageState>(),
builder: (context, state) {
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),
],
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)
.animate()
.fadeIn(delay: 1100.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 _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: const Color.fromARGB(255, 0, 89, 119),
fontSize: 13,
),
],
),
GestureDetector(
onTap: () {
context.read<HomeState>().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<MainPageList> lists;
final List<SwotItem> swotItems;
const _ExploreLatestSlider({required this.lists, required this.swotItems});
@override
Widget build(BuildContext context) {
final List<Widget> items = [];
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,
),
),
);
}
}
if (swotItems.isNotEmpty) {
items.add(
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: SimpleExploreCard(
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
},
);
}
}
// 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<HomeState>().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<NewStatisticState>(
// state: context.watch<NewStatisticState>(),
// placeholder: const Center(child: CircularProgressIndicator()),
// onRetry: () => context.read<NewStatisticState>().init(),
// builder: (context, statisticState) {
// if (statisticState.contents.isEmpty) {
// return const SizedBox.shrink();
// }
// final List<Content> allItems = [];
// statisticState.contents.forEach((category) {
// allItems.addAll(category.contents);
// });
// final List<String> desiredTitles = [
// 'دلار',
// 'بیت کوین',
// 'نیکل',
// 'نفت خام'
// ];
// final List<Content> 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<NewStatisticState>();
// 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);
// }
// }