Untitled
unknown
plain_text
a year ago
15 kB
5
Indexable
Never
import 'dart:js_util'; import 'package:finbox_v2/feature/analysis/model/analytics_data.dart'; import 'package:finbox_v2/feature/analysis/widget/analysis_news_post.dart'; import 'package:finbox_v2/feature/news/model/news_data.dart'; import 'package:finbox_v2/feature/news/widget/news_post.dart'; import 'package:finbox_v2/feature/notification/model/noti_data_request.dart'; import 'package:finbox_v2/feature/notification/model/notification.dart' as n; import 'package:finbox_v2/feature/notification/provider/noti_provider.dart'; import 'package:finbox_v2/feature/notification/repository/noti_repository.dart'; import 'package:finbox_v2/feature/notification/widget/common/noti_common_derivative_order.dart'; import 'package:finbox_v2/feature/notification/widget/common/noti_common_news.dart'; import 'package:finbox_v2/feature/notification/widget/common/noti_common_signal.dart'; import 'package:finbox_v2/feature/recommendations/widget/recommendations_page.dart'; import 'package:finbox_v2/feature/ticker/model/ticker_detail_model.dart'; import 'package:finbox_v2/feature/ticker/provider/active_tickers_provider.dart'; import 'package:finbox_v2/feature/ticker/widget/technical_chart_page.dart'; import 'package:finbox_v2/shared/model/user.dart'; import 'package:finbox_v2/shared/util/navigation_util.dart'; import 'package:finbox_v2/theme/finbox_theme.dart'; import 'package:finbox_v2/widgets/loadding_news.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; class SystemTab extends ConsumerStatefulWidget { const SystemTab({required this.user, this.loadingCount = 3, Key? key}) : super(key: key); final int loadingCount; final User user; @override ConsumerState<SystemTab> createState() => SystemTabState(); } class SystemTabState extends ConsumerState<SystemTab> with SingleTickerProviderStateMixin { final int _visibleNotiCommonCount = 8; int page = 1; bool isLoading = false; bool isFirstLoad = true; bool isRefreshed = false; final ScrollController _scrollController = ScrollController(); // ignore: strict_raw_type List<n.Notification> listNoti = []; Future<void> _loadData() async { final requestData = <String, dynamic>{ 'limit': _visibleNotiCommonCount, 'page': page, 'userId': widget.user.id, }; final request = NotiDataRequest.fromJson(requestData); await ref.read(notiProvider.notifier).getNoti(request); } @override void initState() { _loadData(); _scrollController.addListener(() async { if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent + 50) { if (!isLoading) { await _loadData(); } } }); super.initState(); } @override void dispose() { _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { print('is invoked'); var mapTicker = <String, TickerDetailModel>{}; final listTicker = <String>[]; late final finboxColors = Theme.of(context).extension<FinboxColors>()!; final notiDataState = ref.watch(notiProvider); final _notiDataProvider = ref.read(notiDataProvider.notifier); final notis = ref.watch(notiDataProvider); late NewsData news; late AnalyticsData analytics; // ignore: cascade_invocations notiDataState ..whenOrNull( listNotiLoaded: (loadedNoti) { isFirstLoad = false; page++; // listNoti.addAll(loadedNoti); _notiDataProvider.addNoti(loadedNoti); }, ) ..maybeWhen( loading: () => isLoading = true, orElse: () => isLoading = false, ); for (var noti in notis) { if (noti.notification.type == 'Signals' && (!listTicker.contains(noti.notification.ticker))) { listTicker.add(noti.notification.ticker!); } } if (ref.read(activeTickersProvider.notifier).addTickers(listTicker)) { ref.read(activeTickersProvider.notifier).fetchTickers(); } final tickers = ref.watch(activeTickersProvider); mapTicker = tickers; return Container( margin: const EdgeInsets.only(left: 16), padding: const EdgeInsets.only(top: 24), child: RefreshIndicator( onRefresh: _refresh, color: finboxColors.dark3, child: ListView.builder( controller: _scrollController, physics: const BouncingScrollPhysics(), itemCount: notis.length + widget.loadingCount, // +1 for the "Watch More" button itemBuilder: (context, index) { if (index < notis.length) { if ('Signals' == notis[index].notification.type) { final title = "${notis[index].notification.ticker!} - ${notis[index].notification.action!}${notis[index].notification.signal!}"; final price = 'Giá KN: ${notis[index].notification.price!}'; return GestureDetector( onTap: () { notiDataState.maybeWhen( error: (e) => null, orElse: () { ref .watch(notiProvider.notifier) .readNotification(notis[index]); NavigationUtil.nav( context, TechnicalChartersOverview( tickerName: mapTicker[notis[index].notification.ticker] ?.ticker ?? '', initialTicker: mapTicker[notis[index].notification.ticker], ), ); }, ); }, child: Stack( alignment: Alignment.center, children: [ NotiCommonSignal( time: convertTimeString(notis[index].created), title: title, price: price, ), if (notis[index].read) Icon(Icons.check, color: Color(0xFF0063F7)), // Hiển thị dấu tick nếu thông báo đã xem ], ), ); } if ('DerivativeOrder' == notis[index].notification.type) { var title = 'Phái sinh - Đã có tín hiệu ' + notis[index].notification.signal!; var price = 'Giá KN: ' + notis[index].notification.price!.toString(); return GestureDetector( onTap: () { notiDataState.maybeWhen( error: (e) => null, orElse: () { ref .watch(notiProvider.notifier) .readNotification(notis[index]); NavigationUtil.pushNamedRoute( context, '/recommendations', ); }, ); // Handle onPress event here // You can perform any desired actions print('NotiCommonSignal pressed'); }, child: Stack( alignment: Alignment.center, children: [ NotiCommonDerivative( time: convertTimeString(notis[index].created), title: title, price: price, ), if (notis[index].read) Icon(Icons.check, color: Color(0xFF0063F7)), // Hiển thị dấu tick nếu thông báo đã xem ], ), ); } if ('DerivativeTurn' == notis[index].notification.type) { var title = 'Phái sinh - Đã tiệm cận điểm đảo chiều'; var price = 'Giá hiện tại: ' + notis[index].notification.price!.toString(); return GestureDetector( onTap: () { notiDataState.maybeWhen( error: (e) => null, orElse: () { ref .watch(notiProvider.notifier) .readNotification(notis[index]); NavigationUtil.nav( context, const RecommendationsPage(), ); }, ); // Handle onPress event here // You can perform any desired actions print('NotiCommonSignal pressed'); }, child: Stack( alignment: Alignment.center, children: [ NotiCommonDerivative( time: convertTimeString(notis[index].created), title: title, price: price, ), if (notis[index].read) Icon(Icons.check, color: Color(0xFF0063F7)), // Hiển thị dấu tick nếu thông báo đã xem ], ), ); } if ('NewsDefautSet' == notis[index].notification.type) { var title = notis[index].notification.ticker! + ' - ' + notis[index].notification.content!; var price = 'Nguồn: ' + notis[index].notification.source!; return GestureDetector( onTap: () { notiDataState.maybeWhen( error: (e) => null, orElse: () { ref .watch(notiProvider.notifier) .readNotification(notis[index]); }, ); NavigationUtil.nav( context, NewsPost( slang: notis[index].notification.slang!, ), ); // Handle onPress event here // You can perform any desired actions print('NotiCommonSignal pressed'); }, child: Stack( alignment: Alignment.center, children: [ NotiCommonNews( time: convertTimeString(notis[index].created), title: title, price: price, ), if (notis[index].read) Icon(Icons.check, color: Color(0xFF0063F7)), // Hiển thị dấu tick nếu thông báo đã xem ], ), ); } if ('FinboxNews' == notis[index].notification.type) { var title = notis[index].notification.ticker! + ' - ' + notis[index].notification.content!; var price = 'Nguồn: Finbox'; return GestureDetector( onTap: () { notiDataState.maybeWhen( error: (e) => null, orElse: () { ref .watch(notiProvider.notifier) .readNotification(notis[index]); }, ); NavigationUtil.nav( context, AnalysisNewsPost( slang: notis[index].notification.slang!, ), ); // Handle onPress event here // You can perform any desired actions print('NotiCommonSignal pressed'); }, child: Stack( alignment: Alignment.center, children: [ NotiCommonNews( time: convertTimeString(notis[index].created), title: title, price: price, ), if (notis[index].read) Icon(Icons.check, color: Color(0xFF0063F7)), // Hiển thị dấu tick nếu thông báo đã xem ], ), ); } return NotiCommonSignal( time: notis[index].created, title: '', price: '1000', ); } else { return notiDataState.maybeWhen( loading: () => const SizedBox(), orElse: () => const Column( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: EdgeInsets.only(top: 20), child: NewsCardLoading(isWatchlist: true), ) ], ), ); } }, ), ), ); } Future<void> _refresh() async { // ignore: inference_failure_on_instance_creation setState(() { listNoti = []; page = 1; _loadData(); isFirstLoad = true; isRefreshed = true; }); } String convertTimeString(String time) { // Create a DateTime object from the input string DateTime dateTime = DateTime.parse(time); // Add 7 hours to the DateTime object DateTime updatedDateTime = dateTime.add(Duration(hours: 7)); // Format the updated DateTime to the desired output format DateFormat formatter = DateFormat('HH:mm dd/MM/yyyy'); String output = formatter.format(updatedDateTime); return output; } }