✨ Daily sign
This commit is contained in:
		
							
								
								
									
										7
									
								
								build.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								build.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| targets: | ||||
|   $default: | ||||
|     builders: | ||||
|       json_serializable: | ||||
|         options: | ||||
|           explicit_to_json: true | ||||
|           field_rename: snake | ||||
| @@ -1,10 +1,15 @@ | ||||
| import 'dart:math'; | ||||
|  | ||||
| import 'package:get/get.dart'; | ||||
| import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:solian/models/pagination.dart'; | ||||
| import 'package:solian/models/post.dart'; | ||||
| import 'package:solian/providers/content/posts.dart'; | ||||
|  | ||||
| class PostListController extends GetxController { | ||||
|   late final SharedPreferences _prefs; | ||||
|  | ||||
|   String? author; | ||||
|  | ||||
|   /// The polling source modifier. | ||||
| @@ -19,9 +24,16 @@ class PostListController extends GetxController { | ||||
|       PagingController(firstPageKey: 0); | ||||
|  | ||||
|   PostListController({this.author}) { | ||||
|     _initPreferences(); | ||||
|     _initPagingController(); | ||||
|   } | ||||
|  | ||||
|   void _initPreferences() { | ||||
|     SharedPreferences.getInstance().then((prefs) { | ||||
|       _prefs = prefs; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /// Initialize a compatibility layer to paging controller | ||||
|   void _initPagingController() { | ||||
|     pagingController.addPageRequestListener(_onPagingControllerRequest); | ||||
| @@ -96,6 +108,13 @@ class PostListController extends GetxController { | ||||
|     final idx = <dynamic>{}; | ||||
|     postList.retainWhere((x) => idx.add(x.id)); | ||||
|  | ||||
|     var lastId = postList.map((x) => x.id).reduce(max); | ||||
|     if (_prefs.containsKey('feed_last_read_at')) { | ||||
|       final storedId = _prefs.getInt('feed_last_read_at') ?? 0; | ||||
|       lastId = max(storedId, lastId); | ||||
|     } | ||||
|     _prefs.setInt('feed_last_read_at', lastId); | ||||
|  | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import 'package:solian/bootstrapper.dart'; | ||||
| import 'package:solian/firebase_options.dart'; | ||||
| import 'package:solian/platform.dart'; | ||||
| import 'package:solian/providers/attachment_uploader.dart'; | ||||
| import 'package:solian/providers/daily_sign.dart'; | ||||
| import 'package:solian/providers/link_expander.dart'; | ||||
| import 'package:solian/providers/stickers.dart'; | ||||
| import 'package:solian/providers/theme_switcher.dart'; | ||||
| @@ -129,6 +130,7 @@ class SolianApp extends StatelessWidget { | ||||
|     Get.lazyPut(() => RealmProvider()); | ||||
|     Get.lazyPut(() => ChatCallProvider()); | ||||
|     Get.lazyPut(() => AttachmentUploaderController()); | ||||
|     Get.lazyPut(() => LinkExpandController()); | ||||
|     Get.lazyPut(() => LinkExpandProvider()); | ||||
|     Get.lazyPut(() => DailySignProvider()); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										48
									
								
								lib/models/daily_sign.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/models/daily_sign.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| import 'package:freezed_annotation/freezed_annotation.dart'; | ||||
| import 'package:solian/models/account.dart'; | ||||
|  | ||||
| part 'daily_sign.g.dart'; | ||||
|  | ||||
| @JsonSerializable() | ||||
| class DailySignRecord { | ||||
|   int id; | ||||
|   DateTime createdAt; | ||||
|   DateTime updatedAt; | ||||
|   DateTime? deletedAt; | ||||
|   Account account; | ||||
|   int resultTier; | ||||
|   int resultExperience; | ||||
|   int accountId; | ||||
|  | ||||
|   DailySignRecord({ | ||||
|     required this.id, | ||||
|     required this.createdAt, | ||||
|     required this.updatedAt, | ||||
|     required this.deletedAt, | ||||
|     required this.resultTier, | ||||
|     required this.resultExperience, | ||||
|     required this.account, | ||||
|     required this.accountId, | ||||
|   }); | ||||
|  | ||||
|   factory DailySignRecord.fromJson(Map<String, dynamic> json) => | ||||
|       _$DailySignRecordFromJson(json); | ||||
|  | ||||
|   Map<String, dynamic> toJson() => _$DailySignRecordToJson(this); | ||||
|  | ||||
|   String get symbol => switch (resultTier) { | ||||
|         0 => '大\n凶', | ||||
|         1 => '凶', | ||||
|         2 => '中\n平', | ||||
|         3 => '吉', | ||||
|         _ => '大\n吉', | ||||
|       }; | ||||
|  | ||||
|   String get overviewSuggestion => switch (resultTier) { | ||||
|         0 => '诸事不宜', | ||||
|         1 => '有些不宜', | ||||
|         2 => '平平淡淡', | ||||
|         3 => '有些事宜', | ||||
|         _ => '诸事皆宜', | ||||
|       }; | ||||
| } | ||||
							
								
								
									
										33
									
								
								lib/models/daily_sign.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								lib/models/daily_sign.g.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| // GENERATED CODE - DO NOT MODIFY BY HAND | ||||
|  | ||||
| part of 'daily_sign.dart'; | ||||
|  | ||||
| // ************************************************************************** | ||||
| // JsonSerializableGenerator | ||||
| // ************************************************************************** | ||||
|  | ||||
| DailySignRecord _$DailySignRecordFromJson(Map<String, dynamic> json) => | ||||
|     DailySignRecord( | ||||
|       id: (json['id'] as num).toInt(), | ||||
|       createdAt: DateTime.parse(json['created_at'] as String), | ||||
|       updatedAt: DateTime.parse(json['updated_at'] as String), | ||||
|       deletedAt: json['deleted_at'] == null | ||||
|           ? null | ||||
|           : DateTime.parse(json['deleted_at'] as String), | ||||
|       resultTier: (json['result_tier'] as num).toInt(), | ||||
|       resultExperience: (json['result_experience'] as num).toInt(), | ||||
|       account: Account.fromJson(json['account'] as Map<String, dynamic>), | ||||
|       accountId: (json['account_id'] as num).toInt(), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$DailySignRecordToJson(DailySignRecord instance) => | ||||
|     <String, dynamic>{ | ||||
|       'id': instance.id, | ||||
|       'created_at': instance.createdAt.toIso8601String(), | ||||
|       'updated_at': instance.updatedAt.toIso8601String(), | ||||
|       'deleted_at': instance.deletedAt?.toIso8601String(), | ||||
|       'account': instance.account.toJson(), | ||||
|       'result_tier': instance.resultTier, | ||||
|       'result_experience': instance.resultExperience, | ||||
|       'account_id': instance.accountId, | ||||
|     }; | ||||
							
								
								
									
										37
									
								
								lib/providers/daily_sign.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/providers/daily_sign.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import 'package:get/get.dart'; | ||||
| import 'package:solian/exceptions/request.dart'; | ||||
| import 'package:solian/exceptions/unauthorized.dart'; | ||||
| import 'package:solian/models/daily_sign.dart'; | ||||
| import 'package:solian/providers/auth.dart'; | ||||
|  | ||||
| class DailySignProvider extends GetxController { | ||||
|   Future<DailySignRecord?> getToday() async { | ||||
|     final AuthProvider auth = Get.find(); | ||||
|     if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); | ||||
|  | ||||
|     final client = auth.configureClient('id'); | ||||
|  | ||||
|     final resp = await client.get('/daily/today'); | ||||
|     if (resp.statusCode != 200 && resp.statusCode != 404) { | ||||
|       throw RequestException(resp); | ||||
|     } else if (resp.statusCode == 404) { | ||||
|       return null; | ||||
|     } | ||||
|  | ||||
|     return DailySignRecord.fromJson(resp.body); | ||||
|   } | ||||
|  | ||||
|   Future<DailySignRecord> signToday() async { | ||||
|     final AuthProvider auth = Get.find(); | ||||
|     if (auth.isAuthorized.isFalse) throw const UnauthorizedException(); | ||||
|  | ||||
|     final client = auth.configureClient('id'); | ||||
|  | ||||
|     final resp = await client.post('/daily', {}); | ||||
|     if (resp.statusCode != 200) { | ||||
|       throw RequestException(resp); | ||||
|     } | ||||
|  | ||||
|     return DailySignRecord.fromJson(resp.body); | ||||
|   } | ||||
| } | ||||
| @@ -5,7 +5,7 @@ import 'package:get/get.dart'; | ||||
| import 'package:solian/models/link.dart'; | ||||
| import 'package:solian/services.dart'; | ||||
|  | ||||
| class LinkExpandController extends GetxController { | ||||
| class LinkExpandProvider extends GetxController { | ||||
|   final Map<String, LinkMeta?> _cachedResponse = {}; | ||||
|  | ||||
|   Future<LinkMeta?> expandLink(String url) async { | ||||
|   | ||||
| @@ -2,9 +2,19 @@ import 'dart:math'; | ||||
|  | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:get/get.dart'; | ||||
| import 'package:google_fonts/google_fonts.dart'; | ||||
| import 'package:intl/intl.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:solian/exts.dart'; | ||||
| import 'package:solian/models/daily_sign.dart'; | ||||
| import 'package:solian/models/pagination.dart'; | ||||
| import 'package:solian/models/post.dart'; | ||||
| import 'package:solian/providers/content/posts.dart'; | ||||
| import 'package:solian/providers/daily_sign.dart'; | ||||
| import 'package:solian/providers/websocket.dart'; | ||||
| import 'package:solian/router.dart'; | ||||
| import 'package:solian/screens/account/notification.dart'; | ||||
| import 'package:solian/widgets/posts/post_list.dart'; | ||||
|  | ||||
| class DashboardScreen extends StatefulWidget { | ||||
|   const DashboardScreen({super.key}); | ||||
| @@ -15,6 +25,57 @@ class DashboardScreen extends StatefulWidget { | ||||
|  | ||||
| class _DashboardScreenState extends State<DashboardScreen> { | ||||
|   late final WebSocketProvider _ws = Get.find(); | ||||
|   late final PostProvider _posts = Get.find(); | ||||
|   late final DailySignProvider _dailySign = Get.find(); | ||||
|  | ||||
|   List<Post>? _currentPosts; | ||||
|  | ||||
|   Future<void> _pullPosts() async { | ||||
|     final prefs = await SharedPreferences.getInstance(); | ||||
|     final resp = await _posts.listRecommendations(0); | ||||
|     final result = PaginationResult.fromJson(resp.body); | ||||
|     if (prefs.containsKey('feed_last_read_at')) { | ||||
|       final id = prefs.getInt('feed_last_read_at')!; | ||||
|       setState(() { | ||||
|         _currentPosts = result.data | ||||
|             ?.map((e) => Post.fromJson(e)) | ||||
|             .where((x) => x.id > id) | ||||
|             .toList(); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   bool _signingDaily = true; | ||||
|   DailySignRecord? _signRecord; | ||||
|  | ||||
|   Future<void> _pullDaily() async { | ||||
|     try { | ||||
|       _signRecord = await _dailySign.getToday(); | ||||
|     } catch (e) { | ||||
|       context.showErrorDialog(e); | ||||
|     } | ||||
|  | ||||
|     setState(() => _signingDaily = false); | ||||
|   } | ||||
|  | ||||
|   Future<void> _signDaily() async { | ||||
|     setState(() => _signingDaily = true); | ||||
|  | ||||
|     try { | ||||
|       _signRecord = await _dailySign.signToday(); | ||||
|     } catch (e) { | ||||
|       context.showErrorDialog(e); | ||||
|     } | ||||
|  | ||||
|     setState(() => _signingDaily = false); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _pullPosts(); | ||||
|     _pullDaily(); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
| @@ -28,7 +89,65 @@ class _DashboardScreenState extends State<DashboardScreen> { | ||||
|             Text('today'.tr, style: Theme.of(context).textTheme.headlineSmall), | ||||
|             Text(DateFormat('yyyy/MM/dd').format(DateTime.now())), | ||||
|           ], | ||||
|         ).paddingOnly(top: 8, left: 18, right: 18), | ||||
|         ).paddingOnly(top: 8, left: 18, right: 18, bottom: 12), | ||||
|         Card( | ||||
|           child: ListTile( | ||||
|             leading: AnimatedSwitcher( | ||||
|               switchInCurve: Curves.fastOutSlowIn, | ||||
|               switchOutCurve: Curves.fastOutSlowIn, | ||||
|               duration: const Duration(milliseconds: 300), | ||||
|               transitionBuilder: (child, animation) { | ||||
|                 return ScaleTransition( | ||||
|                   scale: animation, | ||||
|                   child: child, | ||||
|                 ); | ||||
|               }, | ||||
|               child: _signRecord == null | ||||
|                   ? Column( | ||||
|                       mainAxisAlignment: MainAxisAlignment.center, | ||||
|                       children: [ | ||||
|                         Text( | ||||
|                           DateFormat('dd').format(DateTime.now()), | ||||
|                           style: | ||||
|                               GoogleFonts.robotoMono(fontSize: 22, height: 1.2), | ||||
|                         ), | ||||
|                         Text( | ||||
|                           DateFormat('yy/MM').format(DateTime.now()), | ||||
|                           style: GoogleFonts.robotoMono(fontSize: 12), | ||||
|                         ), | ||||
|                       ], | ||||
|                     ) | ||||
|                   : Text( | ||||
|                       _signRecord!.symbol, | ||||
|                       style: GoogleFonts.notoSerifHk(fontSize: 20, height: 1), | ||||
|                     ).paddingSymmetric(horizontal: 9), | ||||
|             ).paddingOnly(left: 4), | ||||
|             title: _signRecord == null | ||||
|                 ? const Text('诸事不宜') | ||||
|                 : Text(_signRecord!.overviewSuggestion), | ||||
|             subtitle: _signRecord == null | ||||
|                 ? const Text('今日未拜访佛祖') | ||||
|                 : Text('+${_signRecord!.resultExperience} EXP'), | ||||
|             trailing: AnimatedSwitcher( | ||||
|               switchInCurve: Curves.fastOutSlowIn, | ||||
|               switchOutCurve: Curves.fastOutSlowIn, | ||||
|               duration: const Duration(milliseconds: 300), | ||||
|               transitionBuilder: (child, animation) { | ||||
|                 return ScaleTransition( | ||||
|                   scale: animation, | ||||
|                   child: child, | ||||
|                 ); | ||||
|               }, | ||||
|               child: _signRecord == null | ||||
|                   ? IconButton( | ||||
|                       tooltip: '上香求签', | ||||
|                       icon: const Icon(Icons.local_fire_department), | ||||
|                       onPressed: _signingDaily ? null : _signDaily, | ||||
|                     ) | ||||
|                   : const SizedBox(), | ||||
|             ), | ||||
|           ), | ||||
|         ).paddingSymmetric(horizontal: 8), | ||||
|         const Divider(thickness: 0.3).paddingSymmetric(vertical: 8), | ||||
|         Obx( | ||||
|           () => Column( | ||||
| @@ -108,8 +227,72 @@ class _DashboardScreenState extends State<DashboardScreen> { | ||||
|                   ), | ||||
|                 ).paddingSymmetric(horizontal: 8), | ||||
|             ], | ||||
|           ), | ||||
|           ).paddingOnly(bottom: 12), | ||||
|         ), | ||||
|         if (_currentPosts?.isNotEmpty ?? false) | ||||
|           Column( | ||||
|             crossAxisAlignment: CrossAxisAlignment.start, | ||||
|             children: [ | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Column( | ||||
|                     crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                     children: [ | ||||
|                       Text( | ||||
|                         'feed'.tr, | ||||
|                         style: Theme.of(context) | ||||
|                             .textTheme | ||||
|                             .titleMedium! | ||||
|                             .copyWith(fontSize: 18), | ||||
|                       ), | ||||
|                       Text( | ||||
|                         'notificationUnreadCount'.trParams({ | ||||
|                           'count': (_currentPosts?.length ?? 0).toString(), | ||||
|                         }), | ||||
|                       ), | ||||
|                     ], | ||||
|                   ), | ||||
|                   IconButton( | ||||
|                     icon: const Icon(Icons.arrow_forward), | ||||
|                     onPressed: () { | ||||
|                       AppRouter.instance.goNamed('feed'); | ||||
|                     }, | ||||
|                   ), | ||||
|                 ], | ||||
|               ).paddingOnly(left: 18, right: 18, bottom: 8), | ||||
|               SizedBox( | ||||
|                 height: 360, | ||||
|                 width: width, | ||||
|                 child: ListView.builder( | ||||
|                   scrollDirection: Axis.horizontal, | ||||
|                   itemCount: _currentPosts!.length, | ||||
|                   itemBuilder: (context, idx) { | ||||
|                     final item = _currentPosts![idx]; | ||||
|                     return SizedBox( | ||||
|                       width: width, | ||||
|                       child: Card( | ||||
|                         child: Card( | ||||
|                           child: PostListEntryWidget( | ||||
|                             item: item, | ||||
|                             isClickable: true, | ||||
|                             isShowEmbed: true, | ||||
|                             isNestedClickable: true, | ||||
|                             onUpdate: (_) { | ||||
|                               _pullPosts(); | ||||
|                             }, | ||||
|                             backgroundColor: Theme.of(context) | ||||
|                                 .colorScheme | ||||
|                                 .surfaceContainerLow, | ||||
|                           ), | ||||
|                         ), | ||||
|                       ).paddingSymmetric(horizontal: 8), | ||||
|                     ); | ||||
|                   }, | ||||
|                 ), | ||||
|               ) | ||||
|             ], | ||||
|           ), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|   | ||||
| @@ -65,7 +65,7 @@ class _FeedScreenState extends State<FeedScreen> | ||||
|           headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { | ||||
|             return [ | ||||
|               SliverAppBar( | ||||
|                 title: AppBarTitle('home'.tr), | ||||
|                 title: AppBarTitle('feed'.tr), | ||||
|                 centerTitle: false, | ||||
|                 floating: true, | ||||
|                 toolbarHeight: SolianTheme.toolbarHeight(context), | ||||
|   | ||||
| @@ -60,7 +60,7 @@ class LinkExpansion extends StatelessWidget { | ||||
|       return const SizedBox(); | ||||
|     } | ||||
|  | ||||
|     final LinkExpandController expandController = Get.find(); | ||||
|     final LinkExpandProvider expandController = Get.find(); | ||||
|  | ||||
|     return Wrap( | ||||
|       children: matches.map((x) { | ||||
|   | ||||
| @@ -4,9 +4,14 @@ import 'package:get/utils.dart'; | ||||
| abstract class AppNavigation { | ||||
|   static List<AppNavigationDestination> destinations = [ | ||||
|     AppNavigationDestination( | ||||
|       icon: Icons.home, | ||||
|       label: 'home'.tr, | ||||
|       page: 'home', | ||||
|       icon: Icons.dashboard, | ||||
|       label: 'dashboard'.tr, | ||||
|       page: 'dashboard', | ||||
|     ), | ||||
|     AppNavigationDestination( | ||||
|       icon: Icons.newspaper, | ||||
|       label: 'feed'.tr, | ||||
|       page: 'feed', | ||||
|     ), | ||||
|     AppNavigationDestination( | ||||
|       icon: Icons.workspaces, | ||||
|   | ||||
							
								
								
									
										110
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -13,10 +13,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: _flutterfire_internals | ||||
|       sha256: b1595874fbc8f7a50da90f5d8f327bb0bfd6a95dc906c390efe991540c3b54aa | ||||
|       sha256: "9371d13b8ee442e3bfc08a24e3a1b3742c839abbfaf5eef11b79c4b862c89bf7" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.40" | ||||
|     version: "1.3.41" | ||||
|   _macros: | ||||
|     dependency: transitive | ||||
|     description: dart | ||||
| @@ -466,114 +466,114 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_analytics | ||||
|       sha256: "064e5b57b0693305946b7caa6a80ed80a918f46804c247b6cd7ed9cd327df48f" | ||||
|       sha256: "7e032ade38dec2a92f543ba02c5f72f54ffaa095c60d2132b867eab56de3bc73" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "11.2.1" | ||||
|     version: "11.3.0" | ||||
|   firebase_analytics_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_analytics_platform_interface | ||||
|       sha256: d094547c9022c404b5ca39b7209607fc80e75e39d38875f050508fa4346b3e74 | ||||
|       sha256: b62a2444767d95067a7e36b1d6e335e0b877968574bbbfb656168c46f2e95a13 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.2.1" | ||||
|     version: "4.2.2" | ||||
|   firebase_analytics_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_analytics_web | ||||
|       sha256: "06dc023b0144c0df630a56b6262cc9e7d6069fe78148853d97614dbefb6ea923" | ||||
|       sha256: bad44f71f96cfca6c16c9dd4f70b85f123ddca7d5dd698977449fadf298b1782 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.5.9+1" | ||||
|     version: "0.5.9+2" | ||||
|   firebase_core: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_core | ||||
|       sha256: "3187f4f8e49968573fd7403011dca67ba95aae419bc0d8131500fae160d94f92" | ||||
|       sha256: "06537da27db981947fa535bb91ca120b4e9cb59cb87278dbdde718558cafc9ff" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.3.0" | ||||
|     version: "3.4.0" | ||||
|   firebase_core_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_core_platform_interface | ||||
|       sha256: "3c3a1e92d6f4916c32deea79c4a7587aa0e9dbbe5889c7a16afcf005a485ee02" | ||||
|       sha256: f7d7180c7f99babd4b4c517754d41a09a4943a0f7a69b65c894ca5c68ba66315 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "5.2.0" | ||||
|     version: "5.2.1" | ||||
|   firebase_core_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_core_web | ||||
|       sha256: e8d1e22de72cb21cdcfc5eed7acddab3e99cd83f3b317f54f7a96c32f25fd11e | ||||
|       sha256: "362e52457ed2b7b180964769c1e04d1e0ea0259fdf7025fdfedd019d4ae2bd88" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.17.4" | ||||
|     version: "2.17.5" | ||||
|   firebase_crashlytics: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_crashlytics | ||||
|       sha256: "30260e1b8ad1464b41ca4531b44ce63d752daaf2f12c92ca6cdcd82b270abecc" | ||||
|       sha256: "4c9872020c0d97a161362ee6af7000cfdb8666234ddc290a15252ad379bb235a" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.0.4" | ||||
|     version: "4.1.0" | ||||
|   firebase_crashlytics_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_crashlytics_platform_interface | ||||
|       sha256: a75e1826d92ea4e86e4a753c7b5d64b844a362676fa653185f1581c859186d18 | ||||
|       sha256: ede8a199ff03378857d3c8cbb7fa58d37c27bb5a6b75faf8415ff6925dcaae2a | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.6.40" | ||||
|     version: "3.6.41" | ||||
|   firebase_messaging: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_messaging | ||||
|       sha256: "1b0a4f9ecbaf9007771bac152afad738ddfacc4b8431a7591c00829480d99553" | ||||
|       sha256: "29941ba5a3204d80656c0e52103369aa9a53edfd9ceae05a2bb3376f24fda453" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "15.0.4" | ||||
|     version: "15.1.0" | ||||
|   firebase_messaging_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_messaging_platform_interface | ||||
|       sha256: c5a6443e66ae064fe186901d740ee7ce648ca2a6fd0484b8c5e963849ac0fc28 | ||||
|       sha256: "26c5370d3a79b15c8032724a68a4741e28f63e1f1a45699c4f0a8ae740aadd72" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.5.42" | ||||
|     version: "4.5.43" | ||||
|   firebase_messaging_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_messaging_web | ||||
|       sha256: "232ef63b986467ae5b5577a09c2502b26e2e2aebab5b85e6c966a5ca9b038b89" | ||||
|       sha256: "58276cd5d9e22a9320ef9e5bc358628920f770f93c91221f8b638e8346ed5df4" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.8.12" | ||||
|     version: "3.8.13" | ||||
|   firebase_performance: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_performance | ||||
|       sha256: "6d17133458b9627f15f278d6f71bebbbce885d393f3462b690e55deeb5c36b90" | ||||
|       sha256: "66666f697ecdcca2616af99f8ccfa74d795e5819c598227f2784fc00b1c6e421" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.10.0+4" | ||||
|     version: "0.10.0+5" | ||||
|   firebase_performance_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_performance_platform_interface | ||||
|       sha256: "28dc0a70a3459fe51d1c1be5754803a9a0db0e210322ec7526f6ce42bf6ad83e" | ||||
|       sha256: ceaa026d067347cc6ea11113ba926ae450f56e305c186d1edce78f05983b481a | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.1.4+40" | ||||
|     version: "0.1.4+41" | ||||
|   firebase_performance_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_performance_web | ||||
|       sha256: db91d86b34280f5253d2913945fdd51d7114486584a298a7bedf1c4b2ab08f79 | ||||
|       sha256: "6d121cd7e27b63995998dc4039caf0cbf304c2eee6fc6ed9ac7f80860cc0e51c" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.1.6+12" | ||||
|     version: "0.1.6+13" | ||||
|   fixnum: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -853,6 +853,22 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "10.7.0" | ||||
|   freezed: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
|       name: freezed | ||||
|       sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.5.7" | ||||
|   freezed_annotation: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: freezed_annotation | ||||
|       sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.4" | ||||
|   frontend_server_client: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -893,6 +909,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "14.2.7" | ||||
|   google_fonts: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: google_fonts | ||||
|       sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.2.1" | ||||
|   graphs: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1070,13 +1094,21 @@ packages: | ||||
|     source: hosted | ||||
|     version: "0.6.7" | ||||
|   json_annotation: | ||||
|     dependency: transitive | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: json_annotation | ||||
|       sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.9.0" | ||||
|   json_serializable: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
|       name: json_serializable | ||||
|       sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.8.0" | ||||
|   leak_tracker: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1265,10 +1297,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: mime | ||||
|       sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" | ||||
|       sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.5" | ||||
|     version: "1.0.6" | ||||
|   nested: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1778,6 +1810,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.5.0" | ||||
|   source_helper: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: source_helper | ||||
|       sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.4" | ||||
|   source_span: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -2030,10 +2070,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: uuid | ||||
|       sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" | ||||
|       sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.4.2" | ||||
|     version: "4.5.0" | ||||
|   vector_graphics: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|   | ||||
| @@ -73,6 +73,9 @@ dependencies: | ||||
|   media_kit_libs_video: ^1.0.4 | ||||
|   flutter_svg: ^2.0.10+1 | ||||
|   cross_file: ^0.3.4+2 | ||||
|   google_fonts: ^6.2.1 | ||||
|   freezed_annotation: ^2.4.4 | ||||
|   json_annotation: ^4.9.0 | ||||
|  | ||||
| dev_dependencies: | ||||
|   flutter_test: | ||||
| @@ -82,10 +85,12 @@ dev_dependencies: | ||||
|   flutter_launcher_icons: ^0.13.1 | ||||
|  | ||||
|   floor_generator: ^1.4.0 | ||||
|   build_runner: ^2.1.2 | ||||
|   build_runner: ^2.4.12 | ||||
|   sqflite_common_ffi: ^2.3.3 | ||||
|   sqflite_common_ffi_web: ^0.4.3+1 | ||||
|   flutter_native_splash: ^2.4.1 | ||||
|   freezed: ^2.5.7 | ||||
|   json_serializable: ^6.8.0 | ||||
|  | ||||
| flutter: | ||||
|   uses-material-design: true | ||||
|   | ||||
		Reference in New Issue
	
	Block a user