From 23264dfd7e304cc2cbf14712f645cb4605bf2455 Mon Sep 17 00:00:00 2001 From: Lex Lim Date: Mon, 30 Jan 2023 08:35:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=A1=B5=E9=9D=A2=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E7=9A=84=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/app_bridge.js | 55 ++-- ios/Podfile.lock | 25 +- ios/Runner.xcodeproj/project.pbxproj | 4 +- lib/api/response/page_info.dart | 34 ++- lib/app.dart | 6 +- lib/components/auto_wrap.dart | 111 +++++++ lib/components/page_card.dart | 62 ++-- lib/components/page_card.getx.dart | 2 +- lib/components/recent_page_list.dart | 32 +- lib/pages/home.dart | 233 ++++++++------- lib/pages/wiki/info.dart | 213 +++++++++++++ lib/pages/{article.dart => wiki/view.dart} | 44 +-- lib/utils/utils.dart | 3 +- macos/Podfile | 2 +- macos/Runner.xcodeproj/project.pbxproj | 9 +- pubspec.lock | 328 ++++++++++----------- 16 files changed, 797 insertions(+), 366 deletions(-) create mode 100644 lib/components/auto_wrap.dart create mode 100644 lib/pages/wiki/info.dart rename lib/pages/{article.dart => wiki/view.dart} (86%) diff --git a/assets/js/app_bridge.js b/assets/js/app_bridge.js index 2715a53..6b67107 100644 --- a/assets/js/app_bridge.js +++ b/assets/js/app_bridge.js @@ -5,15 +5,40 @@ var titleList = []; var currentTitle = '_top'; var titleOffset = 10; +window.MugenApp = { + emit: function() { + window.flutter_inappwebview.callHandler.apply(this, arguments); + }, + scrollToTitle: function (anchor) { + var el = document.getElementById(anchor); + if (el) { + var scrollTop = window.scrollY + el.getBoundingClientRect().top; + if (navigator.safeArea) { + scrollTop -= navigator.safeArea.top + titleOffset; + } + scrollTop = Math.max(0, scrollTop); + + enableScrollSpy = false; + window.scrollTo({ + top: scrollTop, + }); + + setTimeout(function() { + enableScrollSpy = true; + }, 50); + } + }, +}; + function onReadyStateChange() { if (_InAppWebViewReady && document.readyState === "complete") { titleList = document.querySelectorAll('.mw-parser-output h1, .mw-parser-output h2, .mw-parser-output h3, .mw-parser-output h4, .mw-parser-output h5, .mw-parser-output h6'); - window.flutter_inappwebview.callHandler('pageLoaded', true); + window.MugenApp.emit('pageLoaded', true); } } window.addEventListener("flutterInAppWebViewPlatformReady", function(event) { _InAppWebViewReady = true; - window.flutter_inappwebview.callHandler('bridgeConnected', true); + window.MugenApp.emit('bridgeConnected', true); onReadyStateChange(); }); @@ -67,28 +92,6 @@ document.addEventListener('scroll', debouce(function() { if (newCurrentTitle && newCurrentTitle !== currentTitle) { currentTitle = newCurrentTitle; - window.flutter_inappwebview.callHandler('sectionChange', newCurrentTitle); + window.MugenApp.emit('sectionChange', newCurrentTitle); } -}, 200), { passive: true }); - -window.MugenApp = { - scrollToTitle: function (anchor) { - var el = document.getElementById(anchor); - if (el) { - var scrollTop = window.scrollY + el.getBoundingClientRect().top; - if (navigator.safeArea) { - scrollTop -= navigator.safeArea.top + titleOffset; - } - scrollTop = Math.max(0, scrollTop); - - enableScrollSpy = false; - window.scrollTo({ - top: scrollTop, - }); - - setTimeout(function() { - enableScrollSpy = true; - }, 50); - } - }, -}; \ No newline at end of file +}, 200), { passive: true }); \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 934d9cf..1fa3d90 100755 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -7,6 +7,8 @@ PODS: - flutter_inappwebview/Core (0.0.1): - Flutter - OrderedSet (~> 5.0) + - flutter_share (0.0.1): + - Flutter - flutter_web_browser (0.17.1): - Flutter - fluttertoast (0.0.2): @@ -18,7 +20,10 @@ PODS: - OrderedSet (5.0.0) - package_info_plus (0.4.5): - Flutter - - path_provider_ios (0.0.1): + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - share_plus (0.0.1): - Flutter - sqflite (0.0.2): - Flutter @@ -36,10 +41,12 @@ PODS: DEPENDENCIES: - Flutter (from `Flutter`) - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) + - flutter_share (from `.symlinks/plugins/flutter_share/ios`) - flutter_web_browser (from `.symlinks/plugins/flutter_web_browser/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) @@ -57,14 +64,18 @@ EXTERNAL SOURCES: :path: Flutter flutter_inappwebview: :path: ".symlinks/plugins/flutter_inappwebview/ios" + flutter_share: + :path: ".symlinks/plugins/flutter_share/ios" flutter_web_browser: :path: ".symlinks/plugins/flutter_web_browser/ios" fluttertoast: :path: ".symlinks/plugins/fluttertoast/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" - path_provider_ios: - :path: ".symlinks/plugins/path_provider_ios/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/ios" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" sqflite: :path: ".symlinks/plugins/sqflite/ios" url_launcher_ios: @@ -79,15 +90,17 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721 + flutter_share: 4be0208963c60b537e6255ed2ce1faae61cd9ac2 flutter_web_browser: 7bccaafbb0c5b8862afe7bcd158f15557109f61f fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e - path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 + share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 - url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de + url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2 video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0f65ac2..d9a49ad 100755 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -217,6 +217,7 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -253,6 +254,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); diff --git a/lib/api/response/page_info.dart b/lib/api/response/page_info.dart index 1ec2748..a717fbd 100644 --- a/lib/api/response/page_info.dart +++ b/lib/api/response/page_info.dart @@ -6,6 +6,18 @@ import 'package:isekai_wiki/utils/utils.dart'; part 'page_info.freezed.dart'; part 'page_info.g.dart'; +@freezed +class MWPageProtectionInfo with _$MWPageProtectionInfo { + factory MWPageProtectionInfo({ + required String type, + required String level, + required String expiry, + }) = _MWPageProtectionInfo; + + factory MWPageProtectionInfo.fromJson(Map json) => + _$MWPageProtectionInfoFromJson(json); +} + @JsonSerializable() class PageInfo { int pageid; @@ -34,6 +46,12 @@ class PageInfo { String? editurl; String? canonicalurl; + int? watchers; + int? visitingwatchers; + + MWPageProtectionInfo? protection; + List? restrictiontypes; + PageInfo({ required this.pageid, required this.ns, @@ -52,6 +70,10 @@ class PageInfo { this.fullurl, this.editurl, this.canonicalurl, + this.watchers, + this.visitingwatchers, + this.protection, + this.restrictiontypes, }); String get mainTitle { @@ -62,7 +84,8 @@ class PageInfo { return null; } - factory PageInfo.fromJson(Map json) => _$PageInfoFromJson(json); + factory PageInfo.fromJson(Map json) => + _$PageInfoFromJson(json); Map toJson() => _$PageInfoToJson(this); @@ -87,12 +110,15 @@ class PageInfo { class PagesResponse with _$PagesResponse { factory PagesResponse({required List pages}) = _PageResponse; - factory PagesResponse.fromJson(Map json) => _$PagesResponseFromJson(json); + factory PagesResponse.fromJson(Map json) => + _$PagesResponseFromJson(json); } @Freezed(copyWith: false) class PageImageInfo with _$PageImageInfo { - factory PageImageInfo({required String source, int? width, int? height}) = _PageImageInfo; + factory PageImageInfo({required String source, int? width, int? height}) = + _PageImageInfo; - factory PageImageInfo.fromJson(Map json) => _$PageImageInfoFromJson(json); + factory PageImageInfo.fromJson(Map json) => + _$PageImageInfoFromJson(json); } diff --git a/lib/app.dart b/lib/app.dart index 9c224fe..04b93b1 100755 --- a/lib/app.dart +++ b/lib/app.dart @@ -79,8 +79,8 @@ class IsekaiWikiApp extends StatelessWidget { GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ - Locale('zh', 'CN'), Locale('en'), + Locale('zh', 'CN'), ], initialBinding: InitialBinding(), home: _buildApp(context), @@ -97,7 +97,9 @@ class IsekaiWikiApp extends StatelessWidget { ? Styles.materialLightTheme : Styles.materialDarkTheme, child: CupertinoTheme( - data: Styles.cupertinoTheme.copyWith(brightness: brightness), child: child), + data: + Styles.cupertinoTheme.copyWith(brightness: brightness), + child: child), ), ); } diff --git a/lib/components/auto_wrap.dart b/lib/components/auto_wrap.dart new file mode 100644 index 0000000..8896447 --- /dev/null +++ b/lib/components/auto_wrap.dart @@ -0,0 +1,111 @@ +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; + +class AutoWrap extends StatefulWidget { + final List children; + + const AutoWrap({super.key, required this.children}); + + @override + State createState() => _AutoWrapState(); +} + +class _AutoWrapState extends State { + var _computed = false; + var _isFirstBuild = true; + final Map _childWidth = {}; + var _isRow = true; + + void handleSizeChange(Size size, int id) { + _childWidth[id] = size.width; + } + + @override + void didUpdateWidget(covariant AutoWrap oldWidget) { + super.didUpdateWidget(oldWidget); + if (_isFirstBuild) { + _isFirstBuild = false; + var sum = _childWidth.values.reduce((value, element) => value + element); + var width = context.size?.width ?? 0; + + setState(() { + _computed = true; + _isRow = sum < width; + }); + } + } + + @override + Widget build(BuildContext context) { + if (!_computed) { + List stackChildren = []; + for (var i = 0; i < widget.children.length; i++) { + // Only first child is visible + stackChildren.add( + Opacity( + opacity: i == 0 ? 1 : 0, + child: WidgetSizeOffsetWrapper( + id: i, + onSizeChange: handleSizeChange, + child: widget.children[i], + ), + ), + ); + } + return Stack( + children: stackChildren, + ); + } else { + if (_isRow) { + return Row(children: widget.children); + } else { + return Column(children: widget.children); + } + } + } +} + +typedef OnWidgetSizeChange = void Function(Size size, int id); + +class WidgetSizeRenderObject extends RenderProxyBox { + final OnWidgetSizeChange onSizeChange; + final int id; + Size? currentSize; + + WidgetSizeRenderObject(this.onSizeChange, this.id); + + @override + void performLayout() { + super.performLayout(); + + try { + Size? newSize = child?.size; + + if (newSize != null && currentSize != newSize) { + currentSize = newSize; + WidgetsBinding.instance.addPostFrameCallback((_) { + onSizeChange(newSize, id); + }); + } + } catch (e) { + print(e); + } + } +} + +class WidgetSizeOffsetWrapper extends SingleChildRenderObjectWidget { + final OnWidgetSizeChange onSizeChange; + final int id; + + const WidgetSizeOffsetWrapper({ + Key? key, + required this.onSizeChange, + required this.id, + required Widget child, + }) : super(key: key, child: child); + + @override + RenderObject createRenderObject(BuildContext context) { + return WidgetSizeRenderObject(onSizeChange, id); + } +} diff --git a/lib/components/page_card.dart b/lib/components/page_card.dart index 53097d5..cdd0767 100755 --- a/lib/components/page_card.dart +++ b/lib/components/page_card.dart @@ -7,22 +7,28 @@ import 'package:isekai_wiki/api/response/page_info.dart'; import 'package:isekai_wiki/components/flutter_scale_tap/flutter_scale_tap.dart'; import 'package:isekai_wiki/components/isekai_text.dart'; import 'package:isekai_wiki/components/utils.dart'; -import 'package:isekai_wiki/pages/article.dart'; +import 'package:isekai_wiki/pages/wiki/info.dart'; +import 'package:isekai_wiki/pages/wiki/view.dart'; import 'package:like_button/like_button.dart'; import 'package:pull_down_button/pull_down_button.dart'; import 'package:skeletons/skeletons.dart'; -typedef AddFavoriteCallback = Future Function(PageInfo pageInfo, bool localIsFavorite); +typedef AddFavoriteCallback = Future Function( + PageInfo pageInfo, bool localIsFavorite); typedef PageInfoCallback = Future Function(PageInfo pageInfo); class PageCardStyles { static const cardContainerHeight = 100.0; static const cardContentHeight = 100.0; - static const cardHeaderPadding = EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 16); - static const cardHeaderCompactPadding = EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 10); - static const cardContentPadding = EdgeInsets.only(top: 0, left: 20, right: 20, bottom: 14); - static const cardFooterPadding = EdgeInsets.only(top: 0, left: 20, right: 20, bottom: 14); + static const cardHeaderPadding = + EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 16); + static const cardHeaderCompactPadding = + EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 10); + static const cardContentPadding = + EdgeInsets.only(top: 0, left: 20, right: 20, bottom: 14); + static const cardFooterPadding = + EdgeInsets.only(top: 0, left: 20, right: 20, bottom: 14); static const titleFontSize = 24.0; static const subTitleFontSize = 12.0; static const contentFontSize = 14.0; @@ -95,8 +101,18 @@ class PageCard extends StatelessWidget { } } - void handlePageInfoClick() { - if (pageInfo != null) {} + void handlePageInfoClick() async { + if (pageInfo != null) { + var cPageInfo = pageInfo!; + await Navigator.of(Get.context!).push( + CupertinoPageRoute( + builder: (_) => WikiInfoPage( + targetPage: cPageInfo.title, + targetPageId: cPageInfo.pageid, + ), + ), + ); + } } Future handleCardClick() async { @@ -108,8 +124,9 @@ class PageCard extends StatelessWidget { var cPageInfo = pageInfo!; await Navigator.of(Get.context!).push( CupertinoPageRoute( - builder: (_) => ArticlePage( + builder: (_) => WikiViewPage( targetPage: cPageInfo.title, + targetPageId: cPageInfo.pageid, initialArticleData: MinimumArticleData( title: cPageInfo.mainTitle, description: cPageInfo.description, @@ -127,7 +144,8 @@ class PageCard extends StatelessWidget { isLoading: isLoading, skeleton: const SkeletonLine( style: SkeletonLineStyle( - width: PageCardStyles.footerButtonSize, height: PageCardStyles.footerButtonSize), + width: PageCardStyles.footerButtonSize, + height: PageCardStyles.footerButtonSize), ), child: child, ); @@ -154,7 +172,8 @@ class PageCard extends StatelessWidget { isLoading: isLoading, skeleton: SkeletonLine( style: SkeletonLineStyle( - height: (PageCardStyles.titleFontSize * 1.1) * textScale, randomLength: true), + height: (PageCardStyles.titleFontSize * 1.1) * textScale, + randomLength: true), ), child: IsekaiText( pageInfo?.mainTitle ?? "页面信息丢失", @@ -186,12 +205,15 @@ class PageCard extends StatelessWidget { style: SkeletonParagraphStyle( lines: 3, padding: EdgeInsets.symmetric( - vertical: PageCardStyles.contentFontSize * textScale * 0.2, + vertical: PageCardStyles.contentFontSize * + textScale * + 0.2, horizontal: 0, ), lineStyle: SkeletonLineStyle( randomLength: true, - height: PageCardStyles.contentFontSize * textScale), + height: + PageCardStyles.contentFontSize * textScale), ), ), ) @@ -232,7 +254,9 @@ class PageCard extends StatelessWidget { style: const TextStyle(color: Colors.black54)), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap) : const SizedBox(), - pageInfo?.mainCategory != null ? const SizedBox(width: 10) : const SizedBox(), + pageInfo?.mainCategory != null + ? const SizedBox(width: 10) + : const SizedBox(), // 发布日期 Skeleton( isLoading: isLoading, @@ -240,7 +264,9 @@ class PageCard extends StatelessWidget { style: SkeletonLineStyle(width: 100), ), child: Text( - pageInfo?.updatedTime != null ? Utils.getFriendDate(pageInfo!.updatedTime!) : "", + pageInfo?.updatedTime != null + ? Utils.getFriendDate(pageInfo!.updatedTime!) + : "", overflow: TextOverflow.fade, style: PageCardStyles.contentTextStyle, textScaleFactor: max(1, MediaQuery.of(context).textScaleFactor), @@ -345,7 +371,8 @@ class PageCard extends StatelessWidget { borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( - color: Theme.of(context).cardTheme.shadowColor ?? Colors.transparent, + color: + Theme.of(context).cardTheme.shadowColor ?? Colors.transparent, blurRadius: 12, offset: const Offset(0, 2), ), @@ -353,7 +380,8 @@ class PageCard extends StatelessWidget { ), child: SizedBox( height: PageCardStyles.cardContainerHeight + - (PageCardStyles.cardContentHeight * max(1, MediaQuery.of(context).textScaleFactor)), + (PageCardStyles.cardContentHeight * + max(1, MediaQuery.of(context).textScaleFactor)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/components/page_card.getx.dart b/lib/components/page_card.getx.dart index e43cdef..e0dc85d 100644 --- a/lib/components/page_card.getx.dart +++ b/lib/components/page_card.getx.dart @@ -4,7 +4,7 @@ import 'package:get/get.dart'; import 'package:isekai_wiki/api/response/page_info.dart'; import 'package:isekai_wiki/components/flutter_scale_tap/flutter_scale_tap.dart'; import 'package:isekai_wiki/components/utils.dart'; -import 'package:isekai_wiki/pages/article.dart'; +import 'package:isekai_wiki/pages/wiki/view.dart'; import 'package:isekai_wiki/reactive/reactive.dart'; import 'package:like_button/like_button.dart'; import 'package:pull_down_button/pull_down_button.dart'; diff --git a/lib/components/recent_page_list.dart b/lib/components/recent_page_list.dart index a18cf98..204bedf 100755 --- a/lib/components/recent_page_list.dart +++ b/lib/components/recent_page_list.dart @@ -13,6 +13,7 @@ class RecentPageListController extends GetxController { ScrollController? scrollController; UserController? uc; FavoriteListController? flc; + double insetBottom = 0; var shouldRefresh = true; @@ -28,7 +29,8 @@ class RecentPageListController extends GetxController { @override void onInit() { scrollController?.addListener(() { - if (scrollController!.position.pixels > scrollController!.position.maxScrollExtent - 10) { + if (scrollController!.position.pixels > + scrollController!.position.maxScrollExtent - 10) { // 滚动到底部 if (hasNextPage.value && !isLoading.value) { loadNextPages(); @@ -72,7 +74,8 @@ class RecentPageListController extends GetxController { try { var rcListRes = await MWApiList.getMixedRecentChanges( - limit: 10, continueInfo: continueInfo.isNotEmpty ? continueInfo : null); + limit: 10, + continueInfo: continueInfo.isNotEmpty ? continueInfo : null); var pageIds = rcListRes.data.map((rcInfo) => rcInfo.pageid).toList(); var pageListRes = await MWApiList.getPageInfoList( @@ -116,23 +119,23 @@ class RecentPageListController extends GetxController { class RecentPageList extends StatelessWidget { final ScrollController? scrollController; + final double insetBottom; - const RecentPageList({ - super.key, - this.scrollController, - }); + const RecentPageList( + {super.key, this.scrollController, this.insetBottom = 0}); Widget _buildSkeletonList() { return Column( key: key, children: [ - for (var i = 0; i < 6; i++) PageCard(key: ValueKey("rpl-card-$i"), isLoading: true), + for (var i = 0; i < 6; i++) + PageCard(key: ValueKey("rpl-card-$i"), isLoading: true), ], ); } - Widget _buildPageCard( - int index, PageInfo pageInfo, RecentPageListController c, FavoriteListController flc) { + Widget _buildPageCard(int index, PageInfo pageInfo, + RecentPageListController c, FavoriteListController flc) { return PageCard( key: ValueKey("rpl-card-$index"), pageInfo: c.pageList[index], @@ -169,12 +172,15 @@ class RecentPageList extends StatelessWidget { child: Center( child: Obx( () => c.isLoading.value - ? const CupertinoActivityIndicator( - radius: 14, + ? Padding( + padding: EdgeInsets.only(bottom: insetBottom), + child: const CupertinoActivityIndicator( + radius: 14, + ), ) - : const SizedBox( + : SizedBox( width: 28, - height: 28, + height: 28 + insetBottom, ), ), ), diff --git a/lib/pages/home.dart b/lib/pages/home.dart index da1647f..99ed0d1 100755 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -7,6 +7,7 @@ import 'package:get/get.dart'; import 'package:isekai_wiki/components/isekai_nav_bar.dart'; import 'package:isekai_wiki/components/isekai_page_scaffold.dart'; import 'package:isekai_wiki/components/recent_page_list.dart'; +import 'package:isekai_wiki/components/safearea_builder.dart'; import 'package:isekai_wiki/models/user.dart'; import 'package:isekai_wiki/pages/tab_page.dart'; import 'package:web_smooth_scroll/web_smooth_scroll.dart'; @@ -22,7 +23,8 @@ const Color _kDefaultTabBarBorderColor = CupertinoDynamicColor.withBrightness( enum HomeTabs { newest, followed } -class HomeController extends GetxController with GetSingleTickerProviderStateMixin { +class HomeController extends GetxController + with GetSingleTickerProviderStateMixin { double _navSearchButtonOffset = 90; var showNavSearchButton = false.obs; @@ -41,12 +43,15 @@ class HomeController extends GetxController with GetSingleTickerProviderStateMix void onInit() { tabController = TabController(length: 2, vsync: this); - _navSearchButtonOffset = 48 * MediaQuery.of(Get.context!).textScaleFactor + 48; + _navSearchButtonOffset = + 48 * MediaQuery.of(Get.context!).textScaleFactor + 48; scrollController.addListener(() { - if (scrollController.offset >= _navSearchButtonOffset && !showNavSearchButton.value) { + if (scrollController.offset >= _navSearchButtonOffset && + !showNavSearchButton.value) { showNavSearchButton.value = true; - } else if (scrollController.offset < _navSearchButtonOffset && showNavSearchButton.value) { + } else if (scrollController.offset < _navSearchButtonOffset && + showNavSearchButton.value) { showNavSearchButton.value = false; } }); @@ -104,7 +109,8 @@ class HomeTab extends StatelessWidget { duration: const Duration(milliseconds: 100), child: CupertinoButton( padding: EdgeInsets.zero, - child: const Icon(CupertinoIcons.bell, size: 26, color: Styles.themeNavTitleColor), + child: const Icon(CupertinoIcons.bell, + size: 26, color: Styles.themeNavTitleColor), onPressed: () {}, ), ), @@ -120,7 +126,8 @@ class HomeTab extends StatelessWidget { duration: const Duration(milliseconds: 100), child: CupertinoButton( padding: EdgeInsets.zero, - child: const Icon(CupertinoIcons.search, size: 26, color: Styles.themeNavTitleColor), + child: const Icon(CupertinoIcons.search, + size: 26, color: Styles.themeNavTitleColor), onPressed: () { onSearchClick?.call(); }, @@ -134,126 +141,135 @@ class HomeTab extends StatelessWidget { final c = Get.put(HomeController()); return IsekaiPageScaffold( - child: WebSmoothScroll( - controller: c.scrollController, - child: CustomScrollView( + child: SafeAreaBuilder( + builder: (_, safeArea) => WebSmoothScroll( controller: c.scrollController, - physics: const BouncingScrollPhysics( - parent: AlwaysScrollableScrollPhysics(), - ), - slivers: [ - IsekaiSliverNavigationBar( - leading: _buildSearchIconButton(), - backgroundColor: Styles.themeMainColor, - brightness: Brightness.dark, - largeTitle: const Text('首页', style: TextStyle(color: Styles.themeNavTitleColor)), - trailing: _buildNotificationIconButton(), - border: Border.all(style: BorderStyle.none), + child: CustomScrollView( + controller: c.scrollController, + physics: const BouncingScrollPhysics( + parent: AlwaysScrollableScrollPhysics(), ), - SliverPersistentHeader( - delegate: _SliverAppBarDelegate( - minHeight: 48, - maxHeight: 48, - child: Container( - decoration: const BoxDecoration( - color: Styles.themeMainColor, - boxShadow: [ - BoxShadow( - color: Styles.themeMainColor, - blurRadius: 0.0, - spreadRadius: 0.0, - offset: Offset(0, -2), - ), - ], - ), - padding: const EdgeInsets.only(bottom: 10, left: 12, right: 12), - child: CupertinoButton( - color: Colors.white, - padding: const EdgeInsets.all(0), - onPressed: () { - onSearchClick?.call(); - }, - child: Wrap( - spacing: 14, - alignment: WrapAlignment.spaceBetween, - children: [ - Container( - padding: const EdgeInsets.all(1), - child: const Icon(CupertinoIcons.search, color: Colors.black54), + slivers: [ + IsekaiSliverNavigationBar( + leading: _buildSearchIconButton(), + backgroundColor: Styles.themeMainColor, + brightness: Brightness.dark, + largeTitle: const Text('首页', + style: TextStyle(color: Styles.themeNavTitleColor)), + trailing: _buildNotificationIconButton(), + border: Border.all(style: BorderStyle.none), + ), + SliverPersistentHeader( + delegate: _SliverAppBarDelegate( + minHeight: 48, + maxHeight: 48, + child: Container( + decoration: const BoxDecoration( + color: Styles.themeMainColor, + boxShadow: [ + BoxShadow( + color: Styles.themeMainColor, + blurRadius: 0.0, + spreadRadius: 0.0, + offset: Offset(0, -2), ), - const Text("搜索页面...", - textAlign: TextAlign.center, style: TextStyle(color: Colors.black54)) ], ), + padding: + const EdgeInsets.only(bottom: 10, left: 12, right: 12), + child: CupertinoButton( + color: Colors.white, + padding: const EdgeInsets.all(0), + onPressed: () { + onSearchClick?.call(); + }, + child: Wrap( + spacing: 14, + alignment: WrapAlignment.spaceBetween, + children: [ + Container( + padding: const EdgeInsets.all(1), + child: const Icon(CupertinoIcons.search, + color: Colors.black54), + ), + const Text("搜索页面...", + textAlign: TextAlign.center, + style: TextStyle(color: Colors.black54)) + ], + ), + ), ), ), ), - ), - if (Global.siteConfig.enableFollowing) // 仅在站点开启关注功能时显示 + if (Global.siteConfig.enableFollowing) // 仅在站点开启关注功能时显示 + SliverPersistentHeader( + pinned: true, + delegate: _SliverAppBarDelegate( + minHeight: 40.0, + maxHeight: 40.0, + child: Container( + decoration: + BoxDecoration(color: Colors.white, boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + spreadRadius: 2, + blurRadius: 4, + offset: const Offset(0, 2), + ) + ]), + child: Row( + children: [ + SizedBox( + child: TabBar( + isScrollable: true, + controller: c.tabController, + indicatorColor: Styles.themeMainColor, + labelColor: Styles.themeMainColor, + unselectedLabelColor: Colors.black45, + tabs: const [ + CollapsedTabText('最新'), + CollapsedTabText('关注') + ], + onTap: (int selected) {}, + ), + ), + const Expanded(child: Text('')), + ], + ), + ), + ), + ), SliverPersistentHeader( pinned: true, delegate: _SliverAppBarDelegate( - minHeight: 40.0, - maxHeight: 40.0, + minHeight: 1, + maxHeight: 1, child: Container( - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.2), - spreadRadius: 2, - blurRadius: 4, - offset: const Offset(0, 2), - ) - ]), - child: Row( - children: [ - SizedBox( - child: TabBar( - isScrollable: true, - controller: c.tabController, - indicatorColor: Styles.themeMainColor, - labelColor: Styles.themeMainColor, - unselectedLabelColor: Colors.black45, - tabs: const [CollapsedTabText('最新'), CollapsedTabText('关注')], - onTap: (int selected) {}, - ), - ), - const Expanded(child: Text('')), + decoration: BoxDecoration( + color: Theme.of(context).shadowColor, + boxShadow: [ + BoxShadow( + color: Theme.of(context).shadowColor, + spreadRadius: 5, + blurRadius: 4, + ) ], ), ), ), ), - SliverPersistentHeader( - pinned: true, - delegate: _SliverAppBarDelegate( - minHeight: 1, - maxHeight: 1, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).shadowColor, - boxShadow: [ - BoxShadow( - color: Theme.of(context).shadowColor, - spreadRadius: 5, - blurRadius: 4, - ) - ], - ), - ), + CupertinoSliverRefreshControl( + onRefresh: c.handleRefresh, ), - ), - CupertinoSliverRefreshControl( - onRefresh: c.handleRefresh, - ), - SliverSafeArea( - top: false, - bottom: false, - minimum: const EdgeInsets.only(top: 12, bottom: 12), - sliver: RecentPageList( - scrollController: c.scrollController, + SliverSafeArea( + top: false, + minimum: const EdgeInsets.only(top: 12, bottom: 12), + sliver: RecentPageList( + scrollController: c.scrollController, + ), ), - ), - ], + ], + ), ), ), ); @@ -278,7 +294,8 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate { double get maxExtent => max(maxHeight, minHeight); @override - Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { return SizedBox.expand(child: child); } diff --git a/lib/pages/wiki/info.dart b/lib/pages/wiki/info.dart new file mode 100644 index 0000000..aef264d --- /dev/null +++ b/lib/pages/wiki/info.dart @@ -0,0 +1,213 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart'; +import 'package:isekai_wiki/api/mw/list.dart'; +import 'package:isekai_wiki/api/mw/mw_api.dart'; +import 'package:isekai_wiki/api/response/page_info.dart'; +import 'package:isekai_wiki/components/auto_wrap.dart'; +import 'package:isekai_wiki/components/isekai_nav_bar.dart'; +import 'package:isekai_wiki/components/isekai_page_scaffold.dart'; +import 'package:isekai_wiki/global.dart'; +import 'package:isekai_wiki/reactive/reactive.dart'; +import 'package:isekai_wiki/utils/dialog.dart'; +import 'package:isekai_wiki/utils/error.dart'; + +class WikiInfoPageController extends GetxController { + var pageTitle = "".obs; + var pageId = 0.obs; + var pageInfo = Rx(null); + var loadingPageInfo = true.obs; + + @override + void onInit() { + super.onInit(); + + Future.delayed(const Duration(milliseconds: 150)).then((_) { + loadPageInfo(); + }); + } + + Future loadPageInfo() async { + if (pageTitle.isNotEmpty || pageId.value != 0) { + try { + // 加载页面信息 + loadingPageInfo.value = true; + MWResponse> pageInfoRes; + if (pageId.value != 0) { + pageInfoRes = await MWApiList.getPageInfoList(pageids: [ + pageId.value + ], prop: [ + "extracts", + "info", + "pageimages", + "pageviews" + ], extraParams: { + "inprop": + "url|protection|watched|watchers|visitingwatchers|displaytitle", + }); + } else { + pageInfoRes = + await MWApiList.getPageInfoList(titles: [pageTitle.value]); + } + if (pageInfoRes.data.isEmpty) { + throw MWApiErrorException(code: 'no-page', info: "页面信息丢失"); + } + + pageInfo.value = pageInfoRes.data[0]; + pageId.value = pageInfo.value!.pageid; + pageTitle.value = pageInfo.value!.title; + } catch (err, stack) { + alert(Get.overlayContext!, ErrorUtils.getErrorMessage(err), + title: "错误"); + if (kDebugMode) { + print("Exception in page: $err"); + stack.printError(); + } + } finally { + loadingPageInfo.value = false; + } + } else { + alert(Get.overlayContext!, "页面不存在"); + } + } +} + +class WikiInfoPage extends StatefulWidget { + final String? targetPage; + final int? targetPageId; + + const WikiInfoPage({super.key, this.targetPage, this.targetPageId}); + + @override + State createState() => _WikiInfoPageState(); +} + +class _WikiInfoPageState extends ReactiveState { + WikiInfoPageController c = WikiInfoPageController(); + + @override + void initState() { + super.initState(); + + c = Get.put(c); + } + + @override + void dispose() { + c.dispose(); + super.dispose(); + } + + @override + void receiveProps() { + c.pageId.value = widget.targetPageId ?? 0; + c.pageTitle.value = widget.targetPage ?? ""; + } + + Widget buildLoading(BuildContext context) { + return CupertinoListSection.insetGrouped( + header: Text("基本信息"), + backgroundColor: CupertinoTheme.of(context).scaffoldBackgroundColor, + children: [ + CupertinoListTile.notched( + title: Center( + child: CupertinoActivityIndicator( + radius: 10 * MediaQuery.of(context).textScaleFactor), + ), + ), + ], + ); + } + + CupertinoListTile buildPageInfo( + BuildContext context, String label, dynamic value, + {VoidFutureCallback? onTap}) { + final Locale appLocale = Localizations.localeOf(context); + var valueStr = "未知"; + if (value is String) { + valueStr = value; + } + if (value is int) { + valueStr = + NumberFormat.decimalPattern(appLocale.toLanguageTag()).format(value); + } else if (value is double) { + var pattern = NumberFormat.decimalPattern(appLocale.toLanguageTag()); + pattern.maximumFractionDigits = 2; + valueStr = pattern.format(value); + } else if (value is DateTime) { + // ignore: prefer_interpolation_to_compose_strings + valueStr = DateFormat.yMMMd(appLocale.toLanguageTag()).format(value) + + " " + + DateFormat.Hms(appLocale.toLanguageTag()).format(value); + } + + return CupertinoListTile.notched( + padding: const EdgeInsetsDirectional.fromSTEB(20.0, 10.0, 14.0, 10.0), + title: Container( + width: MediaQuery.of(context).size.width, + child: AutoWrap( + children: [ + Text(label), + Text( + valueStr, + style: TextStyle( + color: CupertinoColors.systemGrey2.resolveFrom(context)), + ), + ], + ), + ), + trailing: onTap != null ? const CupertinoListTileChevron() : null, + onTap: onTap, + ); + } + + Widget buildPageInfoList(BuildContext context) { + var pageInfo = c.pageInfo.value; + return Column( + children: [ + Obx( + () => CupertinoListSection.insetGrouped( + additionalDividerMargin: 6, + header: const Text("基本信息"), + backgroundColor: CupertinoTheme.of(context).scaffoldBackgroundColor, + children: [ + buildPageInfo( + context, + "显示标题", + pageInfo?.mainTitle, + onTap: () async {}, + ), + buildPageInfo(context, "页面长度(字节)", pageInfo?.length), + buildPageInfo(context, "页面ID", pageInfo?.pageid), + buildPageInfo(context, "页面内容语言", pageInfo?.pagelanguage), + buildPageInfo(context, "页面内容类型", pageInfo?.contentmodel), + buildPageInfo(context, "收藏者数", pageInfo?.watchers), + buildPageInfo(context, "最后修改于", pageInfo?.updatedTime), + buildPageInfo(context, "该页面的子页面数", null), + buildPageInfo(context, "过去30天的页面访问量", null), + ], + ), + ), + ], + ); + } + + @override + Widget render(BuildContext context) { + return IsekaiPageScaffold( + navigationBar: const IsekaiNavigationBar( + middle: Text("页面信息"), + ), + child: SafeArea( + child: ListView( + children: [ + Obx(() => c.loadingPageInfo.value + ? buildLoading(context) + : buildPageInfoList(context)) + ], + ), + ), + ); + } +} diff --git a/lib/pages/article.dart b/lib/pages/wiki/view.dart similarity index 86% rename from lib/pages/article.dart rename to lib/pages/wiki/view.dart index 9a5b36e..eb72e1b 100755 --- a/lib/pages/article.dart +++ b/lib/pages/wiki/view.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter_share/flutter_share.dart'; import 'package:flutter_slider_drawer/flutter_slider_drawer.dart'; import 'package:get/get.dart'; import 'package:isekai_wiki/api/mw/list.dart'; @@ -13,6 +12,8 @@ import 'package:isekai_wiki/components/nav_bar_button.dart'; import 'package:isekai_wiki/components/safearea_builder.dart'; import 'package:isekai_wiki/components/toc.dart'; import 'package:isekai_wiki/components/wikipage_parser.dart'; +import 'package:isekai_wiki/components/isekai_nav_bar.dart'; +import 'package:isekai_wiki/components/isekai_page_scaffold.dart'; import 'package:isekai_wiki/global.dart'; import 'package:isekai_wiki/models/favorite_list.dart'; import 'package:isekai_wiki/reactive/reactive.dart'; @@ -21,16 +22,17 @@ import 'package:isekai_wiki/utils/error.dart'; import 'package:isekai_wiki/utils/utils.dart'; import 'package:share_plus/share_plus.dart'; -import '../components/isekai_nav_bar.dart'; -import '../components/isekai_page_scaffold.dart'; - class MinimumArticleData { final String title; final String? description; final String? mainCategory; final DateTime? updateTime; - MinimumArticleData({required this.title, this.description, this.mainCategory, this.updateTime}); + MinimumArticleData( + {required this.title, + this.description, + this.mainCategory, + this.updateTime}); } class ArticleCategoryData { @@ -40,7 +42,7 @@ class ArticleCategoryData { ArticleCategoryData({required this.name, required this.identity}); } -class ArticlePageController extends GetxController { +class WikiViewPageController extends GetxController { WikiPageParserController? parserController; var loading = true.obs; @@ -75,9 +77,11 @@ class ArticlePageController extends GetxController { loading.value = true; MWResponse> pageInfoRes; if (pageId.value != 0) { - pageInfoRes = await MWApiList.getPageInfoList(pageids: [pageId.value]); + pageInfoRes = + await MWApiList.getPageInfoList(pageids: [pageId.value]); } else { - pageInfoRes = await MWApiList.getPageInfoList(titles: [pageTitle.value]); + pageInfoRes = + await MWApiList.getPageInfoList(titles: [pageTitle.value]); } if (pageInfoRes.data.isEmpty) { throw MWApiErrorException(code: 'no-page', info: "页面信息丢失"); @@ -92,7 +96,8 @@ class ArticlePageController extends GetxController { var parseRes = await MWApiParse.parse(pageId: pageId.value); parseInfo.value = parseRes.data; } catch (err, stack) { - alert(Get.overlayContext!, ErrorUtils.getErrorMessage(err), title: "错误"); + alert(Get.overlayContext!, ErrorUtils.getErrorMessage(err), + title: "错误"); if (kDebugMode) { print("Exception in page: $err"); stack.printError(); @@ -109,12 +114,13 @@ class ArticlePageController extends GetxController { void handleShareButtonClick() { if (pageInfo.value != null) { - var pageUrl = pageInfo.value!.fullurl ?? getPageUrl(pageInfo.value!.title); + var pageUrl = + pageInfo.value!.fullurl ?? getPageUrl(pageInfo.value!.title); var shareTitle = "${pageInfo.value!.title} - ${Global.siteTitle}"; var shareText = "$shareTitle\n$pageUrl"; - FlutterShare.share( - title: shareTitle, text: shareTitle, linkUrl: pageUrl, chooserTitle: "分享到"); + + Share.share(shareText, subject: shareTitle); } else { alert(Get.overlayContext!, "页面还未加载完成"); } @@ -139,19 +145,20 @@ class ArticlePageController extends GetxController { } } -class ArticlePage extends StatefulWidget { +class WikiViewPage extends StatefulWidget { final MinimumArticleData? initialArticleData; final String? targetPage; final int? targetPageId; - const ArticlePage({super.key, this.targetPage, this.targetPageId, this.initialArticleData}); + const WikiViewPage( + {super.key, this.targetPage, this.targetPageId, this.initialArticleData}); @override - State createState() => _ArticlePageState(); + State createState() => _WikiViewPageState(); } -class _ArticlePageState extends ReactiveState { - var c = ArticlePageController(); +class _WikiViewPageState extends ReactiveState { + var c = WikiViewPageController(); @override void initState() { @@ -216,7 +223,8 @@ class _ArticlePageState extends ReactiveState { semanticLabel: "讨论", ), Obx(() { - if (c.pageInfo.value != null && flc.isFavorite(c.pageInfo.value!)) { + if (c.pageInfo.value != null && + flc.isFavorite(c.pageInfo.value!)) { return NavBarButton( icon: CupertinoIcons.heart_fill, onPressed: () {}, diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 66fffda..b889e46 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -2,5 +2,6 @@ import 'package:isekai_wiki/global.dart'; String getPageUrl(String title) { var titleEncoded = Uri.encodeFull(title.replaceAll(RegExp(r" "), "_")); - return Global.siteConfig.pageUrlTemplate.replaceAll(RegExp(r"\$1"), titleEncoded); + return Global.siteConfig.pageUrlTemplate + .replaceAll(RegExp(r"\$1"), titleEncoded); } diff --git a/macos/Podfile b/macos/Podfile index dade8df..049abe2 100755 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.14' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index c750713..a4e80c2 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -273,6 +273,7 @@ }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -404,7 +405,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -483,7 +484,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -530,7 +531,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/pubspec.lock b/pubspec.lock index c980772..d78e770 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,24 +5,24 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "3444216bfd127af50bbe4862d8843ed44db946dd933554f0d7285e89f10e28ac" - url: "https://pub.flutter-io.cn" + sha256: "0c80aeab9bc807ab10022cd3b2f4cf2ecdf231949dc1ddd9442406a003f19201" + url: "https://pub.dev" source: hosted - version: "50.0.0" + version: "52.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "68796c31f510c8455a06fed75fc97d8e5ad04d324a830322ab3efc9feb6201c1" - url: "https://pub.flutter-io.cn" + sha256: cd8ee83568a77f3ae6b913a36093a1c9b1264e7cb7f834d9ddd2311dade9c1f4 + url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.4.0" animated_snack_bar: dependency: "direct main" description: name: animated_snack_bar sha256: "12459c60530f6652e93adfafa24b0ff8d8dc44ad7be01103cb4370f3776435d5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.3.0" animations: @@ -30,7 +30,7 @@ packages: description: name: animations sha256: fe8a6bdca435f718bb1dc8a11661b2c22504c6da40ef934cee8327ed77934164 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.7" args: @@ -38,7 +38,7 @@ packages: description: name: args sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.2" async: @@ -46,7 +46,7 @@ packages: description: name: async sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.10.0" boolean_selector: @@ -54,7 +54,7 @@ packages: description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" build: @@ -62,7 +62,7 @@ packages: description: name: build sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.1" build_config: @@ -70,7 +70,7 @@ packages: description: name: build_config sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" build_daemon: @@ -78,7 +78,7 @@ packages: description: name: build_daemon sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.0" build_resolvers: @@ -86,7 +86,7 @@ packages: description: name: build_resolvers sha256: "7c35a3a7868626257d8aee47b51c26b9dba11eaddf3431117ed2744951416aab" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.0" build_runner: @@ -94,7 +94,7 @@ packages: description: name: build_runner sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.3" build_runner_core: @@ -102,7 +102,7 @@ packages: description: name: build_runner_core sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.2.7" built_collection: @@ -110,7 +110,7 @@ packages: description: name: built_collection sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.1.1" built_value: @@ -118,7 +118,7 @@ packages: description: name: built_value sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.4.3" cached_network_image: @@ -126,7 +126,7 @@ packages: description: name: cached_network_image sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.3" cached_network_image_platform_interface: @@ -134,7 +134,7 @@ packages: description: name: cached_network_image_platform_interface sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" cached_network_image_web: @@ -142,7 +142,7 @@ packages: description: name: cached_network_image_web sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" characters: @@ -150,7 +150,7 @@ packages: description: name: characters sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.1" checked_yaml: @@ -158,7 +158,7 @@ packages: description: name: checked_yaml sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.2" chewie: @@ -166,7 +166,7 @@ packages: description: name: chewie sha256: e9da4898ee4859825404f507969f57113c04ca0060e152b95c9afd73934126ad - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.0" chewie_audio: @@ -174,7 +174,7 @@ packages: description: name: chewie_audio sha256: f92bb4364ced21318e1a7c0eddaf249a7554e5cf27f869d58c44d926abd292a7 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.0" clock: @@ -182,7 +182,7 @@ packages: description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" code_builder: @@ -190,7 +190,7 @@ packages: description: name: code_builder sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.4.0" collection: @@ -198,7 +198,7 @@ packages: description: name: collection sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.17.0" convert: @@ -206,7 +206,7 @@ packages: description: name: convert sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.1" cookie_jar: @@ -214,7 +214,7 @@ packages: description: name: cookie_jar sha256: d1cc6516a190ba667941f722b6365d202caff3dacb38de24268b8d6ff1ec8a1d - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.1" cross_file: @@ -222,7 +222,7 @@ packages: description: name: cross_file sha256: f71079978789bc2fe78d79227f1f8cfe195b31bbd8db2399b0d15a4b96fb843b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.3.3+2" crypto: @@ -230,7 +230,7 @@ packages: description: name: crypto sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.2" csslib: @@ -238,7 +238,7 @@ packages: description: name: csslib sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.17.2" cupertino_icons: @@ -246,7 +246,7 @@ packages: description: name: cupertino_icons sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.5" cupertino_lists: @@ -254,7 +254,7 @@ packages: description: name: cupertino_lists sha256: "3f31cce75a36bb9bb6a6687f8842bfa1cfa6aaaa1f4c23482485732650d2b602" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.1" dart_style: @@ -262,7 +262,7 @@ packages: description: name: dart_style sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.4" dio: @@ -270,7 +270,7 @@ packages: description: name: dio sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.6" dio_cache_interceptor: @@ -278,7 +278,7 @@ packages: description: name: dio_cache_interceptor sha256: "3f76df600621f3a8ed9c57db053f602b24c7e64c108fbc2791d0fe779c52b45b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.3.1" dio_cookie_manager: @@ -286,7 +286,7 @@ packages: description: name: dio_cookie_manager sha256: ed7ee3ba6cdb54599c8984d5a4ce09675c553ead6c28608eb54e38eec5b4f954 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" dio_http2_adapter: @@ -294,7 +294,7 @@ packages: description: name: dio_http2_adapter sha256: f4ce5e29aaf24c6c1b99b2135c8f4f03c3e2f1b7b535bbfdc859f0c5a74a8298 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" fake_async: @@ -302,7 +302,7 @@ packages: description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.1" ffi: @@ -310,7 +310,7 @@ packages: description: name: ffi sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" file: @@ -318,7 +318,7 @@ packages: description: name: file sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.1.4" fixnum: @@ -326,7 +326,7 @@ packages: description: name: fixnum sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.1" flutter: @@ -339,7 +339,7 @@ packages: description: name: flutter_blurhash sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.7.0" flutter_cache_manager: @@ -347,7 +347,7 @@ packages: description: name: flutter_cache_manager sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.3.0" flutter_displaymode: @@ -355,7 +355,7 @@ packages: description: name: flutter_displaymode sha256: "042f4910ccc5620c58bb598dead6f868261268cf73a22fa93c9f0c57c3c0e666" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.3.2" flutter_html: @@ -363,7 +363,7 @@ packages: description: name: flutter_html sha256: ccb810fcabfce3a7ffaca46e458323915ac7e7fc59082c7357ff848972c02230 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.1" flutter_inappwebview: @@ -371,7 +371,7 @@ packages: description: name: flutter_inappwebview sha256: f73505c792cf083d5566e1a94002311be497d984b5607f25be36d685cf6361cf - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.7.2+3" flutter_layout_grid: @@ -379,7 +379,7 @@ packages: description: name: flutter_layout_grid sha256: "86c1b21520612edfbb93f189b3ec05058470570f3a5c08ce10c92cc76a6e814e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.6" flutter_lints: @@ -387,7 +387,7 @@ packages: description: name: flutter_lints sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" flutter_localizations: @@ -400,7 +400,7 @@ packages: description: name: flutter_math_fork sha256: a34205227e1a1d040a56e74a5e2e56e9397ea930540a9373bd0b3e2e4f122017 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.5.0" flutter_share: @@ -408,7 +408,7 @@ packages: description: name: flutter_share sha256: ae12c1cea13b35926a109824ffac601531e40cb94ad53eeae58625eceb3eaaaa - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" flutter_slider_drawer: @@ -423,7 +423,7 @@ packages: description: name: flutter_svg sha256: cbf529d563dd910a249041bde2a0dfc3cf62280fcc459b85f3d614b2ab73abb3 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.23.0+1" flutter_test: @@ -436,7 +436,7 @@ packages: description: name: flutter_web_browser sha256: a5564b736253f745e147b8c4eff86de436324d081974cc1f16bff881134a400f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.17.1" flutter_web_plugins: @@ -449,7 +449,7 @@ packages: description: name: fluttertoast sha256: "7cc92eabe01e3f1babe1571c5560b135dfc762a34e41e9056881e2196b178ec1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.1.2" freezed: @@ -457,7 +457,7 @@ packages: description: name: freezed sha256: e819441678f1679b719008ff2ff0ef045d66eed9f9ec81166ca0d9b02a187454 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.2" freezed_annotation: @@ -465,7 +465,7 @@ packages: description: name: freezed_annotation sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" frontend_server_client: @@ -473,7 +473,7 @@ packages: description: name: frontend_server_client sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.0" get: @@ -481,7 +481,7 @@ packages: description: name: get sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.6.5" get_storage: @@ -489,7 +489,7 @@ packages: description: name: get_storage sha256: "00b3908d9cd4138738b4db69bcc0fc1cf4ee8570c06594136569470f32a84207" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.3" glob: @@ -497,7 +497,7 @@ packages: description: name: glob sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" graphs: @@ -505,7 +505,7 @@ packages: description: name: graphs sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" html: @@ -513,7 +513,7 @@ packages: description: name: html sha256: d9793e10dbe0e6c364f4c59bf3e01fb33a9b2a674bc7a1081693dba0614b6269 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.15.1" http: @@ -521,7 +521,7 @@ packages: description: name: http sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.13.5" http2: @@ -529,7 +529,7 @@ packages: description: name: http2 sha256: "58805ebc6513eed3b98ee0a455a8357e61d187bf2e0fdc1e53120770f78de258" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" http_multi_server: @@ -537,7 +537,7 @@ packages: description: name: http_multi_server sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.1" http_parser: @@ -545,7 +545,7 @@ packages: description: name: http_parser sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.2" intl: @@ -553,7 +553,7 @@ packages: description: name: intl sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.17.0" io: @@ -561,7 +561,7 @@ packages: description: name: io sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.4" js: @@ -569,7 +569,7 @@ packages: description: name: js sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.6.5" json_annotation: @@ -577,7 +577,7 @@ packages: description: name: json_annotation sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.8.0" json_serializable: @@ -585,7 +585,7 @@ packages: description: name: json_serializable sha256: "040088d9eb2337f3a51ddabe35261e2fea1c351e3dd29d755ed1290b6b700a75" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.6.0" like_button: @@ -593,7 +593,7 @@ packages: description: name: like_button sha256: "08e6a45b78888412df5d351786c550205ad3a677e72a0820d5bbc0b063c8a463" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.5" lints: @@ -601,7 +601,7 @@ packages: description: name: lints sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" logging: @@ -609,7 +609,7 @@ packages: description: name: logging sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" matcher: @@ -617,7 +617,7 @@ packages: description: name: matcher sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.12.13" material_color_utilities: @@ -625,7 +625,7 @@ packages: description: name: material_color_utilities sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.0" meta: @@ -633,7 +633,7 @@ packages: description: name: meta sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.8.0" mime: @@ -641,7 +641,7 @@ packages: description: name: mime sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.4" modal_bottom_sheet: @@ -649,7 +649,7 @@ packages: description: name: modal_bottom_sheet sha256: ef533916a2c3089571c32bd34e410faca77a6849a3f28f748e0794525c5658a0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.2" nested: @@ -657,7 +657,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.0" numerus: @@ -665,7 +665,7 @@ packages: description: name: numerus sha256: "0087ef729d63b96cb347a9c44b9c592f21cecb3605b415bbd18710aef80ce5cb" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" octo_image: @@ -673,7 +673,7 @@ packages: description: name: octo_image sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" package_config: @@ -681,7 +681,7 @@ packages: description: name: package_config sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.0" package_info_plus: @@ -689,7 +689,7 @@ packages: description: name: package_info_plus sha256: f619162573096d428ccde2e33f92e05b5a179cd6f0e3120c1005f181bee8ed16 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.2" package_info_plus_platform_interface: @@ -697,7 +697,7 @@ packages: description: name: package_info_plus_platform_interface sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" path: @@ -705,7 +705,7 @@ packages: description: name: path sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.8.2" path_drawing: @@ -713,7 +713,7 @@ packages: description: name: path_drawing sha256: "3bdd251dae9ffaef944450b73f168610db7e968e7b20daf0c3907f8b4aafc8a2" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.5.1+1" path_parsing: @@ -721,7 +721,7 @@ packages: description: name: path_parsing sha256: ee5c47c1058ad66b4a41746ec3996af9593d0858872807bcd64ac118f0700337 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.1" path_provider: @@ -729,7 +729,7 @@ packages: description: name: path_provider sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.12" path_provider_android: @@ -737,7 +737,7 @@ packages: description: name: path_provider_android sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.22" path_provider_foundation: @@ -745,7 +745,7 @@ packages: description: name: path_provider_foundation sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" path_provider_linux: @@ -753,7 +753,7 @@ packages: description: name: path_provider_linux sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.7" path_provider_platform_interface: @@ -761,7 +761,7 @@ packages: description: name: path_provider_platform_interface sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.5" path_provider_windows: @@ -769,7 +769,7 @@ packages: description: name: path_provider_windows sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.3" pedantic: @@ -777,7 +777,7 @@ packages: description: name: pedantic sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.11.1" petitparser: @@ -785,7 +785,7 @@ packages: description: name: petitparser sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.1.0" platform: @@ -793,7 +793,7 @@ packages: description: name: platform sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.0" plugin_platform_interface: @@ -801,7 +801,7 @@ packages: description: name: plugin_platform_interface sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.3" pool: @@ -809,7 +809,7 @@ packages: description: name: pool sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.5.1" process: @@ -817,7 +817,7 @@ packages: description: name: process sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.2.4" provider: @@ -825,7 +825,7 @@ packages: description: name: provider sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.0.5" pub_semver: @@ -833,7 +833,7 @@ packages: description: name: pub_semver sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.3" pubspec_parse: @@ -841,7 +841,7 @@ packages: description: name: pubspec_parse sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.1" pull_down_button: @@ -849,7 +849,7 @@ packages: description: name: pull_down_button sha256: "31cb3c3c13d7af7b386cfc7a3957c5bda97efa4aa35fedfd42bb838d60530fd4" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.1" quiver: @@ -857,7 +857,7 @@ packages: description: name: quiver sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.1" responsive_builder: @@ -865,7 +865,7 @@ packages: description: name: responsive_builder sha256: f01bc341c73b6db7bd6319e22d2c160f28f924399ae46e6699ecc8160ba2765c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.3" roundcheckbox: @@ -873,7 +873,7 @@ packages: description: name: roundcheckbox sha256: "5d6f607ed9d26fde0072af2545f56d84a6b6d2a45972b0c41f90c2d73224f339" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.5" rxdart: @@ -881,7 +881,7 @@ packages: description: name: rxdart sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.27.7" scroll_bars_common: @@ -889,7 +889,7 @@ packages: description: name: scroll_bars_common sha256: "9a46b430ca602b4fb6c15c6f021d85fd00e561b0b698f11cb13c9e032ee9d93e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" scroll_bottom_navigation_bar: @@ -897,7 +897,7 @@ packages: description: name: scroll_bottom_navigation_bar sha256: "916c3889c349044a03339020dcaf7ca6d9c14662e84f030f4c57b37df498aca9" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.0" share_plus: @@ -905,7 +905,7 @@ packages: description: name: share_plus sha256: e387077716f80609bb979cd199331033326033ecd1c8f200a90c5f57b1c9f55e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.3.0" share_plus_platform_interface: @@ -913,7 +913,7 @@ packages: description: name: share_plus_platform_interface sha256: "82ddd4ab9260c295e6e39612d4ff00390b9a7a21f1bb1da771e2f232d80ab8a1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.0" shelf: @@ -921,7 +921,7 @@ packages: description: name: shelf sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.0" shelf_web_socket: @@ -929,7 +929,7 @@ packages: description: name: shelf_web_socket sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.3" skeletons: @@ -937,7 +937,7 @@ packages: description: name: skeletons sha256: "5b2d08ae7f908ee1f7007ca99f8dcebb4bfc1d3cb2143dec8d112a5be5a45c8f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.0.3" sky_engine: @@ -950,7 +950,7 @@ packages: description: name: source_gen sha256: "2d79738b6bbf38a43920e2b8d189e9a3ce6cc201f4b8fc76be5e4fe377b1c38d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.6" source_helper: @@ -958,7 +958,7 @@ packages: description: name: source_helper sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.3" source_span: @@ -966,7 +966,7 @@ packages: description: name: source_span sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.9.1" sqflite: @@ -974,7 +974,7 @@ packages: description: name: sqflite sha256: "78324387dc81df14f78df06019175a86a2ee0437624166c382e145d0a7fd9a4f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.4+1" sqflite_common: @@ -982,7 +982,7 @@ packages: description: name: sqflite_common sha256: bfd6973aaeeb93475bc0d875ac9aefddf7965ef22ce09790eb963992ffc5183f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.2+2" stack_trace: @@ -990,7 +990,7 @@ packages: description: name: stack_trace sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.11.0" stream_channel: @@ -998,7 +998,7 @@ packages: description: name: stream_channel sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" stream_transform: @@ -1006,7 +1006,7 @@ packages: description: name: stream_transform sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.0" string_scanner: @@ -1014,7 +1014,7 @@ packages: description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.0" synchronized: @@ -1022,7 +1022,7 @@ packages: description: name: synchronized sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.1" term_glyph: @@ -1030,7 +1030,7 @@ packages: description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: @@ -1038,7 +1038,7 @@ packages: description: name: test_api sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.16" timing: @@ -1046,7 +1046,7 @@ packages: description: name: timing sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.1" tuple: @@ -1054,7 +1054,7 @@ packages: description: name: tuple sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" typed_data: @@ -1062,7 +1062,7 @@ packages: description: name: typed_data sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.1" url_launcher: @@ -1070,7 +1070,7 @@ packages: description: name: url_launcher sha256: "698fa0b4392effdc73e9e184403b627362eb5fbf904483ac9defbb1c2191d809" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.1.8" url_launcher_android: @@ -1078,7 +1078,7 @@ packages: description: name: url_launcher_android sha256: "3e2f6dfd2c7d9cd123296cab8ef66cfc2c1a13f5845f42c7a0f365690a8a7dd1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.0.23" url_launcher_ios: @@ -1086,7 +1086,7 @@ packages: description: name: url_launcher_ios sha256: bb328b24d3bccc20bdf1024a0990ac4f869d57663660de9c936fb8c043edefe3 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.0.18" url_launcher_linux: @@ -1094,7 +1094,7 @@ packages: description: name: url_launcher_linux sha256: "318c42cba924e18180c029be69caf0a1a710191b9ec49bb42b5998fdcccee3cc" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.2" url_launcher_macos: @@ -1102,7 +1102,7 @@ packages: description: name: url_launcher_macos sha256: "41988b55570df53b3dd2a7fc90c76756a963de6a8c5f8e113330cb35992e2094" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.2" url_launcher_platform_interface: @@ -1110,7 +1110,7 @@ packages: description: name: url_launcher_platform_interface sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" url_launcher_web: @@ -1118,7 +1118,7 @@ packages: description: name: url_launcher_web sha256: "44d79408ce9f07052095ef1f9a693c258d6373dc3944249374e30eff7219ccb0" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.14" url_launcher_windows: @@ -1126,7 +1126,7 @@ packages: description: name: url_launcher_windows sha256: b6217370f8eb1fd85c8890c539f5a639a01ab209a36db82c921ebeacefc7a615 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.3" uuid: @@ -1134,7 +1134,7 @@ packages: description: name: uuid sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.7" vector_math: @@ -1142,7 +1142,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.4" video_player: @@ -1150,7 +1150,7 @@ packages: description: name: video_player sha256: "59f7f31c919c59cbedd37c617317045f5f650dc0eeb568b0b0de9a36472bdb28" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.5.1" video_player_android: @@ -1158,7 +1158,7 @@ packages: description: name: video_player_android sha256: "984388511230bac63feb53b2911a70e829fe0976b6b2213f5c579c4e0a882db3" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.10" video_player_avfoundation: @@ -1166,7 +1166,7 @@ packages: description: name: video_player_avfoundation sha256: d9f7a46d6a77680adb03ec05a381025d6e890ebe636637c6c3014cc3926b97e9 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.8" video_player_platform_interface: @@ -1174,7 +1174,7 @@ packages: description: name: video_player_platform_interface sha256: "42bb75de5e9b79e1f20f1d95f688fac0f95beac4d89c6eb2cd421724d4432dae" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.0.1" video_player_web: @@ -1182,7 +1182,7 @@ packages: description: name: video_player_web sha256: b649b07b8f8f553bee4a97a0a53d0fe78a70b115eafaf0105b612b32b05ddb99 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.13" wakelock: @@ -1190,7 +1190,7 @@ packages: description: name: wakelock sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.6.2" wakelock_macos: @@ -1198,7 +1198,7 @@ packages: description: name: wakelock_macos sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.0" wakelock_platform_interface: @@ -1206,7 +1206,7 @@ packages: description: name: wakelock_platform_interface sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.3.0" wakelock_web: @@ -1214,7 +1214,7 @@ packages: description: name: wakelock_web sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.0" wakelock_windows: @@ -1222,7 +1222,7 @@ packages: description: name: wakelock_windows sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.1" watcher: @@ -1230,7 +1230,7 @@ packages: description: name: watcher sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" web_smooth_scroll: @@ -1238,7 +1238,7 @@ packages: description: name: web_smooth_scroll sha256: "2a4adc22e42e4045f02ecc1598885bf46adbe7ed9b05aab0a0f5df9ed071e9b6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.0" web_socket_channel: @@ -1246,7 +1246,7 @@ packages: description: name: web_socket_channel sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.0" webview_flutter: @@ -1254,7 +1254,7 @@ packages: description: name: webview_flutter sha256: "6886b3ceef1541109df5001054aade5ee3c36b5780302e41701c78357233721c" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.8.0" webview_flutter_android: @@ -1262,7 +1262,7 @@ packages: description: name: webview_flutter_android sha256: "8b3b2450e98876c70bfcead876d9390573b34b9418c19e28168b74f6cb252dbd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.10.4" webview_flutter_platform_interface: @@ -1270,7 +1270,7 @@ packages: description: name: webview_flutter_platform_interface sha256: "812165e4e34ca677bdfbfa58c01e33b27fd03ab5fa75b70832d4b7d4ca1fa8cf" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.9.5" webview_flutter_wkwebview: @@ -1278,7 +1278,7 @@ packages: description: name: webview_flutter_wkwebview sha256: a5364369c758892aa487cbf59ea41d9edd10f9d9baf06a94e80f1bd1b4c7bbc0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.9.5" win32: @@ -1286,7 +1286,7 @@ packages: description: name: win32 sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.3" xdg_directories: @@ -1294,7 +1294,7 @@ packages: description: name: xdg_directories sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.0+3" xml: @@ -1302,7 +1302,7 @@ packages: description: name: xml sha256: "80d494c09849dc3f899d227a78c30c5b949b985ededf884cb3f3bcd39f4b447a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.4.1" yaml: @@ -1310,7 +1310,7 @@ packages: description: name: yaml sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.1" sdks: