diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3bbbb5b5..91c45a8f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -60,5 +60,11 @@ + + diff --git a/lib/page/my_page.dart b/lib/page/my_page.dart index 664a9a9a..f2757b67 100644 --- a/lib/page/my_page.dart +++ b/lib/page/my_page.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:gsy_github_app_flutter/common/repositories/event_repository.dart'; import 'package:gsy_github_app_flutter/common/repositories/user_repository.dart'; import 'package:gsy_github_app_flutter/page/user/base_person_provider.dart'; -import 'package:gsy_github_app_flutter/provider/app_state_provider.dart'; import 'package:gsy_github_app_flutter/redux/gsy_state.dart'; import 'package:gsy_github_app_flutter/redux/user_redux.dart'; import 'package:gsy_github_app_flutter/common/style/gsy_style.dart'; @@ -118,7 +116,7 @@ class MyPageState extends BasePersonState { getUserOrg(_getUserName()); ///获取用户仓库前100个star统计数据 - getHonor(globalContainer, _getUserName()); + getHonor(); _refreshNotify(); } return await _getDataLogic(); @@ -135,6 +133,11 @@ class MyPageState extends BasePersonState { @override bool get needHeader => false; + @override + FetchHonorDataProvider get headerProvider { + return fetchHonorDataProvider(_getUserName()); + } + @override void didChangeDependencies() { if (pullLoadWidgetControl.dataList.isEmpty) { @@ -146,35 +149,26 @@ class MyPageState extends BasePersonState { @override Widget build(BuildContext context) { super.build(context); // See AutomaticKeepAliveClientMixin. - return Consumer( - builder: (BuildContext context, WidgetRef ref, Widget? child) { - var result = ref.watch(fetchHonorDataProvider(_getUserName())); - return StoreBuilder( - builder: (context, store) { - return GSYNestedPullLoadWidget( - pullLoadWidgetControl, - (BuildContext context, int index) => renderItem( - index, store.state.userInfo!, beStaredCount, notifyColor, () { + return StoreBuilder( + builder: (context, store) { + return GSYNestedPullLoadWidget( + pullLoadWidgetControl, + (BuildContext context, int index) => renderItem( + index, store.state.userInfo!, beStaredCount, notifyColor, () { + _refreshNotify(); + }, orgList), + handleRefresh, + onLoadMore, + scrollController: scrollController, + refreshKey: refreshIKey, + headerSliverBuilder: (context, innerBoxIsScrolled) { + return sliverBuilder(context, innerBoxIsScrolled, + store.state.userInfo!, notifyColor, beStaredCount, () { _refreshNotify(); - }, orgList), - handleRefresh, - onLoadMore, - scrollController: scrollController, - refreshKey: refreshIKey, - headerSliverBuilder: (context, innerBoxIsScrolled) { - return sliverBuilder( - context, - innerBoxIsScrolled, - store.state.userInfo!, - notifyColor, - beStaredCount, - result.value, () { - _refreshNotify(); - }); - }, - ); - }, - ); - }); + }); + }, + ); + }, + ); } } diff --git a/lib/page/trend/trend_user_page.dart b/lib/page/trend/trend_user_page.dart index 58caf985..ef45fbe4 100644 --- a/lib/page/trend/trend_user_page.dart +++ b/lib/page/trend/trend_user_page.dart @@ -24,17 +24,12 @@ class _TrendUserPageState extends ConsumerState { } Future loadData(WidgetRef ref, {bool isRefresh = false}) async { + /// getTrendUserProvider 这里只有一处地方使用,所以不需要做局部单实例共享 final result = await ref.read( - searchTrendUserRequestProvider("China", cursor: endCursor).future); + searchTrendUserRequestProvider("China", isRefresh, cursor: endCursor) + .future); if (result != null) { var (dataList, cursor) = result; - var trendRef = ref.read(trendCNUserListProvider.notifier); - if (isRefresh) { - trendRef.setList(dataList); - } else { - trendRef.addList(dataList); - } - var _ = ref.refresh(trendCNUserListProvider.notifier); endCursor = cursor; } } diff --git a/lib/page/trend/trend_user_provider.dart b/lib/page/trend/trend_user_provider.dart index d7cb1a9c..027675da 100644 --- a/lib/page/trend/trend_user_provider.dart +++ b/lib/page/trend/trend_user_provider.dart @@ -34,9 +34,20 @@ class TrendCNUserList extends _$TrendCNUserList { @riverpod Future<(List, String)?> searchTrendUserRequest( - Ref ref, String location, + Ref ref, String location, bool isRefresh, {String? cursor}) async { var result = await UserRepository.searchTrendUserRequest("China", cursor: cursor); - return result.data; + if (result.data != null) { + var value = result.data; + var trendRef = ref.read(trendCNUserListProvider.notifier); + if (isRefresh) { + trendRef.setList(value.$1); + } else { + trendRef.addList(value.$1); + } + var _ = ref.refresh(trendCNUserListProvider.notifier); + return result.value; + } + return null; } diff --git a/lib/page/trend/trend_user_provider.g.dart b/lib/page/trend/trend_user_provider.g.dart index 63aaec7c..f69da1b7 100644 --- a/lib/page/trend/trend_user_provider.g.dart +++ b/lib/page/trend/trend_user_provider.g.dart @@ -7,7 +7,7 @@ part of 'trend_user_provider.dart'; // ************************************************************************** String _$searchTrendUserRequestHash() => - r'b018ed2759bb7a323022bcd74a75d5be7f5f7e8a'; + r'75fbb074b1095d1600afc4dcc97e6a68454ea95b'; /// Copied from Dart SDK class _SystemHash { @@ -42,11 +42,13 @@ class SearchTrendUserRequestFamily /// See also [searchTrendUserRequest]. SearchTrendUserRequestProvider call( - String location, { + String location, + bool isRefresh, { String? cursor, }) { return SearchTrendUserRequestProvider( location, + isRefresh, cursor: cursor, ); } @@ -57,6 +59,7 @@ class SearchTrendUserRequestFamily ) { return call( provider.location, + provider.isRefresh, cursor: provider.cursor, ); } @@ -81,12 +84,14 @@ class SearchTrendUserRequestProvider extends AutoDisposeFutureProvider<(List, String)?> { /// See also [searchTrendUserRequest]. SearchTrendUserRequestProvider( - String location, { + String location, + bool isRefresh, { String? cursor, }) : this._internal( (ref) => searchTrendUserRequest( ref as SearchTrendUserRequestRef, location, + isRefresh, cursor: cursor, ), from: searchTrendUserRequestProvider, @@ -99,6 +104,7 @@ class SearchTrendUserRequestProvider allTransitiveDependencies: SearchTrendUserRequestFamily._allTransitiveDependencies, location: location, + isRefresh: isRefresh, cursor: cursor, ); @@ -110,10 +116,12 @@ class SearchTrendUserRequestProvider required super.debugGetCreateSourceHash, required super.from, required this.location, + required this.isRefresh, required this.cursor, }) : super.internal(); final String location; + final bool isRefresh; final String? cursor; @override @@ -132,6 +140,7 @@ class SearchTrendUserRequestProvider allTransitiveDependencies: null, debugGetCreateSourceHash: null, location: location, + isRefresh: isRefresh, cursor: cursor, ), ); @@ -147,6 +156,7 @@ class SearchTrendUserRequestProvider bool operator ==(Object other) { return other is SearchTrendUserRequestProvider && other.location == location && + other.isRefresh == isRefresh && other.cursor == cursor; } @@ -154,6 +164,7 @@ class SearchTrendUserRequestProvider int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); hash = _SystemHash.combine(hash, location.hashCode); + hash = _SystemHash.combine(hash, isRefresh.hashCode); hash = _SystemHash.combine(hash, cursor.hashCode); return _SystemHash.finish(hash); @@ -167,6 +178,9 @@ mixin SearchTrendUserRequestRef /// The parameter `location` of this provider. String get location; + /// The parameter `isRefresh` of this provider. + bool get isRefresh; + /// The parameter `cursor` of this provider. String? get cursor; } @@ -179,6 +193,8 @@ class _SearchTrendUserRequestProviderElement @override String get location => (origin as SearchTrendUserRequestProvider).location; @override + bool get isRefresh => (origin as SearchTrendUserRequestProvider).isRefresh; + @override String? get cursor => (origin as SearchTrendUserRequestProvider).cursor; } diff --git a/lib/page/user/base_person_state.dart b/lib/page/user/base_person_state.dart index fe7e83b1..a04a6609 100644 --- a/lib/page/user/base_person_state.dart +++ b/lib/page/user/base_person_state.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:gsy_github_app_flutter/common/repositories/user_repository.dart'; import 'package:gsy_github_app_flutter/model/Event.dart'; import 'package:gsy_github_app_flutter/model/User.dart'; @@ -10,7 +9,9 @@ import 'package:gsy_github_app_flutter/model/UserOrg.dart'; import 'package:gsy_github_app_flutter/common/utils/event_utils.dart'; import 'package:gsy_github_app_flutter/common/utils/navigator_utils.dart'; import 'package:gsy_github_app_flutter/page/user/base_person_provider.dart'; +import 'package:gsy_github_app_flutter/provider/app_state_provider.dart'; import 'package:gsy_github_app_flutter/widget/gsy_event_item.dart'; +import 'package:gsy_github_app_flutter/widget/only_share_widget.dart'; import 'package:gsy_github_app_flutter/widget/pull/nested/gsy_sliver_header_delegate.dart'; import 'package:gsy_github_app_flutter/widget/pull/nested/nested_refresh.dart'; import 'package:gsy_github_app_flutter/widget/state/gsy_list_state.dart'; @@ -67,6 +68,9 @@ abstract class BasePersonState extends State @override bool get needHeader => true; + @protected + FetchHonorDataProvider get headerProvider; + @protected getUserOrg(String? userName) { if (page <= 1 && userName != null) { @@ -98,7 +102,6 @@ abstract class BasePersonState extends State User userInfo, Color? notifyColor, String beStaredCount, - HonorModel? honorModel, refreshCallBack) { double headerSize = 210; double bottomSize = 70; @@ -152,10 +155,9 @@ abstract class BasePersonState extends State return SizedBox.expand( child: Padding( padding: const EdgeInsets.only(bottom: 10, left: 0, right: 0), - child: UserHeaderBottom( - userInfo, - honorModel, - radius, + child: OnlyShareInstanceWidget( + value: headerProvider, + child: UserHeaderBottom(userInfo, radius), ), ), ); @@ -187,8 +189,7 @@ abstract class BasePersonState extends State } ///获取用户仓库前100个star统计数据 - getHonor(ProviderContainer ref, String name) async { - var _ = ref.refresh(fetchHonorDataProvider(name)); - await ref.read(fetchHonorDataProvider(name).future); + getHonor() async { + var _ = globalContainer.refresh(headerProvider); } } diff --git a/lib/page/user/person_page.dart b/lib/page/user/person_page.dart index 076b4432..f4481d06 100644 --- a/lib/page/user/person_page.dart +++ b/lib/page/user/person_page.dart @@ -4,7 +4,6 @@ import 'dart:async'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:gsy_github_app_flutter/common/repositories/event_repository.dart'; import 'package:gsy_github_app_flutter/common/repositories/user_repository.dart'; @@ -13,7 +12,6 @@ import 'package:gsy_github_app_flutter/model/User.dart'; import 'package:gsy_github_app_flutter/model/UserOrg.dart'; import 'package:gsy_github_app_flutter/common/utils/common_utils.dart'; import 'package:gsy_github_app_flutter/page/user/base_person_provider.dart'; -import 'package:gsy_github_app_flutter/provider/app_state_provider.dart'; import 'package:gsy_github_app_flutter/widget/pull/nested/gsy_nested_pull_load_widget.dart'; import 'package:gsy_github_app_flutter/page/user/base_person_state.dart'; import 'package:gsy_github_app_flutter/widget/gsy_common_option_widget.dart'; @@ -93,7 +91,7 @@ class PersonState extends BasePersonState { _getFocusStatus(); ///获取用户仓库前100个star统计数据 - getHonor(globalContainer, _getUserName()); + getHonor(); return; } @@ -148,55 +146,53 @@ class PersonState extends BasePersonState { @override Widget build(BuildContext context) { super.build(context); - return Consumer( - builder: (BuildContext context, WidgetRef ref, Widget? child) { - var result = ref.watch(fetchHonorDataProvider(_getUserName())); - return Scaffold( - appBar: AppBar( - title: GSYTitleBar( - (userInfo != null && userInfo!.login != null) - ? userInfo!.login - : "", - rightWidget: GSYCommonOptionWidget( - url: userInfo?.html_url, + return Scaffold( + appBar: AppBar( + title: GSYTitleBar( + (userInfo != null && userInfo!.login != null) ? userInfo!.login : "", + rightWidget: GSYCommonOptionWidget( + url: userInfo?.html_url, + ), + )), + floatingActionButton: FloatingActionButton( + child: AutoSizeText( + focus, + minFontSize: 8, + maxLines: 1, ), - )), - floatingActionButton: FloatingActionButton( - child: AutoSizeText( - focus, - minFontSize: 8, - maxLines: 1, - ), - onPressed: () { - ///非组织成员可以关注 - if (focus == '') { - return; - } - if (userInfo!.type == "Organization") { - Fluttertoast.showToast( - msg: GSYLocalizations.i18n(context)! - .user_focus_no_support); - return; - } - CommonUtils.showLoadingDialog(context); - UserRepository.doFollowRequest(widget.userName, focusStatus) - .then((res) { - Navigator.pop(context); - _getFocusStatus(); - }); - }), - body: GSYNestedPullLoadWidget( - pullLoadWidgetControl, - (BuildContext context, int index) => renderItem( - index, userInfo!, beStaredCount, null, null, orgList), - handleRefresh, - onLoadMore, - refreshKey: refreshIKey, - headerSliverBuilder: (context, innerBoxIsScrolled) { - return sliverBuilder(context, innerBoxIsScrolled, userInfo!, null, - beStaredCount, result.value, null); - }, - )); - }); + onPressed: () { + ///非组织成员可以关注 + if (focus == '') { + return; + } + if (userInfo!.type == "Organization") { + Fluttertoast.showToast( + msg: GSYLocalizations.i18n(context)!.user_focus_no_support); + return; + } + CommonUtils.showLoadingDialog(context); + UserRepository.doFollowRequest(widget.userName, focusStatus) + .then((res) { + Navigator.pop(context); + _getFocusStatus(); + }); + }), + body: GSYNestedPullLoadWidget( + pullLoadWidgetControl, + (BuildContext context, int index) => + renderItem(index, userInfo!, beStaredCount, null, null, orgList), + handleRefresh, + onLoadMore, + refreshKey: refreshIKey, + headerSliverBuilder: (context, innerBoxIsScrolled) { + return sliverBuilder(context, innerBoxIsScrolled, userInfo!, null, + beStaredCount, null); + }, + )); + } + + @override + FetchHonorDataProvider get headerProvider { + return fetchHonorDataProvider(_getUserName()); } } diff --git a/lib/page/user/widget/user_header.dart b/lib/page/user/widget/user_header.dart index 7fc1827d..83912190 100644 --- a/lib/page/user/widget/user_header.dart +++ b/lib/page/user/widget/user_header.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gsy_github_app_flutter/common/localization/default_localizations.dart'; @@ -12,10 +13,13 @@ import 'package:gsy_github_app_flutter/page/user/base_person_provider.dart'; import 'package:gsy_github_app_flutter/widget/gsy_card_item.dart'; import 'package:gsy_github_app_flutter/widget/gsy_icon_text.dart'; import 'package:gsy_github_app_flutter/widget/gsy_user_icon_widget.dart'; +import 'package:gsy_github_app_flutter/widget/only_share_widget.dart'; /// 用户详情头部 /// Created by guoshuyu /// Date: 2018-07-17 +/// +/// class UserHeaderItem extends StatelessWidget { final User userInfo; @@ -256,10 +260,8 @@ class UserHeaderItem extends StatelessWidget { class UserHeaderBottom extends StatelessWidget { final User userInfo; final Radius radius; - final HonorModel? honorModel; - const UserHeaderBottom(this.userInfo, this.honorModel, this.radius, - {super.key}); + const UserHeaderBottom(this.userInfo, this.radius, {super.key}); ///底部状态栏 _getBottomItem(String? title, var value, onPressed) { @@ -360,12 +362,37 @@ class UserHeaderBottom extends StatelessWidget { height: 40.0, alignment: Alignment.center, color: GSYColors.subLightTextColor), - _getBottomItem(GSYLocalizations.i18n(context)!.user_tab_honor, - honorModel?.beStaredCount, () { - if (honorModel?.honorList != null) { - NavigatorUtils.goHonorListPage(context, honorModel?.honorList); - } - }), + Consumer( + builder: (BuildContext context, WidgetRef ref, Widget? child) { + var data = ref.watch( + OnlyShareInstanceWidget.of(context)!); + return _getBottomItem( + GSYLocalizations.i18n(context)!.user_tab_honor, + switch (data) { + AsyncData(:final value) => + value?.beStaredCount.toString() ?? "---", + AsyncError() => "----", + _ => "---", + }, + () { + var list = data.when( + data: (result) { + return result?.honorList; + }, + error: (_, __) => null, + loading: () => null); + if (list != null && list.isNotEmpty) { + NavigatorUtils.goHonorListPage(context, list); + } + }, + ); + }) + // _getBottomItem(GSYLocalizations.i18n(context)!.user_tab_honor, + // honorModel?.beStaredCount, () { + // if (honorModel?.honorList != null) { + // NavigatorUtils.goHonorListPage(context, honorModel?.honorList); + // } + // }), ], ), ), diff --git a/lib/widget/only_share_widget.dart b/lib/widget/only_share_widget.dart new file mode 100644 index 00000000..a19576ba --- /dev/null +++ b/lib/widget/only_share_widget.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +///往下共享环境配置 +class OnlyShareInstanceWidget extends StatelessWidget { + const OnlyShareInstanceWidget({super.key, this.value, this.child}); + + @override + Widget build(BuildContext context) { + return _OnlyShareInstanceModel(value: value, child: child!); + } + + static V? of(BuildContext context) { + final _OnlyShareInstanceModel? inheritedConfig = + context.dependOnInheritedWidgetOfExactType<_OnlyShareInstanceModel>(); + return inheritedConfig?.value; + } + + final T? value; + + final Widget? child; +} + +class _OnlyShareInstanceModel extends InheritedWidget { + const _OnlyShareInstanceModel({required this.value, required super.child}); + + final T? value; + + ///不需要刷新数据,直接返回false + @override + bool updateShouldNotify(_OnlyShareInstanceModel oldWidget) => false; +} \ No newline at end of file